ロードバランサーを導入すれば「負荷分散と冗長化はできた」と安心していませんか?ロードバランサーはネットワークの入口に立つため、設定を誤ると大量のリクエストによるサービス停止(DDoS)・HTTPリクエストスマグリング・不適切なSSL設定による通信傍受など、深刻なリスクの温床になります。
特に中小企業のWebサービスやAPIサーバーは、攻撃者から見ると「ロードバランサー直下に直接アクセスできる」ことも多く、攻撃の最初の標的になりやすい場所です。
この記事では、ロードバランサーが持つセキュリティリスクと、HAProxy・Nginxでのレート制限・DDoS緩和・SSL終端の安全な設定手順を、現場で使えるレベルで解説します。

ロードバランサーが持つセキュリティリスクとは
ロードバランサー(LB)はWebサーバー・アプリケーションサーバーの前段に置き、複数のバックエンドサーバーへトラフィックを振り分ける機器・ソフトウェアです。HAProxy・Nginx・AWS ALB・F5 BIG-IPなどが代表例です。
セキュリティ上のリスクは主に次の4点です。
・大量リクエストによるサービス停止(DDoS・HTTPフラッド): レート制限がないと、攻撃者が大量のHTTPリクエストを送りつけてバックエンドサーバーを枯渇させる。
・HTTPリクエストスマグリング: LBとバックエンドの間でHTTPヘッダーの解釈が食い違う隙を突き、バックエンドに悪意のあるリクエストを紛れ込ませる攻撃。
・SSL設定の不備: SSL終端をLBで行う場合、古いTLSバージョン(TLS 1.0/1.1)の許可や弱い暗号スイートが残ると、通信が傍受されるリスクがある。
・バックエンドの直接露出: LBを通さず、バックエンドサーバーが外部から直接アクセス可能な状態になっていると、LBのセキュリティ設定が意味をなさなくなる。
「ロードバランサーはセキュリティ機器ではない」という認識が甘さを生みます。LBは攻撃者から見ると「最初に触れる可能性が高い場所」であり、そこでの設定がシステム全体の安全性を大きく左右します。
DDoS・HTTPフラッドへの防御(レート制限)
ロードバランサーレベルで最初に実装すべきセキュリティ対策がレート制限です。ソースIPアドレスごとに単位時間あたりのリクエスト数を制限し、異常な多量リクエストを遮断します。
SYNフラッド攻撃のようなTCPレベルの攻撃はネットワーク機器やiptablesで対処しますが、HTTPレベルのフラッドはLBでの制御が最も効果的です。
1. HAProxyによるレート制限設定
HAProxyはスティックテーブル(stick-table)機能を使ってIPごとのリクエストレートを追跡し、超過したIPを遮断できます。
# /etc/haproxy/haproxy.cfg の設定例(想定例) frontend http_frontend bind *:80 bind *:443 ssl crt /etc/ssl/private/fullchain.pem # スティックテーブルを使ったIPごとのレート制限 stick-table type ip size 1m expire 30s store http_req_rate(10s),conn_cur http-request track-sc0 src # 10秒間に100リクエストを超えたIPをブロック http-request deny deny_status 429 if { sc_http_req_rate(0) gt 100 } # 同時接続数が50を超えたIPをブロック http-request deny deny_status 429 if { sc_conn_cur(0) gt 50 } default_backend web_servers backend web_servers balance roundrobin # バックエンドへの直接アクセスを防ぐため内部IPのみ許可 server web1 10.0.1.10:8080 check server web2 10.0.1.11:8080 check
2. Nginxによるレート制限設定
Nginxではlimit_req_zoneディレクティブでIPごとのリクエストレートを管理します。
# /etc/nginx/nginx.conf の http ブロックに追記(想定例) http { # IPごとに10秒間10リクエストまで(1r/s) limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s; # IPごとの同時接続数制限 limit_conn_zone $binary_remote_addr zone=conn_limit:10m; server { listen 443 ssl; location / { # バースト20まで許容、超過は503 limit_req zone=req_limit burst=20 nodelay; limit_conn conn_limit 20; proxy_pass http://backend_servers; } } }
SSL終端の安全な設定
ロードバランサーでSSL/TLSを終端させる(HTTPS→HTTP変換してバックエンドに流す)構成は一般的ですが、TLSバージョンと暗号スイートの設定が不適切だと通信傍受のリスクがあります。
安全なSSL終端の原則は、TLS 1.3への移行と弱い暗号スイートの無効化です。
1. HAProxyのSSL設定
# HAProxyのSSL設定(haproxy.cfg) frontend https_frontend bind *:443 ssl crt /etc/ssl/private/fullchain.pem ssl-min-ver TLSv1.2 ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384 # HSTSヘッダーを追加(1年間) http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains" # HTTPからHTTPSへリダイレクト http-request redirect scheme https unless { ssl_fc }
2. LBとバックエンド間の通信も暗号化する
SSL終端をLBで行う場合、LBとバックエンド間は内部ネットワーク通信になります。内部ネットワークが完全に信頼できる環境でない限り(ゼロトラスト設計では特に)、LBからバックエンドへの通信もHTTPSにするか、mTLSで相互認証することが推奨されます。
# バックエンドへもSSLで接続する設定(HAProxy) backend web_servers_ssl balance roundrobin option ssl-hello-chk server web1 10.0.1.10:443 ssl verify required ca-file /etc/ssl/certs/internal-ca.pem check server web2 10.0.1.11:443 ssl verify required ca-file /etc/ssl/certs/internal-ca.pem check
HTTPリクエストスマグリング対策
HTTPリクエストスマグリング(HTTP Request Smuggling)は、LBとバックエンド間のHTTPヘッダー解釈の差異を悪用してバックエンドに不正なリクエストを紛れ込ませる攻撃です。
主な対策は次の3つです。
・HTTP/1.1のみを使う場合: Transfer-EncodingとContent-Lengthが同時に存在するリクエストを拒否する設定を入れる
・LBとバックエンド間でHTTP/2を使う: HTTP/2は1リクエスト1レスポンスが明確で、スマグリングが構造上困難になる
・LBとバックエンドのHTTPバージョンを統一する: バージョン混在が解釈差を生む根本原因なため、可能な限り同じHTTPバージョンで通信する
# HAProxy: Transfer-EncodingとContent-Lengthの同時指定を拒否 frontend http_frontend # 両方存在するリクエストはスマグリングの疑いがあるため拒否 http-request deny if { req.hdr_cnt(content-length) gt 1 } http-request deny if { req.hdr_cnt(transfer-encoding) gt 1 }
バックエンドサーバーの直接露出を防ぐ
LBのセキュリティ設定をどれだけ丁寧に行っても、バックエンドサーバーがインターネットから直接アクセス可能な状態だとLBを迂回した攻撃が成立します。
・バックエンドサーバーのポートをLBのIPのみに制限する: iptablesやクラウドのセキュリティグループで、バックエンドの8080ポート等はLBのIPからのみ受け付ける
・パブリックIPを持たせない: バックエンドサーバーをプライベートサブネットに置き、インターネットから直接到達できない構成にする
・ヘルスチェックを悪用させない: LBからバックエンドへのヘルスチェックパスを外部に露出しない
ファイアウォールルールの設計については、ファイアウォールポリシー管理ガイドも参考にしてください。
中小企業でも今日からできること
「ロードバランサーの細かい設定をする余裕がない」という方向けに、優先度別に整理します。
・今すぐできること(設定変更のみ): 使用中のLB(Nginx、HAProxy、AWS ALB等)でTLS 1.0・1.1が有効になっていれば無効化する。弱い暗号スイートを無効化する。証明書の自動更新が設定されているか確認する。
・短期で対応(1週間以内): レート制限の設定を入れる。バックエンドサーバーへの直接アクセスをファイアウォールで遮断する。
・中期で対応(1か月以内): LBのアクセスログをsyslogサーバーに転送して集中管理する。Nginxのセキュリティヘッダー(CSP、X-Frame-Options等)を設定する。
クラウドサービスを使っている場合、AWS ALBにはAWS WAFを組み合わせることで、マネージドルールセットによる即日のLB前段防護が可能です。
よくある誤解と注意点
【注意1】LBを入れれば「DDoSを防げる」という誤解
LBは本来負荷分散が目的であり、DDoS緩和は付加的な機能です。大規模なDDoS攻撃に対してはLBだけでは不十分で、上位のISPレベルでの対策やCDN(Cloudflare等)との組み合わせが必要になります。
【注意2】SSL終端で「安全になった」という誤解
SSL終端をLBで行うと、LBからバックエンド間の通信はHTTP(平文)になることが多いです。内部ネットワークであっても、内部不正や横移動(ラテラルムーブメント)への対策として、この区間も暗号化することが理想的です。
【注意3】ヘルスチェックのパスを推測可能にしていい
一般的に使われる `/health`、`/ping`、`/status` 等のヘルスチェックURLをそのまま使うと、攻撃者がバックエンド構成を推測しやすくなります。独自のパスを使うか、LBのIPのみに制限することを検討してください。
【注意4】LBのログを誰も見ていない
LBのアクセスログには攻撃の痕跡が残ります。ログが有効化されているか、保存・監視体制が整っているかを確認しましょう。
ロードバランサーのセキュリティ対策まとめ
| 対策項目 | HAProxy設定 | Nginx設定 | 優先度 |
|---|---|---|---|
| レート制限 | stick-table + http-request deny | limit_req_zone + limit_req | 高(即対応) |
| TLS 1.0/1.1無効化 | ssl-min-ver TLSv1.2 | ssl_protocols TLSv1.2 TLSv1.3 | 高(即対応) |
| HSTSヘッダー | http-response set-header | add_header Strict-Transport-Security | 高(即対応) |
| リクエストスマグリング対策 | http-request deny(ヘッダー重複拒否) | HTTP/2バックエンド利用 | 中(1週間以内) |
| バックエンド直接アクセス遮断 | iptables / SG設定 | iptables / SG設定 | 高(即対応) |
| LB→バックエンド間SSL化 | backend ssl verify required | proxy_ssl_verify on | 中(余裕があれば) |

本記事のまとめ
ロードバランサーは「入口に立つ機器」だからこそ、適切なセキュリティ設定が全体の防御力を左右します。
・HTTPフラッドへの対策にはIPごとのレート制限が最初の一手
・SSL終端設定ではTLS 1.2以上・強い暗号スイートを必ず確認する
・バックエンドがLBを迂回してインターネットから直接見えていないかを必ず確認する
・LBのアクセスログを保存・監視する体制を整える
ロードバランサーのセキュリティを固めた後は、Nginxのセキュリティ設定やTLS 1.3移行ガイドもあわせて参照することで、Webサーバー全体の防御レベルをさらに高められます。
PR
体系的に学ぶ 安全なWebアプリケーションの作り方 第2版(徳丸浩/SBクリエイティブ)
Webアプリケーションセキュリティの定番書。HTTPの仕組み・SQLインジェクション・XSS・セッション管理の脆弱性から実装レベルの対策まで体系的に解説しており、ロードバランサー設計に必要なHTTP理解を深める一冊です。
