お知らせ

現在サイトのリニューアル作業中のため、表示が崩れているページが存在することがあります。

OCNバーチャルコネクト環境でIPv6サーバーを公開した時にやったことを派生させて更にIPv4にも対応させるプラン。

OCNバーチャルコネクトのIPoEでIPv4 over IPv6のMAP-E環境だと、IPv4ではWell-known portsが開けないが、PPPoEを使って取得したIPv4であれば開けるので、これとIPoE側のIPv6の併用でデュアルスタックでWell-known portsの開放を行い、サーバーを運用できるようにするのが目的だ。

確認環境

環境 内容
ISP OCN光
ISP契約 OCN 光 with フレッツ マンション・スーパーハイスピード 隼・プラン1・西日本
ISP接続方式 OCNバーチャルコネクト(IPoE, MAP-E)
RouterOS OpenWrt 24.10.0
ServerOS Ubuntu 24.04.3 LTS
HTTPD nginx 1.26.1
ドメインレジストラ Value Domain

今回の要件

やり方

サーバー側の準備

ufwではv4にも穴が開いている状態とする

  1. nginxの設定を開きIPv4向けにlisten 443 ssl;を追記して保存する
  2. nginxを再起動する

PPPoEインターフェースの作成

  1. SSHでOpenWrtに入る
  2. /etc/iproute2/rt_tablesを開き次のようにpppoeの行を追加、保存
    #
    # reserved values
    #
    128     prelocal
    255     local
    254     main
    253     default
    300     pppoe
    0       unspec
    #
    # local
    #
    #1      inr.ruhep
    
  3. ルーターを再起動
    • reboot
  4. LuCIに入る
  5. Network→Interfacesを開く
  6. Add new interfaceから、Nameをwanppp、ProtocolをPPPoEとしたインターフェースを作成する
    paste-image-2025-8-22_21-17-30-262.png
  7. General SettingsタブのDeviceにONUと疎通しているポートを指定し、PAP/CHAP usernameとPAP/CHAP passwordにISPの接続情報を入れる
    paste-image-2025-8-22_21-21-59-731.png
  8. Advanced Settingsタブを開き、Use gateway metricを10、Override IPv4 routing tableをpppoe (300)にする
    paste-image-2025-8-22_21-32-25-150.png
  9. Saveボタンを押して保存する
  10. wanインターフェースのEditを押す
  11. Advanced Settingsタブを開き、Use gateway metricを1にする
  12. Saveボタンを押して保存する

ファイアーウォールの作成

  1. 引き続きLuCI上で作業する
  2. Network→Firewallを開く
  3. ZonesのAddボタンを押す
  4. Nameをwan_pppoeにし、MasqueradingとMSS clampingにチェックを入れ、Covered networksでwanpppを選択し保存する
    paste-image-2025-8-22_21-34-55-256.png
  5. lan⇒wanのゾーン設定のEditボタンを押す
  6. Allow forward to destination zones:にwan_pppoeを追加し、保存する
    paste-image-2025-8-22_21-38-35-472.png
  7. Network→Interfacesを開く
  8. wanpppインターフェースのEditボタンを押す
  9. Firewall Settingsタブを開き、Create / Assign firewall-zoneにwan_pppoeが設定されていることを確認する。設定されていなかったら設定する
    paste-image-2025-8-22_21-41-43-664.png

サーバーだけをPPPoEのIPv4通信の対象にする

  1. 引き続きLuCI上で作業する
  2. Network→Routingを開き、IPv4 Rulesタブを開く
  3. General SettingsタブのIncoming interfaceをlanに、SourceをサーバーのIPにする
    paste-image-2025-8-22_21-45-47-319.png
  4. Advanced Settingsタブを開く
  5. Tableにpppoe (300)を設定し、保存する
    paste-image-2025-8-22_21-46-59-928.png

NATを設定する

  1. 引き続きLuCI上で作業する
  2. Network→Firewallを開き、Port Forwardsタブを開く
  3. Addボタンを押す
  4. Nameに適当な名前を付け、Restrict to address familyをIPv4 only、Source zoneをwan_pppoe、External portを443、Internal IP addressを転送先のサーバーIP、Internal portを443にして、保存する
    paste-image-2025-8-22_21-59-16-456.png

疎通確認

  1. Network→Interfacesを開き、wanpppのIPv4を拾う
  2. ドメインレジストラの設定でAレコードにこれを登録
  3. 適当な外部サーバーからcurlを投げて中身が返ってきたらOK
    curl -4 -v https://example.com
    

IP変動対策にDDNSを設定する

/etc/hotplug.d/iface40-pppoeというファイルを作り、以下の内容を記述する。

#!/bin/sh

[ -n "$DEVICE" ] || exit 0
[ "$ACTION" = ifup ] || exit 0
[ "$INTERFACE" = wanppp ] || exit 0

vdpw=ここにDDNS更新用のパスワード
pppoeaddr=$(ip -4 addr show pppoe-wanppp | head -2 | tail -1 | awk '{print $2}')
logger -t "DDNS - PPPoE IP" $pppoeaddr
# hoge.example.comに対して更新リクエストを飛ばす例
logger -t "DDNS - DOMAIN: hoge" $(wget -O - "https://dyn.value-domain.com/cgi-bin/dyn.fcg?d=example.com&p=$vdpw$&h=hoge&i=$pppoeaddr")

# When making requests for multiple domains, wait 60 seconds between each request

このスクリプトはhotplugイベントが発生したときにファイルパス順に呼ばれるスクリプトらしい。

ひとまずデバイスでなく、インターフェイスが起動したときで、かつインターフェース名がwanpppの時に実行されるように組んである。

注意点として、このエンドポイントはレートリミットがシビアで、60秒以内に送ると503を返してくるようなので、複数回投げる場合はsleep 61とかして間隔をあけると良さそうだ。数が増えてきたらバリュードメインAPIのDNS設定APIを利用した方が早いだろう。

ただしこのAPIはTTLの制御に難があり、処理方法によっては3600秒に固定される罠が潜んでいるので注意が必要だ。

トラブルシュート

curlで「Connection refused」や「接続が拒絶されました」と出る

  • /var/log/ufw.logにログがあればufwで穴をあける(まずこれはない)
  • ファイアーウォールかルーティングかNATの設定のどこかがおかしいので見直す。

雑感:かなり苦しい

IPv4, v6のデュアルスタックに出来たのはいいが、幾つかの端末で繋いだところIPv4側に流れるケースがあった。メインのv6でなく、オプションのv4に行くという状況はやや残念だ。

構成的にもマルチセッションという微妙な形態で、v4とv6でインターフェースが二系統あり、セキュリティもNATとFWがあり、なかなか複雑な状態になってしまった。

Mastodonにおいてはv4IPのインスタンス(兵庫丼)との疎通はTLレベルでは出来たものの、画像が出なくなるという頭が痛い問題に出会った。

paste-image-2025-8-23_2-35-19-483.png

Misskey.ioからは疎通できず、こちらからはユーザープロフィールまではアクセスできるがフォローを押しても音沙汰がない。

結論としてはリッチなアプリケーション通信を伴う用途において、この方式は向かない気がした。恐れくこれはルーターより外側がIPoEとPPPoEで別系統になっている関係で、通信が混乱して上手くいかないパターンがあるのではないかと感じている。

DDNSも制約が厳しいし、Value DomainのAPIはあるだけマシではあるものの、超絶使いづらい問題もあり、この環境においてのデュアルスタックはあきらめようと思った。

まぁいい勉強にはなったので、そのうち何かに活かせるだろう、きっと。

本記事はここ昨今のOpenWrtセットアップシリーズの続きである。

OCNバーチャルコネクトのIPoEでIPv4 over IPv6のMAP-E環境だと、IPv4ではWell-known portsが開けない。しかし、IPv6であれば、理論上全部のポートが使えるはずで、それであればサーバーを建てられるのではないかと考えたので、やってみた記録。

確認環境

環境 内容
ISP OCN光
ISP契約 OCN 光 with フレッツ マンション・スーパーハイスピード 隼・プラン1・西日本
ISP接続方式 OCNバーチャルコネクト(IPoE, MAP-E)
RouterOS OpenWrt 24.10.0
ServerOS Ubuntu 24.04.3 LTS
HTTPD nginx 1.26.1
ドメインレジストラ Value Domain

前提条件

IPv4環境下でのHTTPSアクセスが可能で、かつ以下のセットアップが終わっているものとする。

今回の要件

ルーターのファイアウォールでサーバーマシンのみ穴をあけ、それを塞ぐ。つまりNATの再現を行うことで、関係ない端末が攻撃されないようにする。

やり方

サーバーとDNSの設定

  1. nginxの設定を開きlisten [::]:443を追加して再起動
    1. sudo service nginx restart
  2. サーバーマシンのIPv6を控える
    ip -6 addr | grep 'global dynamic' | perl -ale '$F[1] =~ /^([^\/]+)/; print $1;'
    
  3. Value DomainのDNS設定を開きAAAAレコードに、先ほど控えたIPv6アドレスを登録する

ルーターのファイアウォールに穴をあける

  1. LuCIに入りNetwork→Firewall→Traffic Rulesを開く
  2. Addボタンを押し、次の要領で入力して保存
    General Settings

    項目
    Name 適当につける
    Protocol TCP│UDP
    Source zone wan
    Destination zone lan
    Destination address さっき控えたサーバーのv6IPアドレス
    Destination port 開けたいポートを半角スペース区切りで入れる

    Advanced Settings

    項目
    Restrict to address family IPv6 only
  3. 穴をあけたIP以外が外部から疎通しないことを確認

  4. 穴をあけたIPが外部から疎通することを確認

備考

OCN光のIPoE(MAP-E)方式のIPはv4, v6ともに基本的に変動しない

結論から言うと引っ越しでもしない限り、v4が固定なのは知っていたが、v6も固定らしい。

v6のアドレスが変わる気配がないので、OCNのテクニカルサポートに聞いた結果、PPPoEは変動IPv4でルーター再起動時にIPが変わるが、IPoEであればIPv4, IPv6ともに半固定で通常は変わらないとのことだった。

つまりVLANやip6tablesがなくてもサーバーを公開できると言う事でOCN様々と言う事である。

IPv4アクセスをどうするか?

現状は2案検討している。

  1. どっかにペラのページを置いておき、「IPv6でアクセスしてください」みたいなお知らせページにしておく
  2. SNSなどのOGP対策で、簡単なプロキシを組んでおき、OGPだけ出るようにしておく

2のケースだとレンサバにv6側サイトのOGP取得用のCGIを置いておくとか、v6側サイト更新時にOGP付きのペラのHTMLを置いておくなどが検討できると思う。

Cloudflare Tunnelを使わない理由

以前Claudflare CDNを使った時の悪印象を引きずっている部分が大きいが、基本的にオンプレミス至上主義だからというのが答えにはなる。

以前Claudflare CDNを使おうとするとドメインをClaudflare側に持ち込む必要があったのだが、この時にさくらのレンタルサーバーのSPFレコードが正常に扱ず、メールが使えない事態になった。また他にも、管理画面のUIがお世辞にもよくなく、言葉を選ばず言えばクソである点もある。

Cloudflare Tunnelでも同様のことになるかどうかは不明だが、前述の内容以外にも個人的にはCloudflareのWAF機能やhCAPTCHAがユーザーとして嫌いなのもあり、全体的にCloudflareに対してよい印象がないところが大きい。勿論、余計なレイヤーを増やすことによる運用コストの増大もあるので、実務的にもない方がいい。

VPNにリバプロを書けるのも検討したが、レガシーに縋っていても仕方がなく、今のところはIPv6に注力する方向にしようとしている。世界のv6以降に末端からでも貢献出来たらいいなくらいの気持ちでやっていくのだ。

関連記事

OCNバーチャルコネクトはIPv6を使う限り全ポート使えるはずなので、これを利用してサーバーを立てる。

確認環境

  • OpenWrt 24.10.0
  • OCNバーチャルコネクト
  • Windows 11 Pro 24H2
  • Ubuntu 22.04.5 LTS
  • nginx 1.26.1

手順

ルーター側だけでなくサーバー側も対応が必要。ファイアーウォールの穴をあけていても、IPv6でlistenしてないと受けられない。

ここでは一旦80番ポートを開けるものとして進める。

ルーター側の設定

設定ファイルを編集する方法
  1. vi /etc/config/firewallで以下の行を追加
    config rule
            option name 'Allow-Server-IPv6'
            option src 'wan'
            option dest 'lan'
            option proto 'tcp udp'
            option dest_port '80'
            option family 'ipv6'
            option target 'ACCEPT'
    
  2. service firewall restartでfirewallを再起動する
LuCIでやる方法
  1. Network→Firewall→Traffic Rules
  2. Addから次の要領でルールを追加
    General Settings

    項目
    Name 適当な名前
    Protcol TCPとUDPにチェック
    Source zone wan
    Destination zone lan
    Destination port 開けるポートをスペース区切り

    Advanced Settings

    項目
    Restrict to address family IPv6 only
  3. 保存してSave & Apply

サーバー側の設定

ufwやWindowsファイアーウォールの穴は開いているものとする。IPv6向けに穴が開いている必要があるが、通常、ufw addやWindows ファイアーウォールの追加では勝手にv6の穴が開くはずなので意図的に塞がない限り追加時に開いていると思われる。

  1. nginxの設定を開きlisten [::]:80を追加する
  2. 外部から疎通確認して通ればOK

備考

疎通検証に使える簡易サーバー

PHP

php -S "[::]:80"でIPv6向けの簡易サーバーをサクッと立てられるので疎通検証をするときに便利。

Node.js

http-serverだとhttp-server -p 80 -a "[::]"でいける。serveは未対応っぽい。

疎通確認に使えるcurl例

IPv6はURL形式が特殊なのでアドレス部分を[]で囲んだ書式で投げる。これはブラウザで確認する場合でも変わらない。

例:

curl -v "http://[aaaa:bbbb:cccc:dddd:eeee:ffff:gggg:hhhh]:80/"

複数ポートの開き方

option dest_portに値を半角スペース区切りで追加すればよい。

例:

option dest_port '80 443 8080'

連番で開ける場合は公式ドキュメントによると、'1024:65535'のような書式にすれば、連番で開けられるようだ。

例:

option dest_port '8000:8999'

特定端末向けだけにポートを開けたい場合どうするか(未解決)

設定にoption dest_ipを追加し、これで制御できると思うがIPv6が変わる特性上、基本的に難しいと思う。勿論、端末側でIPの変更を検知しOpenWrtの設定を書き換えるバッチを組むなどは出来ると思うが、ややこしい。

VLANを使って隔離するとかできればよいのかもしれないが、具体案は検討できていない。