あなたのサーバー、世界中から「ドアノブ」を回されています。
こんにちは!「LINUX工房」管理人の「リナックス先生」です。
前回は、SSL/TLSとHTTP/3を導入し、通信経路の安全と速度を手に入れました。
これでWebサイトとしては一人前です。
しかし、サーバーをインターネットに公開した瞬間から、目に見えない戦いが始まっていることをご存知でしょうか?
アクセスログを見てみてください。「wp-login.php」への執拗なログイン試行、身に覚えのない「.env」ファイルへのアクセス、そして謎の国からの大量のリクエスト…。
彼らはあなたのサーバーのセキュリティホールを24時間365日探し続けています。
先生、ログを見たら怖くなってきました…。
公開したばかりの無名なサイトなのに、1秒間に何回もアクセスしてくる変なIPがいるんです。
これってDDoS攻撃ですか? サーバーが重くなったらどうしよう。
あと、開発中の管理画面を他人に見られたくないんですけど、どうすればいいですか?
慌てないで。
Nginxには、そういった「招かれざる客」を追い返すための強力な機能が標準で備わっているわ。
特定のIPだけを通す「アクセス制限」、合言葉を知っている人だけ入れる「Basic認証」、そして攻撃的な連打を防ぐ「レートリミット」。
これらを組み合わせれば、高価なセキュリティ製品を買わなくても、かなり強固な要塞が作れるのよ。
本記事では、Nginxのアクセス制御モジュールを使ったIP制限、htpasswd を使ったBasic認証、そしてDDoS対策として不可欠な limit_req (Rate Limiting) の設定手法を、実践的なシナリオに基づいて解説します。
🚀 Nginx基本講座(全8回)カリキュラム
現在地:【第6回】鉄壁の守り。アクセス制限、Basic認証、Rate LimitingによるDDoS対策
- 【第1回】Webサーバーの覇者。Nginxのアーキテクチャ解説と最新インストール完全ガイド
- 【第2回】設定ファイルの解剖学。nginx.confの構造とバーチャルホストの基本
- 【第3回】静的コンテンツ配信の極意。root/aliasの使い分けとインデックス設定
- 【第4回】リバースプロキシの構築。APサーバーへの転送とロードバランシング
- 【第5回】HTTPS化とHTTP/3(QUIC)。Let’s EncryptでのSSL証明書自動更新
- 【第6回】鉄壁の守り。アクセス制限、Basic認証、Rate LimitingによるDDoS対策
- 【第7回】爆速化チューニング。Gzip圧縮、ブラウザキャッシュ、バッファサイズ最適化
- 【第8回】ログ解析と運用監視。アクセスログのカスタム設定とDockerでの運用
第1章:基本にして最強。「IPアドレス制限」
「管理画面(/admin)は社内からしかアクセスさせたくない」「特定の悪質なIPをブロックしたい」。
そんな時に使うのが allow と deny ディレクティブです。
基本構文
location ブロック、または server ブロックの中に記述します。
ルールは「上から順に評価され、最初にマッチしたものが適用される」という点です。
例:ホワイトリスト方式(許可したもの以外すべて拒否)
location /admin/ {
# 社内IP(例: 192.168.1.0/24)を許可
allow 192.168.1.0/24;
# 自分の自宅IP(例: 203.0.113.5)を許可
allow 203.0.113.5;
# それ以外はすべて拒否(403 Forbidden)
deny all;
}
これが最も安全な運用方法です。
必ず最後に deny all; を書くのを忘れないでください。
例:ブラックリスト方式(特定IPのみ拒否)
location / {
# 攻撃者のIPを拒否
deny 1.2.3.4;
deny 5.6.7.8;
# それ以外は許可(デフォルトは許可なので allow all は省略可)
}
💡 プロのノウハウ:geoモジュールでスマートに管理
IPリストが長くなると、設定ファイルが汚れます。
プロは geo モジュールを使って、IPリストを変数化して管理します。
nginx.conf (httpブロック内):
geo $allowed_country {
default 0;
192.168.1.0/24 1; # 社内
203.0.113.5 1; # 自宅
}
serverブロック内:
location /admin/ {
if ($allowed_country = 0) {
return 403;
}
...
}
これなら、許可リストを別ファイル(include ip_list.conf;)に切り出して管理しやすくなります。
第2章:手軽な認証システム「Basic認証」
「IPアドレスが固定できない(スマホなど)けど、関係者以外には見せたくない」。
そんな時は、ブラウザ標準の機能であるBasic認証が便利です。
IDとパスワードを知っている人だけを通します。
ステップ1:パスワードファイルの作成
Apacheに付属する htpasswd コマンドを使うのが一般的ですが、Nginxユーザーなら httpd-tools パッケージを入れて使います。
# ツールのインストール sudo dnf install httpd-tools # ユーザー作成(初回は -c オプションでファイル作成) sudo htpasswd -c /etc/nginx/.htpasswd user1 # パスワード入力を求められます # 2人目以降を追加する場合(-c は付けない!) sudo htpasswd /etc/nginx/.htpasswd user2
ステップ2:Nginxの設定
認証をかけたい location ブロックに記述します。
location /dev/ {
# 認証ダイアログに表示されるメッセージ
auth_basic "Restricted Area";
# パスワードファイルのパス
auth_basic_user_file /etc/nginx/.htpasswd;
}
注意点:HTTPSが必須
Basic認証は、IDとパスワードを「Base64エンコード(暗号化ではない)」して送信します。
つまり、通信を盗聴されると簡単にパスワードがバレてしまいます。
必ず第5回で設定したHTTPS(SSL)環境下で使用してください。
第3章:DDoS攻撃を防ぐ「Rate Limiting(レート制限)」
「F5アタック」や、スクレイピングボットによる大量アクセス。
これらはサーバーのリソース(CPU・メモリ)を食いつぶし、一般ユーザーへのサービス提供を妨害します。
Nginxの limit_req モジュールを使えば、「1秒間に〇回まで」という制限をかけることができます。
ステップ1:ゾーンの定義(httpブロック)
まず、「何を基準に」「どれくらいの頻度で」制限するかを定義します。
通常は nginx.conf の http ブロックに書きます。
http {
# ...
# $binary_remote_addr (IPアドレス) ごとに制限
# zone=one:10m (メモリ領域名を"one"とし、10MB確保)
# rate=1r/s (1秒間に1リクエストまで許可)
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
}
1r/s はかなり厳しい制限です(人間でも連打すると引っかかります)。
APIサーバーなら 10r/s、静的サイトなら 30r/s くらいが目安ですが、用途によります。
ステップ2:制限の適用(server / locationブロック)
定義したゾーンを実際に適用します。
server {
location /login.php {
# ゾーン"one"を使用
# burst=5 (規定を超えても5回分までは行列として待ってあげる)
# nodelay (待たずに即処理するが、総数はburst内に収める)
limit_req zone=one burst=5 nodelay;
}
}
BurstとNodelayの仕組み
ここが初心者が一番混乱するポイントです。
- rate=1r/s のみ: 1秒に1回を超えた瞬間、エラー(503)を返す。非常に厳しい。
- burst=5: 瞬間的に5回アクセスが来ても、エラーにせず「順番待ち(遅延)」させて処理する。
(例:1秒に5回きたら、5秒かけてゆっくり処理してあげる) - nodelay:
burstの枠内なら、遅延させずに即座に処理する。
ただし、その後数秒間は新たなリクエストを受け付けない(借金を返すイメージ)。
結論: ユーザー体験を損なわないためには、burst と nodelay をセットで使うのが現代の定石です。
⚠️ トラブルシューティング:誤検知(False Positive)
NAT(会社のゲートウェイなど)を経由して複数のユーザーが同じIPでアクセスしてくる場合、IPごとの制限だとすぐに引っかかってしまいます。
その場合、制限を緩めるか、CookieやAPIキーを使ったより高度な制限(limit_req_zone $cookie_session_id ...)への切り替えが必要です。
第4章:同時接続数の制限(Limit Conn)
「Rate Limit(頻度)」とは別に、「Connection Limit(同時接続数)」も重要です。
例えば、大容量ファイルをダウンロードするツールで、1人で100セッションも張られたら、帯域が埋まってしまいます。
設定方法
limit_req と似ています。
http {
# ゾーン定義
limit_conn_zone $binary_remote_addr zone=addr:10m;
}
server {
location /downloads/ {
# 1つのIPにつき、同時接続は5本まで
limit_conn addr 5;
}
}
これを超えた接続は 503 Service Temporarily Unavailable になります。
動画配信サイトやファイルアップローダーなどで特に有効です。
第5章:悪質なボットを弾く(WAF的アプローチ)
特定のUser-Agent(ブラウザ情報)を持つスクレイピングツールや、脆弱性を探すスキャナをブロックします。
mapモジュールを使ったブロック
nginx.conf の http ブロックに記述します。
http {
map $http_user_agent $bad_bot {
default 0;
"~*malicious_bot" 1;
"~*scanner" 1;
"~*wget" 1; # wgetコマンドを拒否したい場合
}
}
server ブロックで適用します。
server {
if ($bad_bot) {
return 403;
}
}
隠しファイルへのアクセス拒否
.git や .env などの隠しファイルには、重要な情報が入っていることがあります。
これらへのアクセスをまとめて拒否する設定は必須です。
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
※ただし、.well-known(Let’s Encryptで使用)は許可する必要があるため、実際はもう少し調整が必要です。
第6章:攻撃検知とFail2Ban連携
Nginx単体では「攻撃してきたIPを永続的にBANする」ことはできません。
そこで、ログ監視ツール「Fail2Ban」と連携させます。
仕組み
- Nginxが「パスワード間違い」や「存在しないファイルへのアクセス」を
error.logに記録。 - Fail2Banがログを監視し、規定回数(例:5回)失敗したIPを見つける。
- Fail2BanがLinuxのファイアウォール(Firewalld/iptables)を操作し、そのIPをBANする。
導入手順(概要)
# インストール sudo dnf install fail2ban # 設定(jail.localを作成) [nginx-http-auth] enabled = true port = http,https logpath = /var/log/nginx/error.log maxretry = 3 bantime = 1h
これで、Basic認証を突破しようとするブルートフォース攻撃を自動で遮断できます。
まとめ:多層防御でサーバーを守る
お疲れ様でした!
今回は、Nginxが持つセキュリティ機能をフル活用する方法を解説しました。
今回の重要ポイント:
- 管理画面にはIP制限またはBasic認証をかける。
- DDoS対策には
limit_req(burst+nodelay) が有効。 - ダウンロードエリアには
limit_connで帯域占有を防ぐ。 - WAF的なブロックやFail2Ban連携で、攻撃者を自動排除する。
セキュリティに「これで完璧」はありません。
しかし、これらの設定を入れておくだけで、無差別に行われる攻撃の99%は防ぐことができます。
攻撃ログを見て「おっ、ちゃんと防いでるな」とニヤリとできるようになれば、あなたも立派なサーバー管理者です。
さて、セキュリティの次は「パフォーマンス」です。
せっかく安全になっても、サイトの表示が遅くてはユーザーが逃げてしまいます。
「Gzip圧縮? ブラウザキャッシュ? なにそれ美味しいの?」
次回、第7回は「爆速化チューニング。Gzip圧縮、ブラウザキャッシュ、バッファサイズ最適化」です。
設定ファイルを数行書き換えるだけで、サイトの表示速度を劇的に向上させる魔法のテクニックを伝授します。
Google PageSpeed Insightsのスコアアップ間違いなしです。お楽しみに!
▼ Nginxの実践環境を手に入れる ▼
安全なサーバーを構築するなら
「VPS」で自分専用環境
セキュリティ知識を仕事に
「ITエンジニア転職」

コメント