概要
- HTTPリバースプロキシ は多くの脆弱性を抱える危険な領域
- FastCGI は30年前から存在する安全なプロキシ-バックエンド通信プロトコル
- HTTP/1.1 はパースの曖昧さや信頼できないヘッダー問題を抱える
- FastCGI は明確なメッセージフレーミングと信頼データ分離を提供
- 一部の制限はあるが、 FastCGI は今でも実用的な選択肢
HTTPリバースプロキシの危険性とFastCGIの再評価
- HTTPリバースプロキシ 経由の通信は、Discordのメディアプロキシ脆弱性のような desync攻撃 (リクエストスマグリング)リスク
- HTTP がプロキシ-バックエンド間通信に広く使われているが、本来その用途には不適切
- FastCGI は1996年に公開された プロキシ-バックエンド通信 専用のワイヤープロトコル
- FastCGI はプロセスモデルではなく、 通信プロトコル として利用可能
- .fcgi拡張子ファイル用のプロセス自動生成だけでなく、 長寿命デーモン とのTCP/UNIXソケット通信にも対応
Go言語とFastCGIの実装例
- Go では、標準ライブラリ net/http/fcgi をimportし、 http.Serve を fcgi.Serve に置き換えるだけ
- アプリの他の部分や ハンドラー はそのまま利用可能
- 主要プロキシ (Apache, Caddy, nginx, HAProxy)は FastCGIバックエンド をサポート
- 設定例:
- nginx:
- HTTP:
proxy_pass http://localhost:8080; - FastCGI:
fastcgi_pass localhost:8080; include fastcgi_params;
- HTTP:
- Apache:
- HTTP:
ProxyPass / http://localhost:8080/ - FastCGI:
ProxyPass / fcgi://localhost:8080/
- HTTP:
- Caddy:
- HTTP:
reverse_proxy localhost:8080 { transport http { } } - FastCGI:
reverse_proxy localhost:8080 { transport fastcgi { } }
- HTTP:
- HAProxy:
- HTTP:
backend app_backend server s1 localhost:8080 - FastCGI:
fcgi-app fcgi_app docroot /backend app_backend use-fcgi-app fcgi_app server s1 localhost:8080 proto fcgi
- HTTP:
- nginx:
- 設定例:
HTTPの問題点:desync攻撃・リクエストスマグリング
- HTTP/1.1 はテキストベースで一見シンプルだが、 パースの曖昧さ ・ エッジケース が多い
- メッセージフレーミング が明確でなく、実装ごとに 解釈の違い が発生
- これが desync攻撃 (リクエストスマグリング)の温床
- HTTP/2 は明確なフレーミングでこの問題を解決するが、 FastCGI は1996年から同様の仕組みを持つ
- nginxは初期からFastCGI対応、 HTTP/2バックエンド 対応は2025年後半から
- Apacheの HTTP/2バックエンド 対応は未だ「実験的」扱い
HTTPの問題点:信頼できないヘッダー
- プロキシ がクライアント情報(IPアドレス、認証ユーザー名、クライアント証明書情報など)を HTTPヘッダー で伝達
- ヘッダー名の重複や大文字小文字違い、他ヘッダー利用などで 攻撃者による偽装 リスク
- 例: X-Real-IP や True-Client-IP など、複数ヘッダーの扱いが複雑
- FastCGI は、クライアント由来のヘッダーとプロキシ追加情報の ドメイン分離 をプロトコルレベルで実現
- HTTPヘッダーは「 HTTP_」プレフィックス付きで渡され、 信頼データ と区別
- REMOTE_ADDR パラメータで 本来のクライアントIP を安全に伝達
- Goの net/http/fcgi はこのパラメータを自動で http.Request.RemoteAddr に反映
- fcgi.ProcessEnv で全ての信頼パラメータにアクセス可能
FastCGIの課題と現状
- FastCGI が広まらなかった理由は、 CGI の古臭いイメージや HTTPリバースプロキシの問題認識不足
- desync攻撃 は2005年にWatchfireが指摘したが、長年無視されてきた経緯
- FastCGI は現在も実用的で、 SSLMate では10年以上運用実績
- WebSocket非対応、 ツール不足 (curl未対応)、 最適化不足 によるスループット低下などの弱点
- それでも WebSocket 不要な場合や、 十分な性能 が得られる場合は FastCGI の採用価値
- HTTPリバースプロキシの悪夢 を回避できる点が最大の魅力
- FastCGI の30周年に寄せて、再評価のすすめ