
1. はじめに
自宅に待望の10G光回線を導入し、Ubuntuでせっせと10G自宅サーバーを構築したものの……多くのアキレス腱となるのが IPv4(MAP-E / v6プラス等)による「ポート開放の制限」 です。
ウェルノウンポート(80/443)を開放できない問題を解決するため、「屋外からは一度ConoHa VPSなどの外部VPS(IPv4)を経由させ、リバースプロキシで自宅サーバーへ転送する(串を通す)」 という構成をとっている方も多いのではないでしょうか。
確かにこの「VPS中継」を使えば、IPv4環境からでも問題なくWebサイト(test-site.online など)を公開できます。
……しかし、ここで1つの切実な問題にぶち当たります。
「せっかく自宅に10G回線を引いているのに、すべての通信をVPS経由にしたら、VPSの帯域やリソース制限がボトルネックになって10Gの速さが死んでいませんか……?」
そう、VPSを挟むこと自体は安全・確実な解決策ですが、10G回線が持つ本来のパフォーマンスをドブに捨てている状態とも言えます。
そこで今回提案するのが、「IPv6直結」と「MAP-E(IPv4)VPS中継」を組み合わせた「二刀流(Dual Stack)」構成です!
- IPv6環境からのアクセス: VPSを挟まず、自宅10G回線へダイレクト接続(爆速アクセス!)
- IPv4環境からのアクセス: 従来通りVPS経由で安全に通信をカバー(自宅ポート
50080等へ転送)
この「二刀流」を仕込んでおけば、既存のIPv4互換性を100%保ったまま、IPv6ユーザーに対して自宅10G回線の真価をフルに発揮させることができます。
本記事では、安全な構築手順(サーバー防衛 ➔ ルーター許可 ➔ Nginx設定 ➔ DNS公開) に沿って、具体的な設定手順を分かりやすく徹底解説します!
2. なぜ「二刀流(Dual Stack)」なのか?
まずは、全体像をパッと見て理解できるように整理しましょう。
従来の構成(IPv4のみ / VPS中継)
- [訪問者] ➔ [VPS(
118.27.203.45)] ➔(暗号化トンネル等 / ポート50080)➔ [ルーター・HGW(XG-100NE)ポートフォワード50080➔80または443] ➔ [自宅サーバー(153.156.79.69:80または:443)]
MAP-E環境でWebサイトを公開するために「ConoHa VPS等に一度通信を通して、自宅へ転送する(串を通す)」という構成をとっている場合、ポート制限は突破できますが全通信がVPSを経由するため、VPSの回線帯域がボトルネックになって自宅の10G回線が宝の持ち腐れになってしまいます。
二刀流の構成(IPv6直結 + VPS中継)
- [IPv6の訪問者] ➔(10G直結爆速アクセス!)➔ [自宅サーバー]
- [IPv4の訪問者] ➔ [VPS(
118.27.203.45)] ➔ [自宅サーバー]
┌─── [ IPv6 訪問者 ] ─── (10G直結) ─────────┐
│ ▼
[ サイト訪問者 ] ─┤ ┌──────────────┐
│ │ 自宅10G鯖 │
└─── [ IPv4 訪問者 ] ─── (VPS) ────► │ (Nginx / WP) │
└──────────────┘
┌─── [ IPv6 Visitors ] ─── (Direct 10G Connection) ───┐
│ ▼
[ Site Visitors ]─┤ ┌──────────────┐
│ │ Home Server │
└─── [ IPv4 Visitors ] ─── (VPS Relay) ─────►│ (Nginx / WP) │
└──────────────┘二刀流にする3つのメリット
- IPv6の訪問者には10G回線の爆速レスポンスがそのまま届く!
中継するVPSを挟まないため、遅延(レイテンシ)が限界まで削ぎ落とされ、10G回線の本領を発揮できます。 - VPSの転送量・負荷をごっそり減らせる!
いまやWEB通信の半分以上はIPv6です。そのアクセスを自宅10G回線へ逃がすことで、VPS側のCPUやネットワーク帯域の節約になります。 - IPv4しか使えない環境からのアクセスも100%カバー!
会社の回線や古いモバイル環境など、IPv6未対応の訪問者は今まで通りVPSが安全に中継してくれます。
STEP 1:【最優先】自宅Nginxのセキュリティ強化(防壁の構築)
⚠️ 注意:作業の順番が重要です!
DNSでIPv6アドレス(AAAAレコード)を公開する前に、まずは自宅サーバーのNginxにセキュリティアーマーを着せておきます。無防備な状態でインターネットに露出させるのを防ぐためです。
VPSという“防壁”を挟まず、自宅のNginxが素のインターネット(IPv6)から直接アクセスを受ける形になるため、最初に対策を2段階で整えます。
1. 全体設定(nginx.conf)のレート制限を調整する
1秒間の大量アクセス(DDoS/連投攻撃)を防ぐ「レートリミット」の数値を実用的な値に調整します。
ターミナルで全体設定ファイルを開きます。
sudo nano /etc/nginx/nginx.confhttp { ... } ブロック内にある # Limit Request 周辺の既存設定を探し、以下のように書き換えて保存します。
# Limit Request (既存の定義を調整)
limit_req_status 429; # 制限時は 403 ではなく 429 (Too Many Requests) を返す
# 既存の zone=one や zone=two のレートが厳しすぎる場合は数値を緩和するか、
# 独自の zone を1行追加します (例: 30r/s = 1秒間に30リクエストまで許容)
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=two:10m rate=30r/s;
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=30r/s;# Limit Request (Adjusted existing definitions)
limit_req_status 429; # Return 429 (Too Many Requests) instead of 403 on limit
# If the rate for existing zone=one or zone=two is too strict, relax the numbers
# or add a custom zone (e.g., 30r/s = allows up to 30 requests per second)
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=two:10m rate=30r/s;
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=30r/s;💡 設定のポイントと注意点
limit_req_status 429;
制限に達した際、通常の拒否(403 Forbidden)ではなく、正しく「429 Too Many Requests」を返すように変更します(既存でlimit_req_status 403;がある場合は429に書き換えます)。
【なぜ 403 ではなく 429 にするのか?】- 本来の仕様に合わせる(意味の明確化)
403は「アクセス権限・権限がない(永久的な拒否)」を意味しますが、429は「短時間の送信リクエスト数が多すぎる(一時的な速度制限)」を意味する正しいRFC規格のステータスコードです。 - SEO(検索エンジン)や外部連携への悪影響を防ぐ
Google クローラーや外部サービスが誤って制限に引っかかった際、403を返してしまうと「このページは削除された」と判断され、検索インデックスから削除される恐れがあります。429であれば「一時的な過負荷」と正しく伝わるため、時間を置いて再巡回してくれます。 - ブラウザやクローラーの挙動コントロール
429を返すと、ブラウザや自動リクエストを行うツール側も「一時的なアクセス頻度制限だな」と正しく認識でき、無駄なリトライを防げます。
- 本来の仕様に合わせる(意味の明確化)
- レート(
rate)は30r/s程度に余裕を持たせるrate=1r/sや5r/sなどの厳しい値に設定すると、WordPressの管理画面を開いた際やページ遷移時に、CSS/JavaScript/画像の一斉読み込みが制限に引っかかり、サイトのレイアウトや管理画面が全滅して壊れる原因になります。30r/s程度確保しておくのが安全です。
2. サイト個別設定で攻撃遮断・防衛ルールを組み込む
次に、サイト個別設定に通信プロトコル攻撃やユーザー偵察の遮断ルールを追加します。
sudo nano /etc/nginx/sites-available/test-site.onlineserver { ... }ブロック内に以下の防衛ルールを記述・調整します。
# --- 修正・追記部分 ---
# --- 統合アクセス制限:新陣形 ---
set_real_ip_from 118.27.203.45;
include /etc/nginx/conf.d/cloudflare.conf;
#real_ip_header CF-Connecting-IP;
real_ip_recursive on;
# 1. xmlrpc.php の完全遮断
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}
# 2. WPユーザー偵察対策(REST API /wp-json/wp/v2/users の保護)
location ~* ^/wp-json/wp/v2/users {
allow 192.168.1.0/24; # LAN内からのアクセス許可
allow 153.156.79.69; # 自宅IPv4
allow 2001:db8:1234:5600::/56; # 自宅IPv6プレフィックス
deny all; # 上記以外の外部アクセスはすべて拒否
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php83-fpm-main.sock;
}# --- Modified / Added Sections ---
# --- Integrated Access Control: New Strategy ---
set_real_ip_from 118.27.203.45;
include /etc/nginx/conf.d/cloudflare.conf;
#real_ip_header CF-Connecting-IP;
real_ip_recursive on;
# 1. Completely block xmlrpc.php
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
}
# 2. Prevent WP user enumeration (Protect REST API /wp-json/wp/v2/users)
location ~* ^/wp-json/wp/v2/users {
allow 192.168.1.0/24; # Allow access from LAN
allow 153.156.79.69; # Home IPv4
allow 2001:db8:1234:5600::/56; # Home IPv6 Prefix
deny all; # Deny all other traffic
include fastcgi_params;
fastcgi_pass unix:/var/run/php/php83-fpm-main.sock;
}3. 設定のテスト & リロード
編集が終わったら構文チェックを行い、Nginx に設定を読み込ませます。
sudo nginx -t
sudo systemctl reload nginxSTEP 2:ルーター(XG-100NE)&OS(UFW)のIPv6パケット通過許可設定
自宅サーバー(Nginx)のセキュリティ防衛を整えたら、途中のガードマン(ルーターとUbuntu)に「Webの通信(80/443番)は通してOK!」と許可を出します。
1. NTTホームゲートウェイ(XG-100NE)のIPv6パケットフィルタ設定
NTTの10G光クロス用ルーター(XG-100NEなど)をお使いの場合、ブラウザからルーター管理画面(http://192.168.1.1)にログインし、[ルータ設定] ➔ [IPv6パケットフィルタ設定(IPoE)] からエントリの [編集] を開きます。
HTTP(80番)とHTTPS(443番)の2つの通過ルールをそれぞれ作成します。
① HTTP(80番)用の設定(例:エントリ1)
- フィルタ種別:
許可(※初期値「拒否」から変更) - 通信方向:
IPoE→LAN(※初期値「LAN→IPoE」から変更) - プロトコル:
プロトコル名指定➔TCP - 送信元IPv6プレフィックス/長:
全て指定 - 宛先IPv6プレフィックス/長: ラジオボタンで下側を選択し、自宅サーバーのIPv6
2001:db8:1234:5600::69/128を入力 - 送信元ポート:
全て指定 - 宛先ポート:
ポート名選択➔www(※自動で80番扱いになります)
② HTTPS(443番)用の設定(例:エントリ2)
- フィルタ種別:
許可 - 通信方向:
IPoE→LAN - プロトコル:
プロトコル名指定➔TCP - 送信元IPv6プレフィックス/長:
全て指定 - 宛先IPv6プレフィックス/長: 自宅サーバーのIPv6
2001:db8:1234:5600::69/128 - 送信元ポート:
全て指定 - 宛先ポート: プルダウンに
httpsが無いため、ポート番号指定(1-65535)にチェックを入れ、直接443と入力!
⚠️ 【重要】ここではまだ「有効/無効」のチェックを入れないでください!
ルールの「編集」と「保存」まで終われば、ルーター側の受入れ準備(下準備)は完了です。
ただし、この段階で一覧画面の「有効」チェックボックスにチェックを入れて [設定] を押してしまうと、その瞬間に自宅サーバーの80/443ポートがインターネットへ全開になってしまいます。
事故や無用なスキャン攻撃を防ぐため、ルーターの有効化チェックは、次の「STEP 3:Nginxの設定」がすべて完了した最後の最後(STEP 4のDNS公開タイミング)で行います。
今はチェックを入れずにそのまま次のステップへ進みましょう!
2. Ubuntu(UFW)側の設定
Ubuntuサーバー(作業用ユーザー test-user 等でログイン)のファイアウォール(UFW)でも通信を許可します。
# test-user で実行
# Web通信(80番/443番)を許可(IPv4とIPv6の両方に一括で適用されます)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# 設定を再読み込みして状態を確認
sudo ufw reload
sudo ufw status# Execute as test-user
# Allow web traffic (Ports 80/443) - Applies to both IPv4 and IPv6 at once
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Reload configuration and check status
sudo ufw reload
sudo ufw statusSTEP 3:Nginx / WordOps 側の Dual Stack 設定
次に、自宅サーバーのNginx(WordOps)に「IPv4(VPS中継)とIPv6(直結)の両方からやってくるリクエストを同時に受け付ける(Dual Stack化)」設定を行います。
1. Nginxの listen ディレクティブを確認・追記する
NginxでIPv4とIPv6の両方をバインド(聞き取り)させるには、test-site.online の設定ファイルで listen の行を以下のように記述します。
server {
# IPv4の受け口(80 / 443 / 中継ポート50080)
listen 80;
listen 443 ssl;
http2 on;
# IPv6の受け口([::]:80 / [::]:443)★これが必須!
listen [::]:80;
listen [::]:443 ssl;
http2 on;
server_name test-site.online www.test-site.online;
...
}server {
# IPv4 entry ports (80 / 443 / relay port 50080)
listen 80;
listen 443 ssl;
http2 on;
# IPv6 entry ports ([::]:80 / [::]:443) ★REQUIRED!
listen [::]:80;
listen [::]:443 ssl;
http2 on;
server_name test-site.online www.test-site.online;
...
}💡 [::] とは?
IPv6における「すべてのIPアドレス(0.0.0.0のIPv6版)」を意味します。これを指定することで、外部から直接飛んでくるIPv6通信をNginxがしっかりキャッチできるようになります。
2. WordOps環境での設定反映
作業ユーザー test-user で設定漏れがないか確認し、設定ファイルをテストして再読み込みします。
# Nginxの構文チェック(OKが出れば成功)
sudo nginx -t
# Nginxの再読み込み
sudo wo stack reload --nginx
# (または sudo systemctl reload nginx)# Check Nginx syntax (Success if "ok" is returned)
sudo nginx -t
# Reload Nginx configuration
sudo wo stack reload --nginx
# (or sudo systemctl reload nginx)STEP 4:【仕上げ】DNS設定(お名前.comでAAAAレコードを追加)
自宅サーバー側の「受入れ体制」が100%完成したところで、最後にお名前.comのDNSレコードを設定し、世界中にIPv6直結ルートを開通させます。
1. 🛠️ 正しい「固定IPv6アドレス」の確認手順
サーバー(Ubuntu/Debian等)のターミナルで、以下のコマンドをそのまま実行してください。
ip -6 addr show scope global | grep -v "deprecated"2. 📋 出力結果の見方(どれをコピーすればいい?)
Dockerや仮想ブリッジを運用している環境では、コマンドを実行した際に大量の通信ポート(br- や veth 等)や内部用アドレスが表示されて混乱することがあります。
しかし、見るべきポイントは「物理LANカード(enp4s0 や eno1 等)」の scope global 1行だけです!
3: enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 state UP qlen 1000
inet6 2001:db8:1234:5600::69/64 scope global dynamic noprefixroute
↑ 【コレ!】これがインターネット公開用の本物のグローバルIPv6です!
inet6 fe80::8ac9:b3ff:febc:12e4/64 scope link noprefixroute
↑ ※「scope link」はLAN内限定アドレスのため無視してOK
5: br-3b7ef799ccd5: ...
7: veth616cf01@enp3s0: ...
↑ ※「br-」や「veth」はDocker等の内部仮想ポートのため無視してOK3: enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 state UP qlen 1000
inet6 2001:db8:1234:5600::69/64 scope global dynamic noprefixroute
↑ This is the real public IPv6 address for internet access!
inet6 fe80::8ac9:b3ff:febc:12e4/64 scope link noprefixroute
↑ Ignore "scope link" as it is a LAN-only address.
5: br-3b7ef799ccd5: ...
7: veth616cf01@enp3s0: ...
↑ Ignore "br-" and "veth" as they are internal virtual ports for Docker, etc.💡 見分けるための3大チェックリスト
scope globalと書かれているか?(scope linkは無視)- 物理LAN(
enp4s0やeno1等)の行か?(br-やvethは無視) temporaryという文字が入っていないか?(一時アドレスではない本物の固定IP)
上記の例の場合、末尾の /64 を除いた以下の文字列をお名前.comのAAAAレコード(VALUE欄)に登録します。
2001:db8:1234:5600::693. 💡 一時アドレス(temporary)を無効化するワンポイント
もし temporary(コロコロ変わる一時アドレス)が表示されてしまう場合は、以下のコマンドでカーネルパラメータ(sysctl)から一時アドレス機能を直接オフにしておくと安心です。
# sysctl で一時アドレス(Privacy Extensions)を無効化
# Disable IPv6 temporary addresses (Privacy Extensions) via sysctl
echo "net.ipv6.conf.all.use_tempaddr = 0" | sudo tee -a /etc/sysctl.d/99-disable-ipv6-privacy.conf
echo "net.ipv6.conf.default.use_tempaddr = 0" | sudo tee -a /etc/sysctl.d/99-disable-ipv6-privacy.conf
sudo sysctl -p /etc/sysctl.d/99-disable-ipv6-privacy.confこれを実行すると、迷う余地のない「本物の固定IPv6」1本に絞れるため、アドレス抽出が劇的にラクになります。
4. DNS設定画面(お名前.com / Cloudflare等)での入力例
test-site.online のDNSレコード設定画面で以下のように登録します。
| TYPE (種別) | ホスト名 | VALUE(設定値) | 役割(通信の流れ) |
|---|---|---|---|
| A | 空白 or www | 118.27.203.45(ConoHa VPS等のIPv4アドレス) | [既存]IPv4ユーザーをVPSへ飛ばす |
| AAAA | 空白 or www | 2001:db8:1234:5600::69(自宅10G鯖のグローバルIPv6) | [新規追加]IPv6ユーザーを自宅10Gへダイレクト接続 |
💡 ここが最終トリガー!
AAAAレコードを追加・保存したら、STEP 2 で保留にしていた XG-100NE(ルーター)のパケットフィルタ設定画面で「有効」にチェックを入れて保存 してください!
事前にNginxとセキュリティの準備を完璧に整えてあるため、いつボットやユーザーが飛んで来ても安全に10Gの超高速応答を返すことができます!
STEP 5:動作確認と疎通テスト(本当にIPv6直結できているか?)
DNSの浸透を待ちつつ、一般ユーザー sub-user や外部端末から実際に 「IPv6直結で10G回線に届いているか」 を検証しましょう。
1. ターミナル(PC等)から curl でIPv6強制アクセスしてみる
手元のIPv6対応PCやMacから、-6 オプション(IPv6指定)をつけてリクエストを飛ばします。
curl -6 -I https://test-site.online正常に HTTP/2 200 や HTTP/1.1 200 OK が返ってくれば、IPv6直結経由で自宅Nginxへの疎通が成功しています!
2. アクセスログ(access.log)で判定する
自宅サーバー側のNginxアクセスログ(/var/log/nginx/test-site.online.access.log)をリアルタイム表示させながらアクセスしてみます。
sudo tail -f /var/log/nginx/test-site.online.access.log- IPv6直結アクセスのログ:
2404:xxxx:xxxx...のように、訪問者(sub-user等)の生のIPv6アドレスがそのまま記録されていれば、VPSを経由せずダイレクトに届いています! - IPv4アクセスのログ:
118.27.203.45(ConoHa VPSのIPアドレス)またはプロキシヘッダーのIPv4アドレスが記録されます。
まとめ:10G回線×二刀流で無駄のない最強インフラへ
MAP-E(IPv4)のポート開放制限という壁を乗り越えるために導入したVPS中継ですが、そのままではせっかくの10G自宅回線のポテンシャルを殺してしまうのが大きな悩みでした。
「受け入れ態勢を整えてから最後にDNSを公開する」 という安全な順序を守って 「IPv6直結 + IPv4(VPS)中継」の二刀流(Dual Stack)構成 を導入したことで、
- IPv6ユーザーには、10G回線の爆速パフォーマンスをダイレクトに届ける
- IPv4ユーザーには、VPS(
118.27.203.45)経由で互換性と安全性をしっかり担保する
という、セキュリティ面も含めて一切のスキがない理想的な自宅サーバー公開スタックが完成しました!
通知先メール(test-user@test-site.online)等の運用体制も整えつつ、ぜひこの「二刀流構成」を仕込んで、自宅10Gサーバーの真価を100%引き出してみてください!



コメント