MAP-Eでも諦めない!10G自宅サーバーをIPv6直結&IPv4-VPS中継で完全公開する方法【DNS/Nginx設定】

この記事は約31分で読めます。
この記事が役立ったらブックマーク! あとで読み返したり、環境構築時のリファレンスに活用できます
B! はてなブックマークに追加
  1. 1. はじめに
  2. 2. なぜ「二刀流(Dual Stack)」なのか?
    1. 従来の構成(IPv4のみ / VPS中継)
    2. 二刀流の構成(IPv6直結 + VPS中継)
    3. 二刀流にする3つのメリット
  3. STEP 1:【最優先】自宅Nginxのセキュリティ強化(防壁の構築)
    1. 1. 全体設定(nginx.conf)のレート制限を調整する
      1. 💡 設定のポイントと注意点
    2. 2. サイト個別設定で攻撃遮断・防衛ルールを組み込む
    3. 3. 設定のテスト & リロード
  4. STEP 2:ルーター(XG-100NE)&OS(UFW)のIPv6パケット通過許可設定
    1. 1. NTTホームゲートウェイ(XG-100NE)のIPv6パケットフィルタ設定
      1. ① HTTP(80番)用の設定(例:エントリ1)
      2. ② HTTPS(443番)用の設定(例:エントリ2)
    2. 2. Ubuntu(UFW)側の設定
  5. STEP 3:Nginx / WordOps 側の Dual Stack 設定
    1. 1. Nginxの listen ディレクティブを確認・追記する
    2. 2. WordOps環境での設定反映
  6. STEP 4:【仕上げ】DNS設定(お名前.comでAAAAレコードを追加)
    1. 1. 🛠️ 正しい「固定IPv6アドレス」の確認手順
    2. 2. 📋 出力結果の見方(どれをコピーすればいい?)
      1. 💡 見分けるための3大チェックリスト
    3. 3. 💡 一時アドレス(temporary)を無効化するワンポイント
    4. 4. DNS設定画面(お名前.com / Cloudflare等)での入力例
  7. STEP 5:動作確認と疎通テスト(本当にIPv6直結できているか?)
    1. 1. ターミナル(PC等)から curl でIPv6強制アクセスしてみる
    2. 2. アクセスログ(access.log)で判定する
  8. まとめ:10G回線×二刀流で無駄のない最強インフラへ

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)ポートフォワード5008080または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)] ➔ [自宅サーバー]
Plaintext
                ┌─── [ IPv6 訪問者 ] ─── (10G直結) ─────────┐
                │                                         ▼
[ サイト訪問者 ] ─┤                                   ┌──────────────┐
                │                                   │   自宅10G鯖   │
                └─── [ IPv4 訪問者 ] ─── (VPS) ────► │ (Nginx / WP) │
                                                    └──────────────┘
                                                    
                  ┌─── [ IPv6 Visitors ] ─── (Direct 10G Connection) ───┐
                  │                                                     ▼
[ Site Visitors ]─┤                                            ┌──────────────┐
                  │                                            │ Home Server  │
                  └─── [ IPv4 Visitors ] ─── (VPS Relay) ─────►│ (Nginx / WP) │
                                                               └──────────────┘

二刀流にする3つのメリット

  1. IPv6の訪問者には10G回線の爆速レスポンスがそのまま届く!
    中継するVPSを挟まないため、遅延(レイテンシ)が限界まで削ぎ落とされ、10G回線の本領を発揮できます。
  2. VPSの転送量・負荷をごっそり減らせる!
    いまやWEB通信の半分以上はIPv6です。そのアクセスを自宅10G回線へ逃がすことで、VPS側のCPUやネットワーク帯域の節約になります。
  3. IPv4しか使えない環境からのアクセスも100%カバー!
    会社の回線や古いモバイル環境など、IPv6未対応の訪問者は今まで通りVPSが安全に中継してくれます。

STEP 1:【最優先】自宅Nginxのセキュリティ強化(防壁の構築)

⚠️ 注意:作業の順番が重要です!
DNSでIPv6アドレス(AAAAレコード)を公開する前に、まずは自宅サーバーのNginxにセキュリティアーマーを着せておきます。無防備な状態でインターネットに露出させるのを防ぐためです。

VPSという“防壁”を挟まず、自宅のNginxが素のインターネット(IPv6)から直接アクセスを受ける形になるため、最初に対策を2段階で整えます。

1. 全体設定(nginx.conf)のレート制限を調整する

1秒間の大量アクセス(DDoS/連投攻撃)を防ぐ「レートリミット」の数値を実用的な値に調整します。

ターミナルで全体設定ファイルを開きます。

Bash
sudo nano /etc/nginx/nginx.conf

http { ... } ブロック内にある # Limit Request 周辺の既存設定を探し、以下のように書き換えて保存します。

Nginx
# 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;
Nginx
# 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/s5r/s などの厳しい値に設定すると、WordPressの管理画面を開いた際やページ遷移時に、CSS/JavaScript/画像の一斉読み込みが制限に引っかかり、サイトのレイアウトや管理画面が全滅して壊れる原因になります。30r/s 程度確保しておくのが安全です。

2. サイト個別設定で攻撃遮断・防衛ルールを組み込む

次に、サイト個別設定に通信プロトコル攻撃やユーザー偵察の遮断ルールを追加します。

Nginx
sudo nano /etc/nginx/sites-available/test-site.online

server { ... }ブロック内に以下の防衛ルールを記述・調整します。

Nginx
# --- 修正・追記部分 ---

# --- 統合アクセス制限:新陣形 ---
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;
}
Nginx
# --- 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 に設定を読み込ませます。

Bash
sudo nginx -t
sudo systemctl reload nginx

STEP 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プレフィックス/長: ラジオボタンで下側を選択し、自宅サーバーのIPv62001:db8:1234:5600::69 / 128 を入力
  • 送信元ポート: 全て指定
  • 宛先ポート: ポート名選択www(※自動で80番扱いになります)

② HTTPS(443番)用の設定(例:エントリ2)

  • フィルタ種別: 許可
  • 通信方向: IPoE→LAN
  • プロトコル: プロトコル名指定TCP
  • 送信元IPv6プレフィックス/長: 全て指定
  • 宛先IPv6プレフィックス/長: 自宅サーバーのIPv62001:db8:1234:5600::69 / 128
  • 送信元ポート: 全て指定
  • 宛先ポート: プルダウンに https が無いため、ポート番号指定(1-65535) にチェックを入れ、直接 443 と入力!

⚠️ 【重要】ここではまだ「有効/無効」のチェックを入れないでください!
ルールの「編集」と「保存」まで終われば、ルーター側の受入れ準備(下準備)は完了です。
ただし、この段階で一覧画面の「有効」チェックボックスにチェックを入れて [設定] を押してしまうと、その瞬間に自宅サーバーの80/443ポートがインターネットへ全開になってしまいます。
事故や無用なスキャン攻撃を防ぐため、ルーターの有効化チェックは、次の「STEP 3:Nginxの設定」がすべて完了した最後の最後(STEP 4のDNS公開タイミング)で行います。

今はチェックを入れずにそのまま次のステップへ進みましょう!

2. Ubuntu(UFW)側の設定

Ubuntuサーバー(作業用ユーザー test-user 等でログイン)のファイアウォール(UFW)でも通信を許可します。

Bash
# test-user で実行
# Web通信(80番/443番)を許可(IPv4とIPv6の両方に一括で適用されます)
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# 設定を再読み込みして状態を確認
sudo ufw reload
sudo ufw status
Bash
# 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 status

STEP 3:Nginx / WordOps 側の Dual Stack 設定

次に、自宅サーバーのNginx(WordOps)に「IPv4(VPS中継)とIPv6(直結)の両方からやってくるリクエストを同時に受け付ける(Dual Stack化)」設定を行います。

1. Nginxの listen ディレクティブを確認・追記する

NginxでIPv4とIPv6の両方をバインド(聞き取り)させるには、test-site.online の設定ファイルで listen の行を以下のように記述します。

Nginx
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;
    ...
}
Nginx
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 で設定漏れがないか確認し、設定ファイルをテストして再読み込みします。

Bash
# Nginxの構文チェック(OKが出れば成功)
sudo nginx -t

# Nginxの再読み込み
sudo wo stack reload --nginx
# (または sudo systemctl reload nginx)
Bash
# 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等)のターミナルで、以下のコマンドをそのまま実行してください。

Bash
ip -6 addr show scope global | grep -v "deprecated"

2. 📋 出力結果の見方(どれをコピーすればいい?)

Dockerや仮想ブリッジを運用している環境では、コマンドを実行した際に大量の通信ポート(br-veth 等)や内部用アドレスが表示されて混乱することがあります。
しかし、見るべきポイントは「物理LANカード(enp4s0eno1 等)」の scope global 1行だけです!

Plaintext
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等の内部仮想ポートのため無視してOK
Plaintext
3: 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大チェックリスト

  1. scope global と書かれているか?(scope link は無視)
  2. 物理LANenp4s0eno1 等)の行か?(br-veth は無視)
  3. temporary という文字が入っていないか?(一時アドレスではない本物の固定IP)

上記の例の場合、末尾の /64 を除いた以下の文字列をお名前.comのAAAAレコード(VALUE欄)に登録します。

Plaintext
2001:db8:1234:5600::69

3. 💡 一時アドレス(temporary)を無効化するワンポイント

もし temporary(コロコロ変わる一時アドレス)が表示されてしまう場合は、以下のコマンドでカーネルパラメータ(sysctl)から一時アドレス機能を直接オフにしておくと安心です。

Bash
# 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 www118.27.203.45
(ConoHa VPS等のIPv4アドレス)
[既存]IPv4ユーザーをVPSへ飛ばす
AAAA空白 or www2001: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指定)をつけてリクエストを飛ばします。

Bash
curl -6 -I https://test-site.online

正常に HTTP/2 200HTTP/1.1 200 OK が返ってくれば、IPv6直結経由で自宅Nginxへの疎通が成功しています!

2. アクセスログ(access.log)で判定する

自宅サーバー側のNginxアクセスログ(/var/log/nginx/test-site.online.access.log)をリアルタイム表示させながらアクセスしてみます。

Bash
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%引き出してみてください!

コメント

タイトルとURLをコピーしました