6715.jp

2020-12-16

DS-Lite/PPPoE併用環境で自宅サーバの通信だけPPPoEを通す

sekaisekai
DS-LitePPPoEアドベントカレンダーインフラネットワーク

おうちネット、最近は楽天ひかりを契約してます。 楽天モバイルとセットで申し込むと、ひかりも通信料1年間無料になって激アツです。

IQ1 Advent Calendar 2020 - 16日目の記事です。

自宅サーバ

世はまさに大クラウド時代! 自宅サーバとかいう文字列を目にすることも、こころなしか少なくなったような気がします。

普通の家庭向けインターネット接続サービスではIPv4アドレスが1つしか割当されないのに対して、宅内にはたくさんの端末がある……ので、NAPTでうまいことさばいているのが普通かと思います。 こういう環境下で家にサーバを置くには、いわゆるポート開放1、静的NAPTの設定が必要になるわけですね。

IPv4 over IPv6での自宅サーバ公開

楽天ひかりはIPv4 over IPv6に対応しています。 このやりかたでIPv4ネットワークに接続すると、旧来のPPPoEによる接続と比較してパフォーマンスが良い、とされています。

IPv4 over IPv6の実現する方式にはいくつか種類があって、楽天ひかりはXpass(クロスパス)と呼ばれる方式を利用しているとのこと。なんだかカッコいい名前がついていますが、一般的にはDS-Liteと呼ばれるやつですね。

が、DS-Lite方式のIPv4 over IPv6では、いわゆるポート開放ができません。残念。 では自宅サーバは公開できないのか?というとそうでもなくて、依然として旧来のPPPoE接続はできるので、こっちを通るようにすれば良いです。

DS-LiteとPPPoEの併用

家庭用のルータだとそもそもコレができる機種は限られています。 ここは課金ポイントです。業務用っぽいやつを買いましょう。

ボクはYAMAHAのNVR510を買いました。 具体的な設定手順は省きますが、DS-LiteとPPPoEの両方でIPv4ネットワークに接続できたとしましょう。

当然ですが、DS-Lite側とPPPoE側で別々のアドレスX.X.X.XY.Y.Y.Yを持っているような状態になっています。

普段の通信は、パフォーマンスが良いとされているDS-Lite側(tunnel 1)を通したいです。 なので、デフォルトゲートウェイはこっち側にします。

ip route default gateway tunnel 1

こういう感じになっています。

自宅サーバ宛の通信をPPPoE側で受け入れる

今回はHTTPサーバを公開するということにして、PPPoE側のアドレスに来た80/tcpの通信をサーバが受け取れるように、静的NAPT2エントリを追加します。

nat descriptor type 1 masquerade
nat descriptor masquerade static 1 100080 192.168.0.250 tcp www
pp select 1
  ip pp nat descriptor 1

これで、外の端末からの通信がサーバに到達できるようになりました。 TCPだと、まずSYNパケットが送られてきますよね。

で、サーバはSYN/ACKで応答するわけです。3-wayハンドシェイクというやつの2番目です。 クライアント(Z.Z.Z.Z)がどこにいるなんて末端のサーバは知りません。なので、とりあえず家庭内のルータに丸投げします。当の家庭内ルータもその上位ルータへ投げるだけです。このとき、デフォルトゲートウェイをDS-Lite側に設定しているので、当然このSYN/ACKもそっち側に行ってしまいます。

すると、クライアントからするとおかしな事が起こっているように見えるわけです。Y.Y.Y.Yに送ったSYNの返答がなぜかX.X.X.Xから帰ってくる……これではTCP接続は確立できません。 返りの通信もPPPoEを通るようにしないとダメそう。

ちなみに、UDPならこの状態でも通信できる可能性があります。

返りの通信もPPPoEを通す

ポリシーベースルーティング(PBR)3をします。 ある条件に合致するような通信だけ、別の経路に流したりできる機能です。 これも業務用クラスのルーターじゃないと使えない場合が多そうです。

今回は、HTTPサーバを公開したいという状況なので、送信元が件の自宅サーバでかつポート番号が80のときだけ、PPPoE側(pp 1)にルーティングするようにします。

ip filter 100080 pass 192.168.0.250 * tcp www *
ip route default gateway pp 1 filter 100080 gateway tunnel 1

これで、こうなります。SYNのdstとSYN/ACKのsrcが一致して、クライアントはACKを返してくれることでしょう……晴れて接続確立です。

おしまい

おわりです。 なんかもっといい方法ないのかな。

おまけ:パケットキャプチャ

サーバ側はこう。192.168.0.250が宅内のサーバで、133.130.113.115は外にいるクライアント。 SYN/ACKをめちゃ再送している。 クライアントが再送したSYNもいっぱい来てる。

クライアント側。 SYNを再送してる。サーバが送ったSYN/ACKはそもそも届いてない。 途中の誰かが捨ててるのかな……(ここわからん)


  1. この言い方は好きじゃないですが、よく使われているのでコレで……
  2. YAMAHA製品ではIPマスカレードという名称
  3. YAMAHA製品ではフィルタ型ルーティングに相当