ルータ2台体制によって自宅サーバにIPv4でもIPv6でもアクセスできるようにした

この記事は技術同人誌「きつねまち1」に収録しています。

こんにちは。コンちゃんこと佐々木です。
先日、自宅ネットワークのルータを買い換えて、IPv6対応となりました。
通信速度が上がって万々歳でしたが、1つ問題が。
うちは自宅webサーバを動かしています。この自宅サーバに対して、IPv4環境からアクセスできなくなってしまいました。
IPv6(IPoE)用ルータとIPv4(PPPoE)用ルータの2台構成にすることでなんとか問題解決となったので、詳細を書き記しておきます。


背景・環境

うちには自宅webサーバがあります。
常時電源ONで、ラックみたいな置き場に置いています。Ubuntuの上でWordPressが動いていて、外向けにブログを公開しています。本記事もこのサーバから提供しています。
先にリンクを張りましたが、回線自体はIPv6対応済みで、ルータをIPv6対応のものに交換したことでIPv6が疎通しました。

環境

  • サーバ
    • 2008年モデルのノートPCを再利用(WinXPが動いていました)
    • OS: Ubuntu Server 18.04 LTS(32bit)
    • メモリ: 1GB
    • Webサーバとして、自サイトを世界に公開している
    • 有線LAN接続
  • 回線
    • ドコモ光+NTTぷららの1G固定回線
      • ぷららの場合は「OCNバーチャルコネクト」という名前のIPv6接続サービスを使用している(意識することはほぼない)
      • OCNバーチャルコネクトは「MAP-E」という方式(技術)を使っており、本方式であれば別の接続サービス名でも本記事の内容が適用できるかもしれない
    • IPアドレスの固定サービスは使用せず、変動式
  • ドメイン
    • conchan.akita.jpをドメイン会社から購入
    • DDNS(Dynamic DNS)はMyDNSを使用
      • ドメインに対応するIPアドレスを定期的に更新している
  • 交換前ルータ: Buffalo WHR-1166DHP3
  • 交換後ルータ: Buffalo WSR-3200AX4S
  • その他、自作PCやスマホPixel3などの端末が有線や無線でインターネット接続している

ルータ交換前ネットワーク図

IPv4しか使えなかった頃です。

ルータのNAPT機能を使用し、宛先ポート番号が80番(http)・443番(https)のアクセスは自宅webサーバに向くように設定しています。

ルータ交換後ネットワーク図

今回の問題が起きていた環境です。

機器的にはルータが代わっただけですね。

問題の詳細

外からIPv6で繋げられる環境では自宅webサーバにアクセスできたはずですが、IPv4だと繋がりません(「はず」としたのは、外からIPv6接続を確認できる機器がなかったため)。

実はIPv6環境下(厳密にはMAP-E環境下?)では使えるポートに制限がかかります。
webサーバですので、当ブログを閲覧しようとした人はhttpの80番ポートやhttpsの443番ポートを宛先ポート番号としてアクセスを試みますが、恐らくプロバイダ管理の機器で弾かれてしまいます。
80や443といったwell-knownポートが弾かれるのは何かの間違いでは!?と思ったのですが、正しいっぽいです。

どうしてIPv6環境下でポート制限をかけているかというと、IPv6環境下でIPv4通信するときの接続端末の特定には「IPv4+ポート番号」が使われるからです。
ポート番号も端末特定に必要なので、ポート番号の管理もプロバイダ側持ちとなり、人によって使えるポートが異なることとなり、筆者のところには80や443が割り振られないこととなったのですね。
別の言い方ですと、IPv4環境では端末の特定は単にグローバルIPv4アドレスだけでしたが、IPv6環境ではIPv4アドレス単体でグローバルとは呼べなくなりました。
また、MAP-E限定かもですが、IPv6アドレスとIPv4アドレス+使用可能ポート群は1:1で紐づいています。
IPv6アドレスからIPv4アドレス+使用可能ポートを引けるサイトもあります。

ここでちょっとよく分かっていないことがあって、「IPv6環境下のポート制限はIPv6アドレスにも適用されるか?」ということです。
表にすると以下になります。

IPv4のみの環境IPv6のみの環境
IPv4で通信ポート制限なしポート制限あり
IPv6で通信ポート制限あり?なし?

たぶん、「ポート制限なし」だとは思っています。
IPv6は割り振れる数が潤沢で、端末ごと(厳密にはインターフェースごと?)にグローバルIPアドレスが割り振られるので、端末の特定はポート番号を使用せずできますからね…。
いろいろなサイトを見て、使用できるポートに制限がかかることは分かったのですが、それがIPv4通信のみに適用されるのかIPv6通信にも適用されるのかまでは書かれていなくて、明確には分かりません。
ただ、現にIPv6でhttp(s)アクセスを受付できているので、きっと「書くまでもなくIPv4のみ」ってことなんだろうなぁ…。

対策案

IPv6環境下でIPv4でも自宅サーバを公開するためには、以下の方法があります。

  • 使用可能なポート番号を使う案
    • 使用するポート番号を変えられるアプリケーションならOKですが、http(s)は80(443)を使うと全世界的に決まっており、webサーバの用途では本案は採用不可
  • 自宅サーバとのIPv4通信は今までどおりPPPoEセッションを使用する
    • ルータを2台用意し、片方をPPPoE専用とする案
    • サーバが自力でPPPoEセッションを張る案
      • サーバ側でPPPoEの設定をする(サーバがPPPoEルータを兼ねるイメージ)
      • サーバにあらゆるアクセスが来るため、ファイアウォール設定もして必要な通信だけ通るように防御する
    • IPoEとPPPoEの両方をさばける高機能ルータを使う
      • ヤマハの数万円のルータが対応しているらしい?

やったこと

サーバが自力でPPPoEセッションを張るための設定が難しそうだったため(PPPoEとIPoEの自動切り替えとか)、「ルータを2台用意し、片方をPPPoE専用とする案」を採用しました。
手元に残していた交換前のルータをPPPoE用に転用することにしました。

ネットワーク構成の変更

最終的に、以下のネットワーク図の構成となりました。

新旧2つのルータを使用しています。
新しい方のルータがメイン的な立ち位置で、IPoE通信はこのルータで処理し、配下の端末に流します。
一方、PPPoE通信は新しいルータにはスルーさせ、古いルータに処理させます。
2台のルータ間には2本のLANケーブルで結ばれており、ループ感がありますが、「新ルータの配下の単なるアクセスポイント」としてのIPoE線と、旧ルータのWANポートに入り旧ルータでルーティング処理させるPPPoE線で仕事が分かれています。

「使用する通信規約と通信する端末ごとの通信方式表」も用意しました。
左が通信規約、上が通信端末です。
通信相手の端末やそこまで到達するための経路が全てIPv6対応しているなら「IPv6」が、それ以外は「IPv4」が自動で採用されます。

家の普通のPC・スマホ自宅サーバ
IPv4IPoEに包まれる(IPv4 over IPv6)PPPoE
IPv6IPoEIPoE

IPv6で通信できる場合は、家の普通のPC・スマホの通信も自宅サーバの通信もIPoEを通ります。
一方、それができない場合はIPv4で通信しますが、家の普通のPC・スマホの通信はIPv4でもIPoEの中を通し、自宅サーバの通信はPPPoEを通すようにします。
IPoEを通せるものは極力IPoEを通すことで、なるべく高速通信が適用されるようにしています。

見栄えがよくないですが、写真も撮ってみました。

左端がONU、その右が新ルータ、一番右が旧ルータ。

ルータの設定

ルータが2台になりますが、両方ともDHCP機能がONだと、ネットワーク内でIPアドレスが重複してしまい、うまく通信できません。
DHCP機能はIPoEルータだけにおまかせするようにしましょう。
また、ルータ自身のIPアドレスが2台で重複しないようにも注意してください。
私は見事にやらかしましたのでね…。
IPoEルータを 192.168.1.1 にした場合はPPPoEルータの方は 192.168.1.2192.168.1.100 を明示的に指定しましょう。

IPoE用ルータ
ポイントは以下2点です。

  • PPPoEパススルー機能をONにしてPPPoE通信はPPPoEルータに流す
  • DHCP機能はONのままだが割り振るアドレスを厳しめに制御する

スクリーンショット撮りました。

IPアドレス取得方法はOCNバーチャルコネクト指定です。
自動だとインターネット@スタートになると思いますが、直接指定の方がいいかなーって。
あと、MACアドレスの変更もここでできますが、IPoE側はそのままにしています。

PPPoE接続の設定はなし。

IPv6接続方法はあまりよく分かっていませんが、とりあえずセキュリティ的に「NDプロキシ」が良いらしく、これで。

LAN設定。
ここが肝かも。
IPoEルータとPPPoEルータのIPアドレスを決めておいて、それらがDHCPで割り当てられないようにしておきます。

DHCPリース。
サーバ(画像内緑色マスク)は手動割り当てにしました。

IPv4フィルター。
正直必要なのかよく分からないのですが、http(s)は自宅サーバのローカル固定IPアドレスに飛ぶように設定しました。

IPv6フィルター。
これも必要かよく分からないのですが、http(s)は自宅サーバの(固定ってことにしている)IPv6アドレスに飛ばすようにしました。

パススルー設定。
PPPoEパススルー機能をONにしました。

ポート変換画面。
特に何も設定せずです。


PPPoE用ルータ
続いて古い方のルータです。
DHCP機能はOFFにしましょう。
もしPPPoEルータ経由でスマホ等をネットにつなげたい場合は、接続時に人力でIPアドレスを入力すればOKです。
5GHzと2.4GHzのうち、5GHzの方は使わないので停波しました。

IPアドレス取得方法は「PPPoEクライアント機能を使用する」を選択しました。
DNSサーバーアドレスはプロバイダーからの開通お知らせの紙に書いてあったものです。
MACアドレスは変えてみました、WAN側とLAN側で一緒だとループとか起きちゃうかもと思って。。。

PPPoE接続設定もプロバイダーからの開通お知らせの紙のもの。
あと、Internet@Start等はOFFにしました。

LAN設定。
DHCPをOFFにするのと、ルータ自体のIPアドレスを重複させないこと、これが大事ですね。
割り当てIPアドレス欄は入力できないようになっていますが、前にあがいた時の値が残っちゃっているので、隠しています。

ポート変換。
80番と443番へのアクセスをサーバのローカル固定IPアドレス(の同ポート)宛に転送するように設定しました。
この設定は確実に必要かと。

Ubuntuのネットワーク設定変更

IPv6を受け付けるようにnetplanの設定を変更しました。
設定ファイルは /etc/netplan/ のconfigファイルです。
ポイントは以下です。

  • サーバは固定アドレスとするのでDHCPはfalseにする
  • 固定アドレスを書く
    • ローカルIPv4アドレスは好きにできる
    • IPv6アドレスは固定プランじゃないので変動可能性あるけど実際はあんまり変わらないっぽいのでひとまず書いちゃった
  • gateway(自宅ネットの出口端末)はIPv4側はPPPoEルータ、IPv6側はIPoEルータのアドレスを書く
    • ルータの設定画面のどこかから拾ってきたはず
  • nameserversも両ルータのアドレスを書いてみた
  • シングルクォーテーションで囲まないとうまく動かなかったところがあるので囲んでおく

ファイル全容も載せておきます(一部ぼかしています)。

/etc/netplan$ cat 04-network-setting-20210315.yaml
network:
        version: 2
        ethernets:
                enp1s0:
                        dhcp4: false
                        addresses: [192.168.x.x/24, 'fd9c:yyyy:yyyy::yyyy/64']
                        gateway4: 192.168.x.2
                        gateway6: fe80::xxxx:xxxx:xxxx:b1a0
                        nameservers:
                                addresses: [192.168.x.2, 'fe80::xxxx:xxxx:xxxx:b1a0']
                        optional: true
                        dhcp6: false

nginxの設定変更

/etc/nginx/conf.d の設定ファイルを確認したところ、もうIPv6を受け付けるようになっていましたので、ここは変更なし。

    listen 80 default_server;       # IPv4
    listen [::]:80 default_server;  # IPv6

MyDNSへの通知設定変更

webサーバからMyDNS宛に、今自分(サーバ)に振られているアドレスを通知しています。
通知は、MyDNS側指定のURLをwgetするのをcronで定期実行することで実現しています。
ここで、IPv4アドレスとIPv6アドレスの両方が通知されるようにします。うちの設定ファイルは最終的に以下の形になりました。

#!/bin/sh
#
/usr/bin/wget --bind-address=192.168.x.x -O - 'https://mydnsXXXXXX:PASSWORD@ipv4.mydns.jp/login.html'
/usr/bin/wget -O - 'https://mydnsXXXXXX:PASSWORD@ipv6.mydns.jp/login.html'
#

ipv4.mydns.jp 宛と ipv6.mydns.jp 宛にwgetしています。
ipv4側には --bind-address オプションを付与し、サーバに固定したローカルIPv4アドレスを指定しています。
これにより、IPoE経路ではなくてPPPoE経路を使って通信し、PPPoE経路に割り振られているグローバルIPv4アドレスをMyDNSにお知らせしています。
これがないと、IPoE経路で通信してしまってIPoE経路に割り振られているIPv4アドレスを通知してしまうはずです。

おわりに

ルータを2台使うという荒業?で、なんとか自宅サーバにIPv4でもIPv6でもアクセスできるようになりました。
いやーなんとかなってよかった。
事象解決に1か月、記事執筆にさらに1か月くらいかかっちゃったんですよ!!

ところで、旧ルータの有線LANポートは上限が100Mbpsなので、IPoEで自宅サーバと通信するときもIPoEの高速性を生かせていません。
そもそもサーバ本体側のLANポートも100Mbps上限だったりします。
そんな自宅サーバですが、ノートPCを転用しているので、無線LANも搭載しています。
ということは、ネットワークインターフェースが2つあることになるのでしょうか。
そうなると、片側をIPoE用、もう片側をPPPoE用という風にインターフェース単位で分けられそうで、1インターフェースで両対応するよりは楽そう。
で、その無線もIEEE802.11b/gしか対応していないので、上限54Mbpsなんですけどね……。

ではこのへんで。
最後に参考リンクを羅列します。
50サイトは見た気がしますが、中でも特に記憶に残っているサイトだけ厳選しました。

参考

コメントを残す

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)