FastCGI: 30年経ってもなおリバースプロキシにとって優れたプロトコル
概要
- 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周年に寄せて、再評価のすすめ