おうちネット、最近は楽天ひかりを契約してます。 楽天モバイルとセットで申し込むと、ひかりも通信料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.X
とY.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
はそもそも届いてない。 途中の誰かが捨ててるのかな……(ここわからん)