以前の記事で、ラズパイの wlan0 と eth0 を 併用し、IPv4/IPv6 両方からアクセスできるラズパイサーバーを作りました。
今回は、「eth0 にも IPv6 グローバルアドレスが割り当てられているのだから、それを使って外からアクセスすれば良いのでは?」との友人のコメントをきっかけに、別のアプローチで同じことをやったので報告します。
目次
実現できたこと
IPv4 | IPv6 | |
ラズパイ → インターネット方向の外向きアクセス | eth0 上に構築した IPv4 over IPv6 (DS-Lite) トンネルを使って混雑しにくい IPv6 IPoE 網経由でアクセス | eth0 を使ってネイティブな IPv6 IPoE 経由でアクセス |
インターネット → ラズパイ方向の内向きアクセス | eth0 上に構築した IPv4 PPPoE 接続を使って待ち受ける | eth0 を使ってネイティブな IPv6 IPoE 経由で待ち受ける |
以前の構成と比べた時のメリット
V4, V6 双方を有線LANポート1つでさばけるので、以下のメリットがあります。
- ラズパイの無線機能をOFFして多少節電できる。また、自宅を長期間空けるときなどに、無線LANルーターの電源を落としても支障がない
- ラズパイサーバーが自力でWANに繋がるので、無線LANルーターの外側にラズパイを置くことができる。これによりラズパイサーバと自宅LANを分離できるので、インバウンドIPv6パケットを自宅LAN内部へ通す必要がなくなり、セキュリティ的に好ましい
配線
配線自体は以前の記事と変わらず、下図のように接続する。ただし、wlan0 はあくまでもローカルから SSH 接続で設定を行うために繋いでおり、外部との通信には使わない。
配線が完了し eth0 がリンクした時点で、eth0 には「リンクローカル IPv6 アドレス」「グローバルIPv6アドレス(これを使ってインターネットと接続できる)」「自己構成 IPv4 アドレス」が割り当てられる。
PPPoE の設定
以前の記事と同一だが、メモしておく。こちらのサイトの受け売りなので私が書く必要はほぼない……。
pppoeパッケージのインストールと設定
pppoe, pppoeconf をインストール。
sudo apt install pppoe pppoeconf -y
pppoeconf を実行。
sudo pppoeconf
PPPoEセッションを利用可能なネットワークインターフェイスを自動で見つけて設定が進む。全部YesかOKで答えれば問題ない。途中、ISPから受け取ったPPPoE接続用のユーザー名とパスワードを聞かれる。
ウィザードが終了したら、
ip addr show ppp0
で正しく接続できたか調べる。下のように、ppp0 インターフェイスにIPv4アドレスが付与されたら成功。
5: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1454 qdisc pfifo_fast state UNKNOWN group default qlen 3 link/ppp inet xxx.xxx.xxx.xxx peer yyy.yyy.yyy.yyy/32 scope global ppp0 valid_lft forever preferred_lft forever
手動接続・切断
pon dsl-provider # 接続 poff # 切断
PPPoE接続時にルーティングテーブルを編集
このままの状態だと、ppp0に到着したパケットに対する返答が、ppp0ではなくデフォルトのwlan0から出ていってしまう。すると、IPv4経由で本ブログにアクセスしてきた人が返答を認識できず、ブログを表示できない。そこで、ppp0経由で到着したパケットに対する返答をppp0経由でインターネットに返すよう、ルーティングテーブルを編集する。PPPoE接続の開始時に自動実行してくれるシェルスクリプトが用意されているので、そこに書き加えていく。
sudo nano /etc/ppp/ip-up.d/10dsl-provider
以下を追記。解説すると、
- 「200番」というIDのルーティングテーブルを新規作成する。このテーブルではすべてのパケットについてデフォルトで「dev ppp0」経由にする。ネクストホップに「
$PPP_REMOTE
」を指定する。 - 「
$PPP_LOCAL
」からマシンに入ってきたパケットについては、ルーティングテーブル200番に従って処理するよう設定する。ルールの優先度を200(通常より優先度が高い)とすることで、$PPP_LOCAL
宛のパケットだけ200番に沿ってルーティングさせる
#!/bin/sh ip route add default via "$PPP_REMOTE" dev ppp0 table 200 ip rule add from "$PPP_LOCAL" table 200 prio 200
実行権限を与えて完了。
sudo chmod 755 /etc/ppp/ip-up.d/10dsl-provider
DS-Lite による IPv4 over IPv6 の設定
我が家が契約している「楽天ひかり」は、DS-Lite 技術を用いた IPv4 over IPv6 に対応している。これにより、PPPoE が混雑する時間帯でも、IPv4 サイトを快適に見ることができる。この恩恵に預かりたい人は、ふつう楽天ひかり対応の無線LANルーターを買ってきてそこにラズパイを繋ぐわけだが、今回はルーターの代わりにラズパイ自身が DS-Lite による IPv4 over IPv6 トンネルを構築し、ルーターなしで IPv4 over IPv6 ができるようにする。
事前の確認
DS-Lite における AFTR の IPv6 アドレスを調べておく。楽天ひかりが対応するクロスパスの場合は、dgw.xpass.jp
の IPv6 アドレスが分かればよい。我が家では 2001:f60:0:200::1:1
だった。ちなみに transix の場合は gw.transix.jp
のアドレスを調べる。
$ ping6 dgw.xpass.jp PING dgw.xpass.jp(dgw.xpass.jp (2001:f60:0:200::1:1)) 56 data bytes 64 bytes from dgw.xpass.jp (2001:f60:0:200::1:1): icmp_seq=2 ttl=58 time=3.79 ms ....
ついでにラズパイの eth0
の IPv6 アドレスも調べる。こちらはいつものように ip addr
で見る。
$ ip addr show eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether dc:a6:32:xx:xx:xx brd ff:ff:ff:ff:ff:ff inet 169.254.67.159/16 brd 169.254.255.255 scope global noprefixroute eth0 valid_lft forever preferred_lft forever inet6 2001:f70:a240:xxxx:xxxx:xxxx:xxxx:xxxx/64 scope global dynamic mngtmpaddr noprefixroute # これ valid_lft 2591835sec preferred_lft 604635sec inet6 fe80::470e:xxxx:xxxx:xxxx/64 scope link valid_lft forever preferred_lft forever
設定
IPv4 フォワーディングを有効化し、IPv6 トンネリング機能を有効化。
sudo sysctl -w net.ipv4.ip_forward=1 sudo modprobe ip6_tunnel
いよいよ IPv4 over IPv6 トンネルを張る。ちなみに
を書き忘れるとうまく動かなかったので注意。encaplimit none
sudo ip -6 tunnel add tnl0 mode ipip6 remote 2001:f60:0:200::1:1 local 2001:f70:a240:xxxx:xxxx:xxxx:xxxx:xxxx encaplimit none dev eth0 sudo ip link set dev tnl0 up
ip addr show tnl0
と打ってみて、以下のように、tnl0
というインターフェイスが新たに生成されていれば成功。ping -I tnl0 yahoo.co.jp
などを行い、疎通するか確かめよう。
$ ip addr show tnl0 6: tnl0@eth0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1460 qdisc noqueue state UNKNOWN group default qlen 1000 link/tunnel6 2001:f70:a240:xxxx:xxxx:xxxx:xxxx:xxxx peer 2001:f60:0:200::1:1 inet6 fe80::dcb2:xxxx:xxxx:xxxx/64 scope link valid_lft forever preferred_lft forever
最後の仕上げに、デフォルトルートを tnl0
経由に変更する。PPPoE の設定で、デフォルトルートが ppp0
経由になっているためだ。
sudo ip route delete default dev ppp0 sudo ip route add default dev tnl0
PPPoE の接続時にデフォルトルートが勝手に切り替わらないよう、/etc/ppp/peers/dsl-provider をエディタで開き、「defaultroute
」と書かれた行を探してコメントアウトする。
おわりに
上記の設定のうち、DS-Lite を設定する部分はサーバーを再起動するたびに設定する必要があって面倒なので、似たことをやっているこちらのページを参考に永続化したほうがよいかもしれない。AFTR の IP アドレスも eth0 の IP アドレスもそうそう変わるものではないので、ハードコーディングで良い気がする。(2022/12/11追記)結局、ラズパイ起動時にPPPoE接続を行うために実行される /etc/ppp/ip-up.d/10dsl-provider に、IPv4 over IPv6トンネルを張る上記のコマンドをハードコーディングで追記したが、現時点ではうまくいっている。
参考にしたページ・リンク集
- Raspberry Pi(Linux)を使って楽天ひかりのIPv6(DS-Lite)に繋ぐ方法|OYJ_DANTYO|note
- ほぼドンピシャの実施例。殆どの記事が Raspberry Pi を DS-Lite 対応ルーターにしようとしている中、こちらはラズパイを直接つないだとお見受けした。ちなみにファイアウォール設定は、以前の記事で既に ufw を導入しているので必要ない
- てくろぐ: DS-Lite(RFC6333)対応ルータをLinux (Raspberry Pi) で作る
- 固定IPv4アドレスを失ったので、VPS上にDS-Lite方式に対応したルーターを作ってみた | DevelopersIO
- 自力でIPv4 over IPv6をした(Tunnel編) | 愚行録 the Next Generation