ひかり電話のホームゲートウェイにFreeBSDなルーターを接続する

やること

ひかり電話のホームゲートウェイFreeBSDルーターを接続して、

  1. DHCPv6で/60のIPv6のprefixをHGWからもらう
  2. RAで/64のprefixを配布する

構成

+--------+        +---------+       +---------+
|   HGW  |        | FreeBSD |       | Xubuntu |
|        +--------+         +-------+         |
+--------+        +---------+       +---------+
  • HGWはDHCPv6 PDで/56をもらう。
  • FreeBSDのHGW側のインターフェースは、HGWからのRAを元にアドレスを設定する。(FreeBSDはRAを受信する)
  • FreeBSDXubuntu側のインターフェースは、HGWからのDHCPv6 PDでもらった/60を元にアドレスを設定する。(FreeBSDはDHCPv6のIA_PDの要求を送る)
  • XubuntuFreeBSD側のインターフェースは、FreeBSDからのRAを元にアドレスを設定する。(FreeBSDはRAを送信する)

FreeBSDのインターフェースは、

  • HGW側が、vtnet0
  • Xubuntu側が、vtnet1

とりあえずルーター用の設定

echo 'ipv6_activate_all_interfaces="YES"' >> /etc/rc.conf
echo 'ifconfig_vtnet0_ipv6="inet6 accept_rtadv" >> /etc/rc.conf
echo 'ifconfig_vtnet1_ipv6="inet6 -accept_rtadv" >> /etc/rc.conf
echo 'ipv6_cpe_wanif="vtnet0" >> /etc/rc.conf
echo 'ipv6_gateway_enable="YES" >> /etc/rc.conf

以下の設定をしておかないと、チェックサムが正しく計算されなくてうまく動かなかった。これに気がつくのに時間がかかった。 ハードウェアによるチェックサムの計算等はやらないようにしておく。

echo hw.vtnet.csum_disable=1 >> /boot/loader.conf
echo hw.vtnet.tso_disable=1 >> /boot/loader.conf
echo hw.vtnet.lro_disable=1 >> /boot/loader.conf

vtnetではない場合は、ifconfigでも設定可能。rc.confに書いておくと起動時に設定される。

ifconfig vtnet0 -rxcsum -txcsum -rxcsum6 -txcsum6 -tso -lro
ifconfig vtnet1 -rxcsum -txcsum -rxcsum6 -txcsum6 -tso -lro

設定しておかないと、tcpdumpでchecksumがincorrectになる。

01:05:47.438901 IP6 (flowlabel 0xca7c6, hlim 64, next-header TCP (6) payload length: 40) 2001:0db8:1234:5678:1234:5678:0000:001.34824 > 2001:0db8:1234:5678:1234:5678:0000:0002.3000: Flags [S], cksum 0x29e4 (incorrect -> 0xb731), seq 4096995977, win 64800, options [mss 1440,sackOK,TS val 1028813372 ecr 0,nop,wscale 7], length 0

DHCPv6で/60のIPv6のprefixをHGWからもらう

FreeBSDには標準でIPv6対応のDHCPクライアントが入っていないため、インストールする。

pkg install dhcp6

設定ファイルを作る。

# vtnet0に要求を出して、戻ってきたらvtnet1に設定する。/60をもらえるので、4ビット分IDをつけて、/64を配下に割り当てる。
cat <<EOF > /usr/local/etc/dhcp6c.conf
interface vtnet0 {
  send ia-pd 0;
  send rapid-commit;
};

id-assoc pd 0 {
  prefix-interface vtnet1 {
    sla-id 0;
    sla-len 4;
  };
};
EOF

起動時に動くようにする。&起動

echo 'dhcp6c_enable="YES"' >> /etc/rc.conf

# vtnet0はHGWに接続しているインターフェース
echo 'dhcp6c_interfaces="vtnet0"' >> /etc/rc.conf

service dhcp6c start

RAで/64のprefixを配布する

RAのデーモンを起動する。

echo 'rtadvd_enable="YES"' >> /etc/rc.conf

# vtnet1はRAする側のインターフェース
echo 'rtadvd_interfaces="vtnet1"' >> /etc/rc.conf

# raflagsはDNSサーバーのアドレスをDHCPで配布する用。
cat << EOF > /etc/rtadvd.conf 
vtnet1:\
       :raflags="o":\
       :prefixlen#64:
EOF
service rtadvd start

DHCPDNSサーバーのアドレスを配布する

echo 'option domain-name-servers 2606:4700:4700::1111;' > /usr/local/etc/dhcp6s.conf
echo 'dhcp6s_enable="YES"' >> /etc/rc.conf
echo 'dhcp6s_interface="vtnet1"' >> /etc/rc.conf
service dhcp6s start

もし、最後の起動のところで、

failed to open /usr/local/etc/dhcp6sctlkey: No such file or directory

になった場合は、このファイルを作成する。

openssl rand -base64 -out /usr/local/etc/dhcp6sctlkey 16