==============
UbuntuでIPoE
==============
* :作成日: 2018-12-01
* :更新日: 2019-07-27
はじめに
========
`IIJmioひかり `_ とIIJmio ひかり電話と `IIJmioひかり IPoEオプション `_ を利用しているのですが、Ubuntu 18.04.1 LTSでIPoEを使うようにしたメモです。
構成図
======
ネットワーク配線図は以下の通りです。
.. blockdiag::
blockdiag {
orientation = portrait;
home-gw -- beagle, primergy;
beagle, primergy -- hub;
hub -- wifi-router;
wifi-router -- thinkpad, android, ipad [style = dashed, label = "wifi"];
}
ホームゲートウェイは `RT-500KI `_ です。
WiFiルータは `AtermWG1800HP2 `_ ですがWANポートが1つしかないため、primergyとbeagleの2台をつなぐためにハブを挟んでいます。
ハブはI-O DATAの `ETG-ESH5 `_ です。
WiFiルータはブリッジモードを使用しています。
論理ネットワーク図は以下の通りです。
.. nwdiag::
nwdiag {
inet [shape = cloud];
inet -- home-gw;
network dmz {
address = "192.168.1.x/24"
home-gw [address = "ipv6:prefix:xxxx, 192.168.1.1"];
beagle [address = "ipv6:prefix:zzzz, vip:192.168.1.2, 192.168.1.3"];
primergy [address = "ipv6:prefix:yyyy, 192.168.1.4"];
}
network internal {
address = "192.168.2.x/24";
beagle [address = "vip:192.168.2.1, 192.168.2.2"];
primergy [address = "192.168.2.3"];
thinkpad;
android;
ipad;
}
}
ホームゲートウェイの設定
========================
* DHCPサーバの無効化
- [詳細設定]/[DHCPv4サーバ設定]で[DHCPv4サーバ機能]の[使用する]チェックボックスをオフ
* LAN側の静的ルーティング
- [詳細設定]/[LAN側静的ルーティング設定]で以下のように設定します。
.. list-table::
:stub-columns: 1
* - 宛先IPアドレス/マスク長
- 192.168.2.0/24
* - ゲートウェイ
- 192.168.1.2
サーバのネットワーク設定
========================
beagleの :code:`/etc/netplan/01-netcfg.yaml` は以下の通りです。
.. code:: text
network:
version: 2
renderer: networkd
ethernets:
enp3s0:
dhcp4: no
addresses: [192.168.1.3/24]
gateway4: 192.168.1.1
nameservers:
addresses: [192.168.1.1]
dhcp6: no
enp4s0:
dhcp4: no
addresses: [192.168.2.2/24]
primergyの :code:`/etc/netplan/01-netcfg.yaml` は以下の通りです。
.. code:: text
network:
version: 2
renderer: networkd
ethernets:
enp0s25:
dhcp4: no
addresses: [192.168.1.4/24]
gateway4: 192.168.1.1
nameservers:
addresses: [192.168.1.1]
dhcp6: no
enp2s0:
dhcp4: no
addresses: [192.168.2.3/24]
dhcp6: no
:code:`sudo netplan apply` コマンドで反映しました。
IPv4フォワーディングの有効化
=============================
IPv4のルータとして機能させるため、以下のコマンドを実行してIPv4フォワーディングを有効化します。
.. code:: console
sudo sysctl net.ipv4.ip_forward=1
OS再起動時にもこの設定がされるように :code:`/etc/sysctl.d/99-sysctl.conf` 内の以下の行をアンコメントします。
.. code:: text
# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
IPoEの設定
==========
上記のように配線した状態で :code:`ip a` でIPアドレスを確認するとIPv6のグローバルアドレスがついていました。
:code:`ip -6 tunnel add` コマンドでmodeにipip6(IPv4 over IPv6トンネル)を指定することでトンネルを作成します。以下のようなシェルスクリプト :code:`/usr/local/sbin/ipoe.sh` を作成しました。
IPv6グローバルIPアドレスが付与されるまでの待つコマンドを改良しました。またデフォルトルートの切り替えをip route deleteしてaddしてたのをchangeを使うように改善しました(2019年7月27追記)。
.. code:: sh
#!/bin/sh -x
set -eu
#. /etc/default/ipoe
case "$1" in
start)
while ! /sbin/ip -br a s dev ${WAN_INTERFACE} mngtmpaddr | /bin/grep -q UP; do sleep 1; done
local_addr=$(/sbin/ip -br a s dev ${WAN_INTERFACE} mngtmpaddr | /usr/bin/awk '{ sub("/.*", "", $3); print $3 }')
/sbin/ip -6 tunnel add "${TUNNEL_NAME}" mode ipip6 remote "${GATEWAY_ADDR}" local "${local_addr}" dev "${WAN_INTERFACE}"
/sbin/ip link set "${TUNNEL_NAME}" up
/sbin/ip route change default dev "${TUNNEL_NAME}"
;;
stop)
/sbin/ip route change default dev "${WAN_INTERFACE}"
/sbin/ip link set "${TUNNEL_NAME}" down
/sbin/ip -6 tunnel del "${TUNNEL_NAME}"
;;
*)
echo "Usage: ipoe.sh (start|stop)"
exit 1
;;
esac
:code:`local_addr` を設定している箇所は以下のような行からIPv6アドレスを取り出しています。もしmngtmpaddrを含む行が複数ある場合は最初の行を採用します。
.. code:: text
inet6 xxxx:xxx:xxx:xxxx:xxxx:xxx:xxxx:xxxx/64 scope global dynamic mngtmpaddr noprefixroute
サービス定義ファイル :code:`/etc/systemd/system/ipoe.service` は以下のようにしました。
`IPv6 トンネルブローカー設定 - ArchWiki `_ でsystemd-networkdを使ったトンネルの設定方法も見つけたのですが、こちらは試していません。
.. code:: text
[Unit]
Description=IPoE tunnel
After=network.target
[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/etc/default/ipoe
ExecStart=/usr/local/sbin/ipoe.sh start
ExecStop=/usr/local/sbin/ipoe.sh stop
[Install]
WantedBy=multi-user.target
設定ファイル :code:`/etc/default/ipoe` は以下の通りです。
.. code:: text
# tunnel device name
TUNNEL_NAME=ip6tnl1
# WAN network interface
WAN_INTERFACE=enp0s25
# Gateway address
# You can get this address by running the following command.
# dig -t aaaa gw.transix.jp
GATEWAY_ADDR=2404:8e01::feed:100
:code:`WAN_INTERFACE` は実際の環境に応じて変更してください。
:code:`GATEWAY_ADDR` は :code:`dig -t aaaa gw.transix.jp` で調べられます。
NTT西日本エリアだと :code:`2404:8e01::feed:100` と :code:`2404:8e01::feed:101` のラウンドロビンになっていました。
`YAMAHA RTX1200の設定マニュアル `_ によるとNTT東日本エリアでは :code:`2404:8e00::feed:100` と :code:`2404:8e00::feed:101` で、エリアは `NTT東日本、NTT西日本のサービス提供地域について `_ で確認できます。
以下のコマンドで反映しました。
.. code:: console
sudo systemctl daemon-reload
sudo systemctl start ipoe
sudo systemctl enable ipoe
iptablesの設定
==============
ファイアウォールは `UFW `_ は使わず、iptablesとiptables-persistentを使っています。
.. code:: console
sudo apt install iptables-persistent
設定は以下の通りです。LXDとdockerを使っているのでそれらの設定も含まれています。
:code:`/etc/iptables/rules.v4`
.. code:: text
# Generated by iptables-save v1.6.1 on Sat Dec 1 14:44:22 2018
*filter
:INPUT ACCEPT [238:15436]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [114:36056]
:DOCKER - [0:0]
:DOCKER-ISOLATION-STAGE-1 - [0:0]
:DOCKER-ISOLATION-STAGE-2 - [0:0]
:DOCKER-USER - [0:0]
:WAN_IN - [0:0]
:WAN_LOCAL - [0:0]
-A INPUT -i lxdbr0 -p tcp -m tcp --dport 53 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A INPUT -i lxdbr0 -p udp -m udp --dport 53 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A INPUT -i lxdbr0 -p udp -m udp --dport 67 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A INPUT -i enp0s25 -j WAN_LOCAL
-A FORWARD -o lxdbr0 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A FORWARD -i lxdbr0 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A FORWARD -i enp0s25 -j WAN_IN
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A OUTPUT -o lxdbr0 -p tcp -m tcp --sport 53 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A OUTPUT -o lxdbr0 -p udp -m udp --sport 53 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A OUTPUT -o lxdbr0 -p udp -m udp --sport 67 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -j RETURN
-A WAN_IN -m comment --comment WAN_IN-10 -m state --state RELATED,ESTABLISHED -j RETURN
-A WAN_IN -m comment --comment WAN_IN-20 -m state --state INVALID -j DROP
-A WAN_IN -s 192.168.1.0/24 -p icmp -m comment --comment WAN_IN-30 -j ACCEPT
-A WAN_IN -m comment --comment "WAN_IN-10000 default-action drop" -j LOG --log-prefix "[WAN_IN-default-D]"
-A WAN_IN -m comment --comment "WAN_IN-10000 default-action drop" -j DROP
-A WAN_LOCAL -m comment --comment WAN_LOCAL-10 -m state --state RELATED,ESTABLISHED -j RETURN
-A WAN_LOCAL -m comment --comment WAN_LOCAL-20 -m state --state INVALID -j DROP
-A WAN_LOCAL -s 192.168.1.0/24 -p icmp -m comment --comment WAN_LOCAL-30 -j ACCEPT
-A WAN_LOCAL -s 192.168.1.0/24 -p vrrp -m comment --comment WAN_LOCAL-40 -j ACCEPT
-A WAN_LOCAL -m comment --comment "WAN_LOCAL-10000 default-action drop" -j LOG --log-prefix "[WAN_LOCAL-default-D]"
-A WAN_LOCAL -m comment --comment "WAN_LOCAL-10000 default-action drop" -j DROP
COMMIT
# Completed on Sat Dec 1 14:44:22 2018
# Generated by iptables-save v1.6.1 on Sat Dec 1 14:44:22 2018
*mangle
:PREROUTING ACCEPT [2054464:7594383842]
:INPUT ACCEPT [1989651:7566369331]
:FORWARD ACCEPT [64047:27954808]
:OUTPUT ACCEPT [937916:146880228]
:POSTROUTING ACCEPT [1005398:175609326]
-A POSTROUTING -o lxdbr0 -p udp -m udp --dport 68 -m comment --comment "generated for LXD network lxdbr0" -j CHECKSUM --checksum-fill
COMMIT
# Completed on Sat Dec 1 14:44:22 2018
# Generated by iptables-save v1.6.1 on Sat Dec 1 14:44:22 2018
*nat
:PREROUTING ACCEPT [9291:2179690]
:INPUT ACCEPT [3252:483996]
:OUTPUT ACCEPT [3623:517216]
:POSTROUTING ACCEPT [3545:511992]
-A POSTROUTING -s 10.70.121.0/24 ! -d 10.70.121.0/24 -m comment --comment "generated for LXD network lxdbr0" -j MASQUERADE
COMMIT
# Completed on Sat Dec 1 14:44:22 2018
:code:`/etc/iptables/rules.v6`
.. code:: text
# Generated by ip6tables-save v1.6.1 on Mon Nov 12 18:31:46 2018
*nat
:PREROUTING ACCEPT [5513:616145]
:INPUT ACCEPT [5243:585056]
:OUTPUT ACCEPT [2714:318879]
:POSTROUTING ACCEPT [2645:312423]
-A POSTROUTING -s fd42:f7bd:987f:2f80::/64 ! -d fd42:f7bd:987f:2f80::/64 -m comment --comment "generated for LXD network lxdbr0" -j MASQUERADE
COMMIT
# Completed on Mon Nov 12 18:31:46 2018
# Generated by ip6tables-save v1.6.1 on Mon Nov 12 18:31:46 2018
*filter
:INPUT ACCEPT [251:73519]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [226:60652]
:WANv6_IN - [0:0]
:WANv6_LOCAL - [0:0]
-A INPUT -i lxdbr0 -p tcp -m tcp --dport 53 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A INPUT -i lxdbr0 -p udp -m udp --dport 53 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A INPUT -i lxdbr0 -p udp -m udp --dport 547 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A INPUT -i enp0s25 -j WANv6_LOCAL
-A FORWARD -o lxdbr0 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A FORWARD -i lxdbr0 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A FORWARD -i enp0s25 -j WANv6_IN
-A OUTPUT -o lxdbr0 -p tcp -m tcp --sport 53 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A OUTPUT -o lxdbr0 -p udp -m udp --sport 53 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A OUTPUT -o lxdbr0 -p udp -m udp --sport 547 -m comment --comment "generated for LXD network lxdbr0" -j ACCEPT
-A WANv6_IN -m comment --comment WANv6_IN-10 -m state --state RELATED,ESTABLISHED -j RETURN
-A WANv6_IN -m comment --comment WANv6_IN-20 -m state --state INVALID -j DROP
-A WANv6_IN -p ipv6-icmp -m comment --comment WANv6_IN-30 -j RETURN
-A WANv6_IN -m comment --comment "WANv6_IN-10000 default-action drop" -j LOG --log-prefix "[WANv6_IN-default-D]"
-A WANv6_IN -m comment --comment "WANv6_IN-10000 default-action drop" -j DROP
-A WANv6_LOCAL -m comment --comment WANv6_LOCAL-10 -m state --state RELATED,ESTABLISHED -j RETURN
-A WANv6_LOCAL -m comment --comment WANv6_LOCAL-20 -m state --state INVALID -j DROP
-A WANv6_LOCAL -p ipv6-icmp -m comment --comment WANv6_LOCAL-30 -j RETURN
-A WANv6_LOCAL -p udp -m comment --comment WANv6_LOCAL-40 -m udp --sport 547 --dport 546 -j RETURN
-A WANv6_LOCAL -p ipip -m comment --comment WANv6_LOCAL-50 -j RETURN
-A WANv6_LOCAL -p tcp -m comment --comment WANv6_LOCAL-60 -m tcp --dport 22 -j RETURN
-A WANv6_LOCAL -m comment --comment "WANv6_LOCAL-10000 default-action drop" -j LOG --log-prefix "[WANv6_LOCAL-default-D]"
-A WANv6_LOCAL -m comment --comment "WANv6_LOCAL-10000 default-action drop" -j DROP
COMMIT
# Completed on Mon Nov 12 18:31:46 2018
ファイルの内容を変更したら以下のコマンドを実行して反映します。
.. code:: console
sudo iptables-restore < /etc/iptables/rules.v4
sudo ip6tables-restore < /etc/iptables/rules.v6
逆に設定をファイルに保存するには以下のコマンドを実行します。
.. code:: console
sudo iptables-save | sudo tee /etc/iptables/rules.v4
sudo ip6tables-save | sudo tee /etc/iptables/rules.v6
:code:`/etc/iptables/rules.v{4,6}` の内容はbitbucket.orgのプライベートレポジトリで管理しています。
keepalivedの設定
================
keepalivedを使ってVIP(仮想IPアドレス)を設定しています。
keepalivedは標準パッケージをインストールしました。
.. code:: console
sudo apt install keepalived
:code:`/etc/keepalived/keepalived.conf` は以下の通りです。送信元のメールアドレスは途中を大文字にしてどこから送られたかを判別できるようにしています。
.. code:: text
global_defs {
notification_email {
john.doe+home@example.com
}
notification_email_from jOhn.doe@example.com
smtp_server localhost
smtp_connect_timeout 30
router_id 1
}
include vrrp.conf
beagleの :code:`/etc/keepalived/vrrp.conf` は以下の通りです。
.. code:: text
vrrp_instance VRRP1 {
state MASTER
interface enp3s0
virtual_router_id 1
priority 200
advert_int 1
smtp_alert
virtual_ipaddress {
192.168.1.2/24
}
}
vrrp_instance VRRP2 {
state MASTER
interface enp4s0
virtual_router_id 2
priority 200
advert_int 1
smtp_alert
virtual_ipaddress {
192.168.2.1/24
}
}
primergyの :code:`/etc/keepalived/vrrp.conf` は以下の通りです。
.. code:: text
vrrp_instance VRRP1 {
state BACKUP
interface enp0s25
virtual_router_id 1
priority 100
advert_int 1
smtp_alert
virtual_ipaddress {
192.168.1.2/24
}
}
vrrp_instance VRRP2 {
state BACKUP
interface enp2s0
virtual_router_id 2
priority 100
advert_int 1
smtp_alert
virtual_ipaddress {
192.168.2.1/24
}
}
stateとpriorityをbeagleとprimergyで上記のように設定することでbeagleのほうを優先するようにしています。
DHCPサーバの設定
================
DHCPサーバはisc-dhcp-serverパッケージを使っています。
.. code:: console
sudo apt install isc-dhcp-server
beagleの :code:`/etc/dhcp/dhcpd.conf` は以下の通りです。
.. code:: text
option domain-name-servers 192.168.1.1;
default-lease-time 600;
max-lease-time 7200;
ddns-update-style none;
subnet 192.168.2.0 netmask 255.255.255.0 {
range 192.168.2.20 192.168.2.99;
option routers 192.168.2.1;
}
primergyの :code:`/etc/dhcp/dhcpd.conf` は以下の通りです。
.. code:: text
option domain-name-servers 192.168.1.1;
default-lease-time 600;
max-lease-time 7200;
ddns-update-style none;
subnet 192.168.2.0 netmask 255.255.255.0 {
range 192.168.2.100 192.168.2.189;
option routers 192.168.2.1;
}
beagleとprimergyでDHCPのrangeを重ならないように設定し、ゲートウェイにはVIPを指定しています。こうすることで片方のサーバが停止してもThinkPadなどDHCPクライアントのマシンはそのまま通信できると同僚に教わりました。ありがとうございます!