お知らせ

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

Google Analyticsを廃止してMatomoを導入してから集めていたIPv6のアクセス比率を集計した結果をメモしておく。

集計期間は2025/08/17~2025/10/21。

サイト IPv6ビジット IPv4ビジット
lycolia.info 56 (55.0%) 77 (45.0%)
ブログ (blog.lycolia.info) 2,018 (43.4%) 2,644 (56.7%)
ECO-Wiki (eco.lycolia.info/wiki) 7,946 (40.5%) 11,291 (59.4%)
ツールサイト (tool.lycolia.info) 13 (65.0%) 7 (35.0%)
合計 10,033 (41.7%) 14,019 (58.2%)

以上の結果からIPv6は約四割、v4は約六割ということが分かった。また最もアクセスがあるのはECO-Wikiで、ツールサイトにはほぼアクセスがないことも明確になった。まぁツールは私が使えればいいので仕方ないね。

lycolia.infoは突出してIPv6のアクセスが多いが、実数が少なすぎるので余りアテにならない。ただ恐らく、リンク元の特性的に、ITオタク周りのアクセスが多いことが想定されるため、この結果はある程度妥当かもしれない。ツールサイトもそういう人が興味を持って踏んでるのだとしたら納得だ。ブログも技術記事がある関係で比率が高い可能性がある。

逆にECO-Wikiは比較的一般向けのサイトなので比率が少なくなっていると思った。

あとがき

まだまだIPv4の環境は多く、IPv6シングルスタックへの移行はやや戸惑うレベルだ。GitHubのWebhookもIPv4だったりするので、しばらくはデュアルスタックで運用していくのが無難だろう。

現状さくらのレンタルサーバー上にある資源を自宅サーバーにフル移行する場合、DNS側の制約でマルチドメインのDDNSが面倒な問題があるため、専用のスクリプトを作る必要が出てきそうだ。

これは契約しているDNSサーバーのDDNSが1回に1レコードしか更新できず、レートリミットが60秒に1回という面倒な仕様なため、ドメインが複数あると厄介なのだ。現状Mastodonだけが自宅サーバーにある状態なのでどうにかなっているが、どうにかして対処しないといけない。

契約しているDNSサーバーにはDDNS API以外にも、DNSレコードを全部書き換えられるAPIがあり、こちらは1回に複数レコードを触れるため、比較的レートリミットを気にする必要がなくなる。なので、これを使って自力で書き換えるスクリプトを組めばDDNS APIのレートリミットは無視できるようになる。まぁ、こっちのAPIはレートリミットが緩いので何度でも叩けるのだが、バルク編集できるAPIを何度も叩く意味もないので…。

これとは関係なく、将来的には自宅サーバー側に権威DNSを立てて、レジストラのDNSサーバー側にはNSレコードだけというのもやってみたさがある。この場合、ドメインの追加や削除で一々レジストラの管理画面にアクセスする頻度が減らせ、管理が楽になるメリットがありそうだし、レジストラのDNSでは実現できないことが出来るようになる可能性もあるだろうから面白いかもしれない。

投稿日:ネットワーク::IPv6

確認環境

NICはともに一つのみ。

  • Windows 11 Pro 24H2
  • Ubuntu 24.04.3 LTS

Windows

NICのIPv6アドレス(GUA)を取得する

コントロールパネルから取得
  1. コントロールパネル→ネットワークと共有センターを開く
  2. イーサネット→詳細を開く
  3. IPv6アドレスと書かれているのがGUA
コマンドプロンプトで取得

ipconfigを叩き、「IPv6 アドレス」と書かれているものがGUA

Powershellで取得
(ipconfig | Select-String -Pattern "IPv6 アドレス(?: .)+: (.+)").Matches.Groups[1].Value

Ubuntu

# perl版
ip -6 addr | grep 'global dynamic' | perl -ale '$F[1] =~ /^([^\/]+)/; print $1;'

# awk版
ip -6 addr | grep 'global dynamic' | awk '{ split($2, a, "/"); print a[1] }'

OCNバーチャルコネクト環境でIPv6サーバーをポート443で公開した時にやったことを派生させて更に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. 反映する
    • service network restart
  4. LuCIに入る
  5. Network→Interfacesを開く
  6. Add new interfaceから、Nameをwanppp、ProtocolをPPPoEとしたインターフェースを作成する
  7. General SettingsタブのDeviceにONUと疎通しているポートを指定し、PAP/CHAP usernameとPAP/CHAP passwordにISPの接続情報を入れる
  8. Advanced Settingsタブを開き、Use DNS servers advertised by peerのチェックを外し、Use gateway metricを10、Override IPv4 routing tableをpppoe (300)にする
  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を選択し保存する
  5. lan⇒wanのゾーン設定のEditボタンを押す
  6. Allow forward to destination zones:にwan_pppoeを追加し、保存する
  7. Network→Interfacesを開く
  8. wanpppインターフェースのEditボタンを押す
  9. Firewall Settingsタブを開き、Create / Assign firewall-zoneにwan_pppoeが設定されていることを確認する。設定されていなかったら設定する

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

  1. 引き続きLuCI上で作業する
  2. Network→Routingを開き、IPv4 Rulesタブを開く
  3. General SettingsタブのIncoming interfaceをlanに、SourceをサーバーのIPにする(例:192.168.1.5/32
  4. Advanced Settingsタブを開く
  5. Tableにpppoe (300)を設定し、保存する

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にして、保存する
  5. 最後にこれまでの内容をSave & Applyする

疎通確認

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

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

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

#!/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の設定のどこかがおかしいので見直す。

同一LANにぶら下がっている端末でDNS解決に失敗する

PPPoEインターフェース(wanppp)の設定を開き、Advanced SettingsからUse DNS servers advertised by peerのチェックを外すと直る。

雑感:かなり苦しい

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

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

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

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

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

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

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

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

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

セキュリティを考慮し、サーバー以外にはアクセスできないよう、NATのような仕組みで構築する。

確認環境

環境 内容
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アクセスが可能で、かつ以下のセットアップが終わっているものとする。

今回の要件

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

やり方

サーバーとDNSの設定

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

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

設定ファイルを編集する方法
  1. vi /etc/config/firewallで以下の行を追加
    config rule
            option name 'Allow-Server-IPv6'
            option src 'wan'
            option dest 'lan'
            option proto 'tcp udp'
            option dest_ip 'さっき控えたサーバーのIPv6アドレス'
            option dest_port '443'
            option family 'ipv6'
            option target 'ACCEPT'
    
  2. service firewall restartでfirewallを再起動する
LuCIでやる方法
  1. LuCIに入りNetwork→Firewall→Traffic Rulesを開く
  2. Addボタンを押し、次の要領で入力して保存
    General Settings

    項目
    Name Allow-Server-IPv6
    Protocol TCP│UDP
    Source zone wan
    Destination zone lan
    Destination address さっき控えたサーバーのIPv6アドレス
    Destination port 443

    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を使わない理由

Cloudflare Tunnelを使えればIPv4を利用でき、デュアルスタック対応もできるだろう、しかしなぜ使わないのかという話。

基本的にオンプレミス至上主義だからというのが答えにはなるが、実務的な理由もある。

まずCloudflare Tunnelを利用する場合、ネームサーバーを委任する必要があるが、CloudflareのDNSはさくらインターネットのSPFレコードを扱おうとするとバリデーションエラーを吐いて使えない。他にも、管理画面のUIがお世辞にもよくなく、言葉を選ばず言えばクソである点もある。勿論、余計なレイヤーを増やすことによる運用コストの増大もあるため、使わなくて済むのであれば、それに越したことはないという考えだ。

またCloudflareのWAF機能やhCAPTCHAがユーザーとして嫌いなのもあり、自分が嫌いなものをユーザーに提供したくないのもあるし、Cloudflareのエラー画面を見て嬉しく思う人もいないと思うので、あのインフラには乗りたくない思いもある。

IPv4のデュアルスタック対応としては、VPNにリバプロをかけるのも検討したが、レガシーに縋っていても仕方がなく、今のところはIPv6に注力する方向にしようとしている。世界のIPv6移行に末端からでも貢献出来たらいいなくらいの気持ちでやっていくのだ。

疎通検証に使える簡易サーバーの作り方

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/"

ドメインを利用する場合に、リクエスト先をAレコードとAAAAレコードで明示的に分ける場合は、以下の書き分けができる。

# IPv4向け
curl -4 -v "http://example.com/"
# IPv6向け
curl -6 -v "http://example.com/"

複数ポートの開き方

option dest_portに値を半角スペース区切りで追加すればよい。LuCIでも同じ書き方で通用する。

例:

option dest_port '80 443 8080'

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

例:

option dest_port '8000:8999'

関連記事

このコマンドをcronとかで回し続けてれば行けそう

事前準備

Value-Domainのコンパネから登録対象のDNSレコードにaaaaレコードを足しておく。

コマンド

ipaddr=$(ip a | grep 'scope global temporary dynamic' | perl -ne '/inet6 ([^\/]+)/; print $1')
echo 'https://dyn.value-domain.com/cgi-bin/dyn.fcg?d=<ドメイン>&p=<パスワード>&h=<ホスト名>&i='$ipaddr

凡例

項目
ドメイン example.comみたいなルートドメイン
パスワード Value-DomainのDDNSパスワード
ホスト名 sub.example.comのsubの部分

参考