ラズパイ自宅サーバで PPPoE と DS-Lite を自力で行う方法【楽天ひかり】

投稿者: | 2022年9月23日

以前の記事で、ラズパイの wlan0 と eth0 を 併用し、IPv4/IPv6 両方からアクセスできるラズパイサーバーを作りました。

今回は、「eth0 にも IPv6 グローバルアドレスが割り当てられているのだから、それを使って外からアクセスすれば良いのでは?」との友人のコメントをきっかけに、別のアプローチで同じことをやったので報告します。

実現できたこと

IPv4IPv6
ラズパイ → インターネット方向の外向きアクセス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トンネルを張る上記のコマンドをハードコーディングで追記したが、現時点ではうまくいっている。

参考にしたページ・リンク集

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA