
悪意のあるボットがサーバーにアクセスするのを自動的に阻止する
TUI、Web コンソール、CLI を提供し、CDN の背後に隠れることなく、悪質なボットを遮断するようにサーバーを設定できるツールです。
NGINX と既存のファイアウォール(nftables または iptables)と連携して動作します:

このアプリはサーバーから締め出されないように最善を尽くしますが、使用は自己責任でお願いします。また、AGPL ライセンスの下で提供されているため、商用利用する場合はライセンスを遵守してください。
Debian または Ubuntu では、APT リポジトリから:
curl -fsSL https://ivankovic.github.io/stop-bots/key.gpg \
| sudo tee /usr/share/keyrings/stop-bots.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/stop-bots.gpg] \
https://ivankovic.github.io/stop-bots stable main" \
| sudo tee /etc/apt/sources.list.d/stop-bots.list
sudo apt update && sudo apt install stop-bots
パッケージには man stop-bots(および man stop-bots-batch など動詞ごとのページ)と
bash、zsh、fish の補完が含まれています。サービスはインストールされず、何も起動しません。
または crates.io から、Rust 1.88 以降で:
cargo install stop-bots
またはGitHubのreleasesからx86_64またはaarch64 Linux用の静的バイナリをダウンロードしてください。
installはDebianまたはその派生でないホストを拒否します。nft、またはiptables-restoreとip6tables-restore、その他にはnginx。コンテナ内のNGINXも動作します — Running NGINX in a containerを参照してください。sudo stop-botsでTUIが起動します。root権限が必要です。/etc/nginxを書き換え、ファイアウォールルールをロードするためです。uで全てのリストをダウンロードします: ボットリスト、クローラーIP範囲、そして有効にしたフィードや国。1) にはホスト全体のポリシーがあります: どのボットカテゴリをブロックするか、国、そしてログを読み取る検出器。NGINX画面 (4) では、rでサイトを見つけます。Blocks画面 (5) には、検出器またはあなたが追加した全てのルールとその理由が一覧表示されます。aで全てを適用します。まず何が変更されるか — ファイル、追加・削除されるルール、ロックアウトチェックの判定 (dで差分) — を表示し、確認を求めます。sudo stop-bots install firewallで、適用されたルールが再起動後も保持されます。これがないと、再起動後はルールが全くない状態に戻ります。sudo stop-bots statusでカーネル、ユニット、ファイルをチェックし、何が欠けているかを報告します。sudo stop-bots status
sudo stop-bots batch --dry-run --diff
sudo stop-bots batch --apply
sudo stop-bots install firewall
sudo stop-bots status
batch --dry-run はダウンロードもスキャンも行いません。新規インストールでは、バイナリに組み込まれたボットリストから NGINX ブロックが表示され、ログから何も読み取られていないため、ファイアウォールルールはまだありません。--apply を付けずに sudo stop-bots batch を実行すると、ダウンロードとスキャンが行われ、適用せずにレビュー用のファイルが書き込まれます。batch の動作については Unattended, from cron を参照してください。
sudo stop-bots uninstall all --dry-run
sudo stop-bots uninstall all
最初のものはすべてのステップを列挙し、2番目のものがそれらを実行します。アップグレードとアンインストールを参照してください。
既知のボット、カテゴリ別(スキャナー / 検索エンジン / AI クローラー)。ソースは
ArcJet's Well-Known Bots、
ai.robots.txt、および
NGINX Ultimate Bad Bot Blocker
リスト。カテゴリをブロックすると、各サイトの NGINX 設定に if ($http_user_agent ...) ルールが注入されます。
リクエストが多すぎる場合、NGINX 自身のレート制限による。
まず礼儀正しく — ブロックしているすべてのボットを列挙した生成済みの robots.txt。これを尊重するクローラー向けであり、以下に示すハニーポットパスも含みます。
あなたが別段の指示をしない限り — サイトごとのパス除外、および信頼されたアドレスとユーザーエージェント(trust)。これらにはブロック、リスト、レート制限のいずれも適用されません。
ブラウザらしく見えないリクエスト、サイトごと。6つの独立したルールがあり、それぞれに独自のトグルがあり、デフォルトではすべてオフです — ルールごとに1つのスイッチなので、あなたの何かが動作しなくなった場合、どのルールが原因か特定できます:
| ルール | ボット以外に拒否するもの |
|---|---|
| HTTP/1.0 および HTTP/1.1 | HTTP/2 を話さないクローラーと API クライアント |
Accept ヘッダーなし | 一部の API クライアントは送信しない |
Accept-Language なし | プライバシーツールが削除する |
空または存在しない User-Agent | スクリプトやヘルスチェックがしばしば省略する |
Host が裸の IP | IP でサイトに到達するのを妨げる |
| TLS 1.0 / 1.1 | 非常に古いクライアントのみ |
7つの選択肢があります:
| オプション | 何のためか |
|---|---|
403 Forbidden(デフォルト) | ブロックが意図的であったことを示す。誤って捕捉された人間が対処できる唯一のもの |
404 Not Found | 何かがブロックされたこと自体を隠す |
410 Gone | 行儀の良いクローラーに URL を永久に削除するよう求める — 攻撃者ではなくクローラーを拒否する場合は 403 よりこちらを推奨 |
429 Too Many Requests | 礼儀正しいクライアントにバックオフして再試行するよう伝える |
418 I'm a teapot | RFC 2324 のジョーク。動作はするが、IANA 登録されておらず、NGINX は空のボディで送信する |
444 close connection | まったく返信しない。最も低コストだが、サーバーがダウンしているのと区別がつかない |
Tarpit | 403 を返すがボディを毎秒1バイトで細流するため、クライアントは先に進む代わりに待機する |
Tarpit は誤検知に対して最も穏やかなオプションです — 誤って捕捉されたクライアントは拒否されず、遅くなるだけです — そしてボットにとってはコストが最も厳しいものです。ボットの接続はアイドル状態のままになります。選択する前に知っておくべきこと: それはあなたのワーカー接続の1つもその間保持するため、tarpit されたクライアントの洪水は実際の訪問者と worker_connections を奪い合います。
これらのそれぞれは、ダッシュボードの「Automatic blocking」パネルの独立したスイッチ、または CLI の set-detector です。それぞれが時間制限付きのファイアウォールブロックを追加します。nftables ではカーネルが期限切れになると解除します。iptables ではスクリプトが次に適用されるまで残ります。
検出はウィンドウ方式です: 検出器はそのウィンドウ内でログが示すものだけをカウントし(1日、または以下の3つの行動ベースのものについては1時間。set-detector --window-hours で変更可能)、ブロックはそれを作り出した証拠を消費します。したがって、期限切れのブロックは新たな違反に対してのみ再び現れ、最初のスキャンが古いログ行でブロックすることは決してありません。list-detectors は各検出器のスイッチ、ブロック期間、しきい値、ウィンドウを表示します。
これらは内部タイマーで実行され、毎分 SSH および NGINX アクセスログを再読み込みします — ただし TUI または Web UI が実行されている間のみ。 どちらか一方が同じスケジュール、同じデータベースで維持するため、Web UI を起動したままにしておけば十分です。どちらも実行されていないときは何も検出されません。stop-bots プロセスがまったくないサーバーについては、以下の無人、cron からを参照してください。
最初の5つは新しいデータベースでオンになっています:
/.env、/.git/config、/wp-config.php などへの単一のリクエストは即時禁止です。組み込みリストは、どこかで正当なパス — /wp-login.php、/wp-admin/、/xmlrpc.php、/phpmyadmin — を意図的に除外しています。なぜなら、自分の管理者を締め出すことは、404 検出器がとにかく捕捉するスキャナーを見逃すよりも悪いからです。set-probe-paths で独自のものを追加してください。${jndi: ルックアップ、PHP-CGI の allow_url_include エクスプロイト、$(wget …) または ../../、エンコード方法を問わず。1回のリクエストで十分で、ブロックは1週間続きます。人が入力する可能性のあるテキスト、例えば /etc/passwd や union select は、検索ボックスとリファラー以外でのみカウントされるため、ブログでそれを検索しても安全です。デフォルトでオフ:
robots.txt に Disallow: としてのみ公開され、どこからもリンクされていないパス。そこに到達することは robots.txt を無視することを意味し、禁止に値します。機能させるには robots.txt 生成をオンにする必要があります。さらに3つは、クライアントが何を求めるかではなく、どのように振る舞うかを調べます。3つともデフォルトでオフです。それぞれに誤検知があるためです — そして3つとも検証済みの検索エンジンクローラーを除外します。そうでなければそれらすべてに一致してしまうからです:
304 は取得されたアセットとしてカウントされます)。アセットをまったく配信しないサイトでは役に立ちません。Referer が決してない。Referrer-Policy: no-referrer とプライバシーツールによって弱められますが、異なるパスのしきい値がそれを実用的にします。どの検出器も Cloudflare のエッジアドレスをブロックすることはありません — エッジをブロックすると、それを経由する全員をブロックしてしまいます。あなたのサイトが Cloudflare の背後にあり、NGINX が訪問者ではなくエッジをログに記録する場合、検出器は誰もブロックできません。その場合 status が警告し(cdn-edges)、NGINX が再び訪問者をログに記録するようにする set_real_ip_from と real_ip_header の行を提示します。