OpenBSDでIPv6 PPPoEを設定したときのメモ
コンテンツ
ホームルータとして利用している OpenBSD を使い,固定回線(フレッツ)をIPv6で接続した話.IPv6で接続する方法は複数存在しており,実際にどの方法を使えば良いかなどの情報が少なく,色々と苦労したというメモ.
ISP は OCN を利用しており,OCNは IPv6接続を PPPoE 形式で提供している(ちなみに追加料金は不要).
別途,機器が必要なようにも読めるがなくても大丈夫である.
今回はIPv6 PPPoE 接続の話題である.別方式としてフレッツ網内で PPPoE をカプセル化しない,IPv6 IPoE (IP over Ethernet) 方式が存在する.素人考え的には PPPoE のカプセンリングなんて面倒なことはせずに NTT東西が ISPサービスも提供すれば,シンプルになるとは思うのだが.
IPv6 PPPoE 接続の流れ
次のような流れで IPv6 接続ができることが分かった.
- IPv6 用の PPPoE セッションを確立する(IPv4とは別セッション).
- DHCPv6 クライアントを使用して IPv6 のプレフィックスを取得する.
- DHCPv6 クライアントを使用して LAN インターフェイスに IPv6 アドレスを割り当てる.
- Router Advertisement (RA) と DHCPv6 サーバ を使用して LAN 内の端末に IPv6 アドレス割り当て,同時にデフォルトルート,DNSサーバの情報を渡す.
IPv4接続の場合は step 1 で接続完了なのだが,IPv6の場合は step 4 まで(厳密には 3 まで)必要である.ここを理解していなかったので,アレIPv6アドレスふってこない,などと勘違いしていた.
IPv6の場合は追加で DHCPv6 の prefix delegation が必要になる.これはIPアドレスではなくIPv6のサブネットを取得する.IPv4 で例えると 192.0.2.1
ではなく 192.0.2.0/24
を取得するイメージ.このサブネットからルータのLAN側インターフェイスにIPv6を割り当て,LAN内の端末にIPv6を払い出す.ここで DHCPv6 と RA を利用する.
IPv6用PPPoEセッションの確立
IPv4用の PPPoE セッションが pppoe0
で確立されているので,別の PPPoE用のインターフェイス pppoe1
でセッションを開始する.
IPv6用の PPPoE セッションを開始するには次のようなコマンドを実行する.
|
|
オプションの inet6
の後の <link-local-address> prefixlen 64
は eui64
でも可だが,後でIPv6のデフォルトゲートウェイを pppoe1
の IPv6 リンクローカルアドレスに設定するので, ifconfig pppoe1
で確認しておく.また, eui64
を使用した場合,物理インターフェイスのマックアドレス,今回は em0
, を元にリンクローカルアドレスが生成される.
ifconfig pppoe1
で次のような表示が含まれていればセッションが確立されている.
|
|
IPv4の場合と違い,この段階ではグローバルな IPv6 アドレスが割り当てられていないので,インターネットには接続できない.グローバルアドレスは次の DHCPv6-PD で取得する.
DHCPv6によるIPv6のプレフィックスの取得
Prefix Delegation (PD) によりグローバルな IPv6 サブネットを取得する.IPv4の場合は単一のアドレスが割り当てられるため NAT が必要だが, IPv6 の場合はサブネットが割り当てられるので NAT が不要となる.
IPv6では128ビットのうち前半64ビットでサブネット,後半64ビットでホストを表す.一般に DHCPv6-PD では64ビット未満のプレフィックスが割り当てられる.例えば私の環境(OCN)では56ビットのプレフィックスが割り当てられている.残り 8 ビットはどうするのかというと,DHCPv6-PD でプレフィックスを受け取った側で自由に設定できる.後半64ビットはIPアドレスを設定するインターフェイスのMACアドレスから生成する.
(追記)
以下ではDHPCv6-PDクライアントとして wide-dhcpv6
を利用してるが,現在は dhcpcd
を利用している.理由は次.
- IPv6アドレスがeui64に固定される.
2001:0DB8::1
等の設定できずMACアドレスが埋め込まれたIPアドレスで通信することになる. - 移譲されたプレフィックスの経路を reject していないためパケットループが発生する可能性がある(実際は問題にならないが…).
- 下記でも
dhcpcd
が良いのではと指摘されている.
インストールは pkg_add dhcpcd
でできる.設定方法は /usr/local/share/doc/pkg-readmes/
にインストールされるドキュメントに記載してある.例えばWAN側PPPoEインターフェイス pppoe1
でDHCPv6-PDのリクエストを送信して,取得したプレフィックスをLAN側 vether0
に割り当てるには次のような設定ファイル /etc/dhcpcd.conf
を利用する.
|
|
(追記終り)
DHCPv6は標準ではインストールされておらず,バイナリパッケージを pkg_add
でインストールする必要がある.いくつか DHCPv6 の機能を提供するパッケージが複数存在する.DHCPv6 のサーバ機能も必要になる(後述)こと,必要なのは IPv6 の DHCP だけなので wide-dhcpv6
を選択した.インストールするには pkg_add wide-dhcpv6
を実行する.
設定は /etc/dhcp6c.conf
に記述する.次の設定はWAN側PPPoEインターフェイス pppoe1
で DHCPv6-PD のリクエストを送信し,/56のIPv6プレフィックスを取得する.そのプレフィックスに最下位のみ 1
となっている 8 ビットを追加して /64 のサブネットを作成し,LAN側インターフェイス vether0
にIPv6アドレスを割り当てる.
|
|
DHCPv6のクライアントを許可するように /etc/pf.conf
を編集する.DHCPv6は宛先IPv6が特殊なパケットを送信するためステートフルファイアウォールが効かない.
|
|
IPv4の場合と違い PPPoE のインターフェイスにはグローバルアドレスは割り当てない.しかし,デフォルトゲートウェイは PPPoE インターフェイスなので次のように設定する.
|
|
この時点で OpenBSD ルータは IPv6 でインターネットに接続できる. AAAAで名前解決ができる場合は次のコマンド
|
|
名前解決ができない場合は Google の public DNS に ping を打つことで疎通を確認できる.
|
|
次はLAN内の端末がインターネットに IPv6 で接続できるように RA と DHCPv6 サーバを設定する.
LAN内の端末にIPv6, デフォルトルート,DNS情報を配布する.
Router Advertisement (RA) と DHCPv6 サーバにより実現する.技術的には RA だけで実現できるが Windows は RA による DNS サーバの配布(RFC 6106)に対応していないので,そのため DHCPv6のサーバ機能を利用する.
(上のリンクにはWindowsでRAでのDNSをサポートしないのはレイヤ違反だから,RAはネットワークレイヤでDNSはアプリケーションレイヤ,というコメントがありましたが,個人的には細けえこたあいいんだよという気がします)
RA, DHCPv6 どちらも機能的にはLAN内の端末にIPアドレスとDNS情報を配布することができる.クライアントにどちらから情報を取得するかを伝えるためには RA の Managed address configuration flag (Mフラグ) と Other configuration flag (Oフラグ)を使用する.MフラグがオンのときはIPアドレスとDNSの両方をDHCPv6から取得することを伝える.OフラグがオンがDNSなどのみDHCPv6を利用することを伝える.
Windows がRAによるDNSサーバの配布に対応していないのでOフラグをONにして,IPアドレスはRA,DNSサーバはDHCPv6を利用する.
RAの設定は /etc/rtadvd.conf
に記述する.次は vether0
でMフラグをオンにしてRAを有効にする.
|
|
(念の為,DHCPv6に対応していない機器も考慮してDNS情報を設定している)
DHCPv6サーバの設定は /etc/dhcp6s.conf
に記述する.
|
|
LAN内のDNSリゾルバのグローバルIPv6アドレスは変化する可能性があるので,現在はユニークローカルIPv6ユニキャストアドレス(IPv4でいうところのプライベートアドレス)を割り当て,そちらをDNSサーバの情報として配布している.ULAでリッスンしておけばファイアウォールに不備があってもオープンリゾルバにはらないので.
pf の設定
IPv6用に pf
を設定する必要がある.現在は次のように設定している(該当部分のみ抜粋).
|
|
1行目の pass out quick inet6 modulate state
は外向きの IPv6 トラフィックを許可している.
2行目の pass in quick on $int_if inet6
は LAN内の端末からの IPv6 トラフィックを許可している.
3行目の pass in on egress inet6 proto ipv6-icmp ...
で ICMPv6 を許可している.IPv6 ではフラグメントできないので Path MTU の発見が失敗すると最悪の場合,通信ができなくなる.その他に関しては RFC 4890 の Section 4.3 を参考にした.
4行目の pass in inet6 proto udp to (self) port dhcpv6-client
は DHCPv6 のクライアントパケットの戻りを許可するため.
起動時設定
あとは起動時に自動でIPv6のPPPoEセッションが確立して,DHCPv6-PDでプレフィックスを取得するように /etc/hostname.pppoe1
に設定すれば良いのだが,ここがうまくいかなかった.
次のような設定を記述したが, PPPoEセッションがいつまでたっても確立されなかった.
|
|
なぜかIPv4のPPPoEセッションも確立しないときもあった.どうやら,同時に2つのPPPoEセッションを確立しようとすると失敗することがあるようだったので,IPv4のPPPoEセッションが確立してからIPv6のPPPoEセッションを開始するようなスクリプトを用意して,起動時に実行するようにしている.
ひとまず,現在は次のようなシェルスクリプトでその場しのぎをしている( tcpdump
とかでパケットキャプチャしてデバッグするほどの気力と知識がなかたっので,その場しのぎ).
|
|
参考
作成者 Toru Mano
最終更新時刻 2023-01-01 (c70d5a1)