nginx 設定 (R640) — stream SNI router + WordPress

// NGINX R640 — DMZ 公開フロント / 最終更新: 2026-05-14

稼働中 R640 は nginx stream SNI router + katuocloud.com WP 専用に転換 (2026-05-14)。 NC / Portal は maguro に移植済。

大改定 (2026-05-14)

従来は R640 が NC / Portal / Collabora 全部を抱える「全部入り」だったが、 役割分離のため:

  • R640 (DMZ Front): nginx stream SNI router + katuocloud.com WP のみ
  • maguro (Secure Storage): cloud.k2-o.net (NC) / 運営 Portal / WG 全部
  • hirame (Office): Collabora Docker (fabric 直結)
R640 nginx の役割 (新): ① TCP443 を SNI で振り分け、 ② katuocloud.com 自身は内部 8443 で終端、 ③ cloud.k2-o.net は maguro へ TCP passthrough。
経路図 (SNI router)
Internet (顧客) │ TCP 443 to 公開IP ▼ RTX1300 NAT 20000/11 → 192.168.20.21:443 (R640) │ ▼ R640 nginx stream (port 443) │ ssl_preread で SNI を判定 │ ├──→ SNI = “katuocloud.com” or “www.katuocloud.com” │ └→ 127.0.0.1:8443 (R640 inner WP block, LE cert で終端) │ └──→ SNI = “cloud.k2-o.net” └→ maguro:443 (TCP passthrough, maguro で TLS 終端) (fabric 経由 173.0.0.1 or VLAN20 192.168.20.20)
設定ファイル構成 (R640: /etc/nginx/)
ファイル役割
nginx.confmain + http + stream の include
conf.d/stream-sni-router.confstream module で SNI 振り分け
sites-enabled/katuocloud.cominner block (127.0.0.1:8443) で WP を終端
sites-enabled/defaultport 80 → 301 redirect to 443 (ACME challenge も処理)
stream SNI router 設定
# /etc/nginx/conf.d/stream-sni-router.conf

stream {
    map $ssl_preread_server_name $upstream {
        katuocloud.com            inner_katuocloud;
        www.katuocloud.com        inner_katuocloud;
        cloud.k2-o.net            maguro_nc;
        default                   inner_katuocloud;   # fallback
    }

    upstream inner_katuocloud {
        server 127.0.0.1:8443;
    }

    upstream maguro_nc {
        server 192.168.20.20:443;          # maguro VLAN20 DATA
        # 代替: 173.0.0.1:443 (fabric 直結) も検討
    }

    server {
        listen 443;
        proxy_pass $upstream;
        ssl_preread on;
        proxy_protocol off;                # passthrough なので OFF
    }
}
katuocloud.com WP (inner block)
# /etc/nginx/sites-enabled/katuocloud.com

server {
    listen 127.0.0.1:8443 ssl http2;
    server_name katuocloud.com www.katuocloud.com;

    ssl_certificate     /etc/letsencrypt/live/katuocloud.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/katuocloud.com/privkey.pem;

    client_max_body_size 64M;

    root /var/www/katuocloud_wp;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.1-fpm.sock;
        fastcgi_param HTTPS on;
        fastcgi_param HTTP_X_FORWARDED_PROTO https;   # 301 ループ防止
    }
}
HTTP_X_FORWARDED_PROTO 対応: stream SNI passthrough なので nginx-WP 間は内部 TCP。 WP 側が「自分は HTTP で受けてる」と誤判定して https に 301 リダイレクト → 無限ループする。 wp-config.php で $_SERVER['HTTPS']='on' 対応 + nginx で fastcgi_param HTTP_X_FORWARDED_PROTO https をセット。
port 80 + ACME challenge
# /etc/nginx/sites-enabled/default

server {
    listen 80 default_server;
    server_name _;

    # ACME challenge は素通し
    location /.well-known/acme-challenge/ {
        root /home/xs273132/wanchance.com/public_html;
    }

    # それ以外は HTTPS にリダイレクト
    location / {
        return 301 https://$host$request_uri;
    }
}
cloud.k2-o.net passthrough の意味

R640 nginx stream module は L4 (TCP) で生 proxy。 TLS 終端は maguro 側で行う。 これにより:

  • ✓ 証明書は maguro 側で管理 (snap certbot)
  • ✓ R640 が cloud.k2-o.net の cert を持つ必要なし
  • ✓ R640 侵入時も NC のキーは安全
  • ! source IP が R640 nginx 出口 (192.168.30.21 等) に置換される (要注意)
source IP 置換の挙動: stream proxy は L4 なので、 maguro nginx の $remote_addr は R640 nginx の出口 IF IP になる (例 192.168.30.21)。 内部 LAN ユーザーが外部 DNS で cloud.k2-o.net を引いても同じく 192.168.30.21 になる。 maguro 側で allow 192.168.30.21 を削除すると、 全 SNI 経由ユーザー (内部含む) が forbidden になる。
Let’s Encrypt 証明書 (R640 側)
ドメイン管理備考
katuocloud.com (+ www)apt certbotR640 inner block で終端
cloud.k2-o.net(R640 にも保持)passthrough のため使わないが、 万一の R640 自己終端用に保持
admin.wan-secure.net(R640 にも保持)同上
office.k2-o.net(R640 にも保持)同上
office.wan-secure.net(R640 にも保持)同上

cert-watch cron (06:30 daily) で全証明書を Telegram 監視 (<14日 警告 / 失効通知)。

セキュリティ Layer (R640 nginx)
// Layer 1: SNI 振り分け

未知の SNI (default) は inner_katuocloud にフォールバック。 katuocloud.com とその WP のみ公開、 他は届かない。

// Layer 2: WP 側
  • 未実装: /wp-admin の IP 制限 (作業時のみ開放) — 今後追加予定
  • WP コアアップデート + プラグイン自動更新
  • strong password + 2FA プラグイン
// Layer 3: Fail2ban

! 未実装。 nginx access.log と sshd の brute-force 検知設定は今後追加予定。

過去構成との差分
項目旧 (〜2026-05-13)新 (2026-05-14〜)
R640 nginx 役割NC / Portal / Collabora 全部終端SNI router + WP のみ
有効な sites-enabledcloud.k2-o.net, office.wan-secure.net, admin.wan-secure.net, nextcloud.vpn, portal.vpnkatuocloud.com, default のみ
cloud.k2-o.net 終端R640 (上 NC + IP制限 + WG)maguro へ TCP passthrough
WP(なし、 xserver VPS で稼働)R640 inner で稼働 (2026-05-14 移行)
stream module未使用使用 (ssl_preread)
運用コマンド
# 設定文法チェック
sudo nginx -t

# 設定リロード (無停止)
sudo systemctl reload nginx

# 再起動 (cert 更新後等)
sudo systemctl restart nginx

# stream の状態確認
sudo ss -tlnp | grep nginx

# アクセスログ確認
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log

# 証明書更新 (cron で自動)
sudo certbot renew --quiet --post-hook "systemctl reload nginx"
教訓・試行錯誤メモ
  • stream module は ngx_stream_ssl_preread_module が必要: Ubuntu 標準パッケージで OK。 nginx -V で --with-stream + --with-stream_ssl_preread_module を確認。
  • cloud.k2-o.net を fabric IP に向ける選択: upstream maguro_nc { server 173.0.0.1:443; } にすると VLAN20 を経由せず fabric 直結。 帯域 25G + ホップ少。 ただし fabric の MTU (9000) と LAN MTU (1500) の不整合に注意。
  • WP 301 ループ: X-Forwarded-Proto を見ない WP テーマ・プラグインがあり、 $_SERVER['HTTPS']='on' も併用必要だった。 wp-config.php に追記。
  • fastcgi vs proxy_pass: WP は php-fpm に fastcgi_pass で。 一般的な「nginx → Apache」じゃないので注意。 高速。
  • ACME challenge と SNI router の衝突: stream module は port 443 を占有するため、 ACME (TLS-ALPN-01) は使えない。 HTTP-01 (port 80) を使う必要がある。 default vhost で /.well-known/acme-challenge/ を素通し。
  • 2026-05-14 fresh install: R640 を Ubuntu 22.04 で完全再構築。 旧設定は /etc/nginx-r640-snapshot/ に退避。 復活には maguro 側 NC を止めて R640 NC を起こす必要あり (DB / NC データ整合性)。
今後の課題
  • ! /wp-admin の IP 制限 (作業時のみ開放)
  • ! Fail2ban 導入
  • ! nginx + ModSecurity (WAF) 検討
  • ! 他クライアント HP の WP マルチサイト化 (R640 SNI で複数 FQDN を捌く)
  • ! stream module の access.log を別ファイルに分離 (現在 stderr 出力のみ)
2026-05-14 達成: R640 が「DMZ 公開フロント」に集中。 katuocloud.com WP の新規ホスティング + cloud.k2-o.net SNI passthrough。 nginx 設定は最小限になり、 セキュリティと可読性が大幅向上。