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.conf | main + http + stream の include |
conf.d/stream-sni-router.conf | stream module で SNI 振り分け |
sites-enabled/katuocloud.com | inner block (127.0.0.1:8443) で WP を終端 |
sites-enabled/default | port 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 certbot | R640 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-enabled | cloud.k2-o.net, office.wan-secure.net, admin.wan-secure.net, nextcloud.vpn, portal.vpn | katuocloud.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 設定は最小限になり、 セキュリティと可読性が大幅向上。