Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
stop-bots — 悪意のあるボットがサーバーにアクセスするのを自動的に阻止する | Kitploit
ツール/GitHubGitHub/ivankovic/stop-bots
防御ツール構成監査情報収集ウェブセキュリティネットワークセキュリティユーティリティとフレームワーク侵入検知アンチボットログ分析
GitHubivankovic/stop-bots

stop-bots

悪意のあるボットがサーバーにアクセスするのを自動的に阻止する

リポジトリを見る
121日前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

Stop Bots

CI crates.io Coverage MSRV License: AGPL v3+

TUI、Web UI、CLI を備え、CDN の背後に隠れることなく、悪質なボットをサーバー側で遮断するための設定を支援するツールです。

NGINX と既存のファイアウォール(iptables または nftables)と連携し、2 つの異なるレイヤーで動作します:

  • NGINX 設定。 - 既知のボットをカテゴリ(スキャナー、検索エンジン、AI クローラー)ごとに分類し、サイト設定にルールを注入することでブロックまたは許可します。NGINX ログをスキャンしてボットを動的に検出し、まだどのルールセットにも登録されていないボットでもブロックできます。
  • ファイアウォールスクリプト。 - 特定の国、データセンターの IP 範囲、既知のボット IP 範囲、またはサーバーへのログインに繰り返し失敗する任意の IP アドレスをブロックします。

stop-bots ダッシュボード:システム全体のボットカテゴリ、ジオブロッキング、自動検出機能、内部 cron

このアプリはサーバーから締め出さないよう最善を尽くしますが、使用は自己責任でお願いします。また、AGPL ライセンスの下で提供されているため、商用利用する場合はライセンスの文言に従ってください。

インストール

crates.io から:``` cargo install stop-bots

root@kitploit:~
チェックアウトからビルドする場合:```
cargo install --path .

GitHub の releases で、ビルド済みの x86_64 Linux バイナリを入手できます。

依存関係

ビルドには Rust 1.88 以降が必要です。実質的に Linux 専用です。systemctl、nginx -t、nft/iptables を外部コマンドとして呼び出すため、他の環境でもコンパイルはできますが、そこではほとんど役に立ちません。

使い方

引数なしでバイナリを実行すると TUI が起動します。同じ画面をブラウザで表示するには stop-bots web(Web UI を参照)、CLI サブコマンドの完全な一覧は stop-bots --help を参照してください。TUI と CLI は併用できます。TUI ですべてを設定し、その後 crontab で CLI を使ってルールを最新の状態に保つ、という使い方ができます。

アプリの終了、またはポップアップ/サブメニューから戻るには、'q' または Escape を押します。

テーマ

't' でダークテーマとライトテーマを切り替えられます。アプリはテーマの自動検出を試みますが、一部のターミナルとマルチプレクサの組み合わせでは、正しい選択を行うための情報が十分に得られません。

画面

1〜4(または d/b/s/p)で各画面に直接ジャンプできます。Left/Right、またはその vim エイリアス h/l で画面を順に移動できます。? でいつでもキーバインドの完全なリファレンスを切り替え表示でき、: でコマンドパレットを開いてすべてのアクションを名前で一覧表示できます。Tab / Shift+Tab は常に現在の画面のパネル間を移動し、画面間を移動することはありません。

Dashboard はファイアウォールスクリプトに最終的に含まれるすべてを管理し、Site settings はNGINX 設定に最終的に含まれるすべてを管理します。この分担によって、各設定がどこに属するかが決まります。

  • Dashboard(デフォルト画面): システム全体のカテゴリ既定値(Scanners / Search Bots / AI Bots — Allowed または Blocked)、ホスト全体のジオブロッキング(特定の国をブロックまたは許可リスト化)、各検出器と各サードパーティブロックリストのオン/オフスイッチを備えた「Automatic blocking」パネル、レンダリングで書き込まれるルール数・ディスク上のスクリプトが古くなっているかどうか・レンダリング元のサイトとボットリストを示す「Firewall script」パネル、内部 cron のジョブとその最終実行時刻を示す「Scheduled」パネル(現在バックグラウンドで実行中のジョブの横にはスピナーが表示されます)、そしてアプリが最後に何を行ったかの Log。タブの下のステータスストリップは、どの画面でもホストのヘルスチェックを表示します。Up/Down は 3 つのリスト間を移動します。m はジオモードを切り替えます。F を押すと現在のファイアウォールルールをスクリプトにレンダリングします — ポップアップには「apply after writing」トグル(Space)もあり、後で手動で適用する代わりに、実際に即座に適用できます。さらに 3 つのキーがホスト全体に作用します。u はすべてのリストをダウンロードし、a は両方のプレーン(NGINX、次にファイアウォール)を適用し、w はこのコンソールを NGINX の背後に配置します — ブラウザでボタンとパネルとして提供されているのと同じ 3 つです。
  • Bot settings: 既知のすべてのボットリストソース(更新アクション付き)と、すべての個別ボットを一覧表示します。名前で検索でき、ボットごとのオーバーライド(Allowed / Blocked / カテゴリ既定に従う)があります。
  • Site settings: 生成される設定を形作るホスト全体の選択肢を保持する「NGINX settings」パネル(Tab でフォーカス)— ブロックされたリクエストに何を返すか(下記参照)、生成された robots.txt を配信するかどうか、レート制限 — が、ディスク上で検出されたすべての NGINX サイトの上にあります。各サイトにはライブの「up to date / stale / not found」ステータスと、現在のポリシーを 1 つのサイトまたはすべてのサイトに適用するアクションがあります。これらの設定を変更すると、適用済みのすべてのサイトが STALE に変わり、再適用の合図となります。サイトを開くと、そのカテゴリ/ボットポリシーをオーバーライドし、6 つのリクエスト形状ルールのいずれかをオンにし、ブロックから除外するパスを一覧表示できます。

Bot settings。すべてのリストソースとすべての個別ボットがここにあります:

Bot settings: the three bot-list sources with their counts, and a search matching five bots across categories

Site settings。ホスト全体の NGINX の選択肢が、ディスク上で見つかったすべてのサイトの上にあります:

Site settings: block response, robots.txt and rate limiting, above two sites tagged UP TO DATE and STALE

Dynamic Protection。現在サーバーに到達しているもののライブビュー:

Dynamic Protection: failed SSH logins and top user agents, each row tagged BLOCKED, BLOCKLIST or NOT BLOCKED

実際に何から守るのか

NGINX 設定を使う

  • 既知のボットをカテゴリ別(scanner / search engine / AI crawler)に。 ArcJet's Well-Known Bots、 ai.robots.txt、 NGINX Ultimate Bad Bot Blocker リストから取得します。カテゴリをブロックすると、各サイトの NGINX 設定に if ($http_user_agent ...) ルールが挿入されます(apply-blocks / Site settings の a/A)。

  • リクエストが多すぎる場合は、NGINX 自身のレート制限を使います。ここにある他のすべてとは異なり、これは後でログを分析するのではなく、リクエスト時に NGINX によって適用されます。既定ではオフです。間違ったサイトに合わせた制限は、実際の訪問者を追い払ってしまいます。

  • まず礼儀正しく — ブロックしているすべてのボットを列挙した、生成された robots.txt(任意)。これを尊重するクローラー向けで、下記のハニーポットパスも含みます。既定ではオフです。現在 /robots.txt で配信しているものを置き換えてしまうからです。

  • ただし指定した場所以外では — サイトごとのパス除外により、/blog 以外では AI クローラーをブロックする、といったことができます。

  • ブラウザらしくないリクエストをサイトごとに。6 つの独立したルールがあり、それぞれに専用のトグルがあり、すべて既定ではオフです — ルールごとに 1 つのスイッチなので、自分の何かが動かなくなったとき、どのルールが原因か分かります:

ブロックされたリクエストが実際に受け取るもの

Site settings にあるホスト全体の 1 つの選択肢です。これらは互換可能なステータスコードではありません — それぞれ異なることを伝え、その違いは、あなたが捕まえるつもりのなかったクライアントにとって最も重要です:

ターピットは誤検知に対して最も穏やかなオプションです — 誤って捕まえたクライアントは拒否されず、遅くされるだけです — そしてボットにとってはコスト面で最も厳しく、その接続はアイドル状態のままになります。これを選ぶ前に知っておくべきことが 2 つあります。ターピットはその間、あなたのワーカー接続の 1 つも占有するので、ターピットされたクライアントの洪水は worker_connections をめぐって実際の訪問者と競合します。そして実際にどれだけ続くかは、NGINX が小さなエラーボディをどう書くかに依存し、TODO.md に実際のサーバーでの確認が必要と記されています。

ログから、自動的に

これらはそれぞれ Dashboard の「Automatic blocking」パネルにある独立したスイッチで、それぞれが自動的に期限切れになり、行為が続けば再追加される一時的なファイアウォールブロックを追加します。

これらは内部タイマーで動作し、毎分 SSH と NGINX のアクセスログを読み直します — ただし TUI または Web UI が実行されている間だけです。 どちらでも同じスケジュール、同じデータベースで動作するので、Web UI を立ち上げたままにしておけば十分です。どちらも実行されていないときは何も検出されません。stop-bots プロセスがまったく動いていないサーバーについては、下記の Unattended, from cron を参照してください。

  • SSH および Web スキャナー: 大量の SSH ログイン失敗、または多数の異なる 404 パスを持つ IP。最近 SSH ログインに成功した IP、または既知のクローラーが公開している IP 範囲内の IP は決して対象になりません。
  • 偽装クローラー: Googlebot、Bingbot、GPTBot を自称しながら、そのクローラーの運営者自身が公開していないアドレスからのもの。最も安価で一般的な偽装であり、公開された CIDR リストがそれを決着させます。それらのリストが実際に取得されるまでは機能しません。
  • 露出した秘密情報の探索: /.env、/.git/config、/wp-config.php などへの単一のリクエストはそれだけで決定的なので、しきい値は不要です。組み込みリストは、どこかで正当なパス — /wp-login.php、/wp-admin/、/xmlrpc.php、/phpmyadmin — を意図的に除外しています。自分の管理者を締め出すのは、404 検出器がどうせ捕まえるスキャナーを見逃すより悪いからです。set-probe-paths で独自のパスを追加できます。
  • ハニーポット: 生成された robots.txt に Disallow: としてのみ公開され、どこからもリンクされていないパス。そこに到達することは robots.txt を無視することを意味し、正当なものは偶然にはそうしません — ここで最強のシグナルであり、最長のブロックです。機能させるには robots.txt 生成がオンになっている必要があります。

さらに 3 つは、クライアントが何を求めるかではなく、どのように振る舞うかに注目します。3 つとも既定ではオフです。それぞれに単独では排除できない誤検知があるからです — そして 3 つとも検証済みの検索エンジンクローラーを除外します。そうでなければ、それらすべてに一致してしまうからです:

  • アセットを取得しない: 多数の異なるページがあり、スタイルシート、スクリプト、画像が 1 つもない。ブラウザはページに付随するものを読み込みます。API クライアントは捕まえません(異なるパスを数え、API クライアントはヒットが少ない)。また、よくキャッシュされた再訪者も捕まえません(304 は取得されたアセットとして数えられます)。アセットをまったく配信しないサイト — 純粋な JSON API — では役に立ちません。
  • ユーザーエージェントのローテーション: 1 つのアドレスから複数のアイデンティティ。NAT によってかなり弱められます: キャリア、キャンパス、オフィスのゲートウェイは 1 つの IP 上で多数の実ブラウザを提示し、タイムスタンプ解析なしでは、それをエージェントを循環させる 1 つのスクレイパーと区別する方法がありません。
  • リファラーなしでクロール: 多数の異なる深いページがあり、Referer が決してない。Referrer-Policy: no-referrer とプライバシーツールによって弱められます。異なるパスのしきい値が、これをそもそも使えるものにしています。

アドレス別

  • 国全体を、IPdeny の集約 CIDR リスト経由で — 特定の国をブロックするか、許可リストモードに切り替えてそれ以外すべてをブロックします。
  • 既知の悪いアドレスを、サードパーティリスト経由で: FireHOL level 1、Tor 出口ノード、blocklist.de。すべて既定ではオフです。
  • ホスティングプロバイダー全体: AWS、Google Cloud、DigitalOcean は自社のアドレス空間を公開しており、住宅の訪問者はそこからブラウズしません。これらは鈍器であり、そのようにラベル付けされています — ボットだけでなく、そこにホストされているすべての訪問者をブロックします。VPN エンドポイント、企業の出口、API クライアントも含みます。既定ではオフで、オンにすると警告が表示されます。
  • 隣接アドレスを、任意で: 1 つの IPv4 /24 内の複数のアドレスが同じパスでフラグ付けされた場合、その /24 をブロックします。既定ではオフです — 3 つが問題を起こしたからといって 256 個のアドレスをブロックするのは、設計上の巻き添えです。(IPv6 は異なり、スイッチは不要です。検出は常に /64 をブロックします。/64 は 1 つの LAN であり、単一の IPv4 アドレスが表すものと同じだからです。IPv6 攻撃者がたまたま使った単一のアドレスをブロックしても何も止まりません — 彼らにはさらに 2^64 個あります。)
  • その他すべてを、手動で — IP/CIDR の許可またはブロックルールを直接追加するか、Dynamic Protection 画面を使って、自動しきい値を超える前に見つけた特定の IP やユーザーエージェントを恒久的にブロックします。

実際に機能しているか?

上記はすべて生成されたものです。そのいずれかが実際に有効かどうかは別の問題であり、それに答えるのが stop-bots status です:``` stop-bots status

root@kitploit:~
7つのチェックがあり、最初のものが最も価値がある。生成されたルールは実際にカーネル内に存在するのか、それともディスク上にあるだけなのか? ある実ホストでは、`/etc/stop-bots/firewall.nft` に48,860件のdropルールがありながらルールセットが空のまま3週間稼働していた。スクリプトの作成とロードは2つのステップであり、2番目を確認するものが何もなかったからだ。

残りは、ルールセットが再起動後も維持されるか(`nftables.service` が有効か?)、スクリプトが依然としてルールと一致しているか、NGINXのブロックが適用されているか、コンソールサービスが指定されたバイナリを実行しているか、データベース用の空き容量があるか、検出器がログを読み取れるか、である。

何かが **CRITICAL** であれば非ゼロで終了するため、監視チェックとして機能する。`--quiet` は注意が必要なものだけを出力し、これがcron用の形式である:```
0 * * * * /usr/local/bin/stop-bots status --quiet

実行できなかったチェック — nft list には root が必要 — は UNKNOWN を報告し、決して OK にはなりません。確認できなかったからといってすべて問題ないと報告するヘルスチェックは、信じられてしまう分、何もないより悪いのです。

同じレポートはコンソールと TUI の両方の Dashboard にあり、レンダリングのたびではなく内部 cron によって毎時取得されます。大規模なルールセットに対する nft list は数メガバイトのテキストになるからです。

あなたなしでは何も起こりません

上記のすべてのファイアウォール判断は生成されるだけで、自動的に適用されることはありません。render-firewall(または Dashboard の f キー)はレビューして自分で適用するための iptables または nftables スクリプトを書き出し、現在接続中の SSH セッションをロックアウトしてしまうスクリプトの書き出しは拒否します。

それを代わりに適用できるものが 3 つあり、いずれもあなたが要求する必要があります。TUI のレンダーポップアップ(「書き込み後に適用」)またはその a キー、Web コンソールのファイアウォールパネル(「書き込み後に実行」)またはその「Apply everything」ボタン、そしてあなたが書いた crontab からの batch --apply です — Unattended, from cron を参照してください。これらのいずれも、何か自動的なものの副作用ではありません。内部 cron はスクリプトをレンダリングするだけで、決して実行しません。

同じことは NGINX 側にも当てはまります。設定を変更しても、書き込まれるであろう内容が変わるだけです。Site settings は適用するまで各サイトを STALE として表示します。

検出器をオフにしても、すでに追加されたブロックは削除されません — それらは自然に期限切れになります。「検出を停止する」と「検出されたものを元に戻す」は意図的に別物です。後者は Dynamic Protection 画面または remove-firewall-rule です。

ブロックとは独立した、単純なアクセスログの集計もあります。record-access-stats / list-access-stats は、成功した(エラーでない)リクエストに各ユーザーエージェントがどれだけ頻繁に現れるかを数えるので、誰がブロックされているかに加えて、誰が実際に訪問しているかを確認できます。

Unattended, from cron

stop-bots batch は、TUI が手動で行うすべてを 1 回のパスで実行します。すべてのリストを更新し、ログをスキャンし、NGINX ブロッキングルールとファイアウォールスクリプトを書き出します。```

One full pass a night. Refreshes the lists, scans the logs, applies both.

0 4 * * * root /usr/local/bin/stop-bots batch --apply --ssh-log /var/log/auth.log

And detection every ten minutes, without re-downloading lists that change weekly.

*/10 * * * * root /usr/local/bin/stop-bots batch --apply --no-fetch --ssh-log /var/log/auth.log

root@kitploit:~
すべてがうまくいったときは何も出力しないので、正常な夜間実行ではメールが届きません。失敗した
ステップは stderr に出力し、非ゼロの終了ステータスを設定します。これにより cron があなたに
それを知らせます。まず手動で `--verbose` を付けて一度実行してください — ステップごとに1行出力され、
実際に何をしているかを確認する最も簡単な方法です。

**`--apply` が実際に何かを強制する鍵です。** これがないと、`batch` は NGINX 設定
とファイアウォールスクリプトを書き出して停止します。設定はリロードするまで何もせず、スクリプトは実行されるまで何もしません。
これはこのプロジェクトのどこでもデフォルトであり、ここでもデフォルトのままです。

`batch` と長時間実行されるフロントエンドは安全に共存できます。TUI、Web UI、`batch` はすべて
同じデータベースの同じキーを通じて実行内容を記録するため、どれかが先にジョブに到達すればそれを実行し、他はそれが期限切れでないことを検知します — 二重の検出パスは発生せず、
Dashboard の「Scheduled tasks」パネルには、すべてが期限切れだと主張するのではなく、実際に何が起きたかが表示されます。すでに Web UI を動かしっぱなしにしているなら、夜間の `batch` エントリは必須ではなく念のための保険です。動かしていないなら、それが検出を最新に保つ唯一の手段です。

**`--apply` を付けると、SSH ロックアウトガードが拒否することがあります — そして拒否は何も適用されないことを意味します。**
ルールが現在接続中のクライアントをブロックする場合、*かつ* SSH ログがまったく読めなかった場合に拒否します。後者の場合、チェックを実行できないからです。対話型の
`render-firewall` は2番目のケースでメモを出力するだけです。人間がターミナルを見ているという理由からです。cron からは誰も見ていません。**`--ssh-log` を明示的に渡してください**: cron は root として実行されるため `/var/log/auth.log` は通常問題なく読めますが、journald のみのホストでは cron 下の `journalctl` が空を返すことがあり、まさにそれが拒否するケースです。`--force` は本気ならガードを上書きします。

1つのステップが失敗しても他のステップは決して停止せず、NGINX とファイアウォールの半分は独立しています —
NGINX のリロードが失敗してもファイアウォールは適用されたままで、その逆も同様です。

`batch` は各ステップを TUI の内部 cron が使用するのと同じスケジュールに対して記録するため、両者は
すでに実行された内容について一致し、両方が実行することを避けます。また Dashboard の「Scheduled
tasks」パネルには、実際の cron が何をしたかが表示されます。

# Web UI

`stop-bots web` は同じ5つの画面をブラウザで提供します。```
stop-bots web

127.0.0.1:8787 にバインドされ、そのマシンからのみ到達可能で、初回実行時に生成されたパスワードを一度だけ出力します。ラップトップから SSH トンネル経由でアクセスします:``` ssh -L 8787:127.0.0.1:8787 your-server

root@kitploit:~
次に <http://127.0.0.1:8787/> を開きます。

![Webコンソールのダッシュボード: ヘッダーにヘルスチップとホスト全体の2つのボタン、一方の列にポリシー、ジオブロッキング、サードパーティフィード、もう一方の列に自動ブロッキングとスケジュールタスク](https://assets.kitploit.com/production/public/readmes/55148/73bbcc92f0f3d2c9d0586bd71ad18f1b4d582fa59824b4f5e3c97e08575f5070/bb45db648f6a59192f56b1e14a019f50f0816bff651766316c377cbe79f700b6-display-v1.webp)

コンソールはオペレーティングシステムのライト/ダーク設定に従い、ヘッダーにトグルがあります。上記のTUIスクリーンショットはダークテーマで、こちらはライトテーマです。TUIが使用するキーはここでも機能します: `1`–`4` で画面を切り替え、`/` で検索ボックスにフォーカスし、`?` でヘルプを開きます。

![Webコンソールの動的保護ページ: 失敗したSSHログインとトップユーザーエージェント、それぞれにカウントバーと状態タグ、行ごとにブロックまたはブロック解除ボタン](https://assets.kitploit.com/production/public/readmes/55148/090d4d2151eb00a69781c44351abe10f268d8031816199b9aeb5b4d2cddfc5f5/52a05387d1227288e7f45ece3c33e4af17957d8e9e73fb7c0213d64c49dc7419-display-v1.webp)

3つのホスト全体のアクションがヘッダーにあり、ブラウザではボタンとして、TUIでは単一キーとして利用できます:

- **すべて更新** (`u`) は、すべてのボットリスト、すべてのクローラーIP範囲、すべての*有効な*レピュテーションフィード、およびすべての*選択された*国をダウンロードします — `stop-bots batch` が取得するのと同じセットを、同じプランから取得します。1つのソースが失敗しても残りは停止せず、何かが適用するまで何も強制されません。
- **すべて適用** (`a`) は、NGINX設定を書き込んでリロードし、次にファイアウォールスクリプトを書き込んで実行します。2つのプレーンは独立しています: どちらかが失敗しても、もう一方は順番を得ます。なぜなら、半分適用されたホストは、NGINX構文エラーでファイアウォールも古いままになったホストよりもましだからです。
- **Webアクセス** (`w`) は、NGINXがコンソール自体を提供するように設定します — [NGINXの背後](#behind-nginx-a-subdomain-or-a-path-prefix)を参照してください。

## サービスとして (Debian)```
sudo stop-bots install web

/etc/systemd/system/stop-bots-web.service を書き込み、/var/lib/stop-bots(0700 — コンソールのパスワードハッシュを保持)と /etc/stop-bots を作成し、パスワードが存在しなければ生成し、ユニットを有効化して起動します。

--dry-run は計画全体を表示し、何も変更しません。 これはプロジェクト内でデーモンを起動する唯一のコマンドなので、まずそこから始めてください。--prefix <dir> は同じツリーを root なしで読める場所に書き込みます。ユニットが既に存在し、あなたが編集している場合、インストーラーはあなたの編集を置き換えるのではなく停止してその旨を伝えます。本当に置き換えるつもりなら --force を使ってください。

サービスは root として実行されます。コンソールが /etc/nginx を書き換え、ファイアウォールスクリプトを書き込み、nginx -t と systemctl reload nginx を実行するためです。機能セットを維持したまま非特権に分割する方法はありません。ユニットにはその要件を生き残るハードニングと、どのハードニングを省略したか、その理由を記したコメントが含まれています。

バインドアドレス、ホスト許可リスト、パスプレフィックスは意図的にユニットに含まれていません — 実行中のサーバーがデータベースから再読み込みするため、ExecStart に入れると信頼できる情報源が二つになってしまいます。これらを変更するには stop-bots web --save ... を使って再起動してください。

これが root として実行されると一つ変わることがあります。内部 cron の毎日の RenderFirewall ジョブが /etc/stop-bots/firewall.nft を書き込めるようになりますが、あなた自身としてコンソールを手動で実行していたときは書き込めませんでした。そのスクリプトを適用するものは何もありません — 実行するのは依然としてあなたの役目です。

チェックされるのは Debian のみです。テストされているのがそれだからです。ユニットは systemd を採用するあらゆるディストリビューションでほぼ確実に正しく動作しますが、想定している SSH ログのパスは Debian のものです。

公開する

ループバック以外にバインドするには、二つ目の意図的なフラグが必要です。このコンソールは実行されているホストのファイアウォールと NGINX 設定を書き換えられるためです:``` stop-bots web --bind 0.0.0.0:8787 --expose --allowed-hosts admin.example.com --save

root@kitploit:~
`--allowed-hosts` は実運用上省略できません。リストにないホスト名を持つリクエストは拒否されます。これによりコンソールに対する DNS リバインディングが失敗し、名前でアクセスされる公開サーバーではその名前を明示する必要があるのです。

TLS 付きの NGINX の背後に配置してください — このツールが保護しているのと同じ NGINX です。そうする場合、プロキシが `X-Forwarded-For` を設定するなら、コンソールにそのヘッダーを信頼してよいと伝えてください。そうしないと、リクエストが実際にどこから来たのかを判別できません:```
stop-bots web --bind 127.0.0.1:8787   # and set web:trust_forwarded_for

TLS の背後では、web:secure_cookie も設定してください。これがないと、ブラウザは同じホストの http:// URL に対してもセッション Cookie を送信してしまいます。

web:trust_forwarded_for は見た目以上に重要です。これがないと、プロキシ背後のすべてのリクエストが 127.0.0.1 から到着したものとして扱われるため、コンソールはあるクライアントと別のクライアントを区別できません — つまり、大量のログイン試行があなたと同じスロットルバケットを共有することになり、自分自身のアドレスをブロックしてしまうのを防ぐガードも比較対象を持ちません。これを設定すれば、どちらもクライアント単位で機能します。

NGINX の背後: サブドメイン、またはパスプレフィックス

コンソールからこれを設定できますし、TUI からも可能です(Dashboard で w)。どちらも NGINX 設定を書き込み、パスプレフィックスを記録し、ホスト名を許可リストに追加します — この 3 つは一致していなければなりません。なぜなら、プレフィックスが欠けるとすべてのリンクが location ブロックから外れてしまい、ホスト名が欠けるとすべてのリクエストが 403 になるからです。どちらも設定が有効になる前に nginx -t で検証し、失敗した場合はロールバックし、検証が通って初めて新しいアドレスを記録します。

2 つのモードがあり、path がデフォルトであるのには理由があります。既存のサイトに location ブロックを追加するため、コンソールはそのサイトの証明書を継承します。サブドメインには独自の証明書が必要で、certbot --nginx -d <host> が実行されるまで、このコンソールのパスワードフォームとセッション Cookie は平文でネットワークを流れます。

このセクションの残りは同じことを手動で行う方法です。パネルを使う場合でも一度読む価値があります — 以下の末尾スラッシュの罠は、まさにそれを防ぐために存在する間違いです。

サブドメインの方がシンプルなデプロイであり、可能ならこちらを選ぶべきです:```nginx server { server_name stopbots.example.com; location / { proxy_pass http://127.0.0.1:8787; proxy_set_header Host $host; } }

root@kitploit:~
## 検出

### 検出ルール

- ルールは `rules/` ディレクトリに配置されています。
- 各ルールは、検出ロジックを定義した YAML ファイルです。
- ルールは、疑わしいアクティビティのパターンを識別するために、イベントデータと照合されます。

### 検出の仕組み

1. イベントが収集され、正規化されます。
2. 正規化されたイベントが、有効な検出ルールと照合されます。
3. 一致したルールは、設定された重要度に基づいてアラートを生成します。
4. アラートは、設定された出力先に送信されます。

### ルールの構造

```yaml
title: Suspicious Process Execution
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects suspicious process execution patterns
author: Security Team
date: 2024/01/01
level: high
logsource:
    category: process_creation
    product: windows
detection:
    selection:
        Image|endswith:
            - '\suspicious.exe'
            - '\malicious.exe'
    condition: selection
falsepositives:
    - Legitimate administrative tools
tags:
    - attack.execution
    - attack.t1059

ルールの管理

  • ルールは、rules/ ディレクトリ内でカテゴリ別に整理されています。
  • 各ルールには、一意の id フィールドが必要です。
  • ルールは、status フィールドを使用して、experimental、testing、stable としてマークできます。
  • ルールは、level フィールドを使用して、重要度別に分類されます。

アラートの重要度

レベル説明
critical即時の対応が必要
high早急な調査が必要
medium調査が必要
low情報提供目的
informational参考情報

誤検知

  • 誤検知は、falsepositives フィールドを使用して文書化する必要があります。
  • 誤検知を減らすために、除外フィルターを追加できます。
  • 定期的なルールのチューニングが推奨されます。``` stop-bots web --allowed-hosts stopbots.example.com --save
root@kitploit:~
**パスプレフィックスも同様に機能します**が、コンソールにそれを伝える必要があります — すべてのリンク、フォームアクション、リダイレクト、Cookieパスをプレフィックス込みで生成する必要があり、推測することはできません:```
stop-bots web --base-path /stop-bots --allowed-hosts example.com --save

検出

検出ルール

  • ルールは rules/ ディレクトリに YAML ファイルとして保存されます。
  • 各ルールは、検出ロジックを定義する detection ブロックを含みます。
  • ルールは、severity、tags、metadata などのメタデータを含むことができます。

検出ロジック

  • detection ブロックは、selection と condition のキーをサポートします。
  • selection は、マッチさせるフィールドと値を定義します。
  • condition は、selection をどのように組み合わせるかを定義します(例: and、or、not)。

例

root@kitploit:~
detection:
  selection:
    EventID: 4624
    LogonType: 3
  condition: selection

フィールド修飾子

  • フィールド修飾子は、フィールドのマッチ方法を変更します。
  • 一般的な修飾子には、contains、startswith、endswith、re があります。
  • 修飾子は、フィールド名の後にパイプ記号(|)を使用して適用されます。

例

root@kitploit:~
detection:
  selection:
    CommandLine|contains: 'powershell'
    Image|endswith: '\cmd.exe'
  condition: selection

条件式

  • 条件式は、selection を組み合わせるために論理演算子を使用します。
  • サポートされる演算子には、and、or、not があります。
  • 括弧を使用して、条件をグループ化できます。

例

root@kitploit:~
detection:
  selection1:
    EventID: 1
  selection2:
    EventID: 2
  condition: selection1 or selection2

集約条件

  • 集約条件は、時間枠内のイベント数をカウントします。
  • これらは | 演算子と count() 関数を使用して定義されます。
  • 集約条件は、ブルートフォースやその他のしきい値ベースの検出に役立ちます。

例

root@kitploit:~
detection:
  selection:
    EventID: 4625
  condition: selection | count() by SourceIp > 10

しきい値

  • しきい値は、アラートをトリガーするために必要なイベントの最小数を定義します。
  • これらは threshold キーを使用して定義されます。
  • しきい値は、ノイズの多い検出をフィルタリングするのに役立ちます。

例

root@kitploit:~
detection:
  selection:
    EventID: 4625
  condition: selection
  threshold:
    count: 10
    timeframe: 5m

相関

  • 相関は、複数のルールを組み合わせてより複雑な検出を作成します。
  • これらは correlation キーを使用して定義されます。
  • 相関は、マルチステージ攻撃の検出に役立ちます。

例

root@kitploit:~
correlation:
  - name: Multiple Failed Logons Followed by Success
    rules:
      - failed_logon
      - successful_logon
    timeframe: 10m
    condition: failed_logon and successful_logon

フィルタ

  • フィルタは、検出からイベントを除外するために使用されます。
  • これらは filter キーを使用して定義されます。
  • フィルタは、誤検知を減らすのに役立ちます。

例

root@kitploit:~
detection:
  selection:
    EventID: 4624
  filter:
    User: 'SYSTEM'
  condition: selection and not filter

抑制

  • 抑制は、重複するアラートを防ぐために使用されます。
  • これらは suppression キーを使用して定義されます。
  • 抑制は、アラート疲れを減らすのに役立ちます。

例

root@kitploit:~
suppression:
  - name: Suppress Duplicate Alerts
    field: SourceIp
    timeframe: 1h

アラート

  • アラートは、検出がトリガーされたときに生成されます。
  • これらは alert キーを使用して定義されます。
  • アラートは、電子メール、Slack、またはその他のチャネルに送信できます。

例

root@kitploit:~
alert:
  - name: Suspicious Logon
    severity: high
    message: 'Suspicious logon detected from {SourceIp}'
``````nginx
location /stop-bots/ {
    proxy_pass http://127.0.0.1:8787;   # NO trailing slash
    proxy_set_header Host $host;
}

proxy_pass の末尾スラッシュは重要であり、その欠如が仕組みのすべてです。 これがないと、NGINX はフルパスをそのまま通し、stop-bots は /stop-bots/whatever を見ることになり、それが現在提供・生成されているものです。末尾に スラッシュがあると、NGINX はプレフィックスを除去します — そしてブラウザはページ内のリンクを ドメインルートに対して解決し、location ブロックの外に着地し、すべてが 404 になります。サーバー側で どれだけ注意を払ってもこれを修正することはできないため、プレフィックスはプロキシを通過して生き残る必要があります。

これを外部から強制するものは何もありませんが、失敗は微妙ではなく明白です。プレフィックスが 設定されている場合、プレフィックスのないリクエストは半分だけ動作するページではなく、単なる 404 になります。

これが行わないこと

2 つのことが意図的に欠けており、Help 画面にはその理由とともに記載されています:

  • ダウンロードしたリストがブロックしたものを解除することはありません — そのリストの次回の更新が それを黙って元に戻してしまうからです。
  • 自身のパスワードを変更することはありません。 ホスト上で stop-bots web --set-password を使用してください。

また、接続元のアドレスをブロックすることも拒否します。それは元に戻すために使用する コンソールを奪ってしまうからです。

以前は 3 つでした。 ファイアウォールスクリプトの適用が 3 つ目でした。それを実行することが ホストをネットワークから切断しうる唯一の操作であるという理由からです。これは現在利用可能です — ダッシュボードの 「Apply everything」(TUI では a)、またはファイアウォールパネルの「run it after writing」ボックス — cron から安全にするガードがボタンからも安全にするからです: ルールは現在 SSH でログインしているクライアントに対して、スクリプト自体が評価する順序でチェックされ、 そのうちの 1 つをブロックするルールは警告ではなく拒否となります。コンソールを --no-apply で 起動すると、以前の書き込み専用の動作に戻ります。

ログイン試行はスロットリングされます。パスワードが推測可能だからではなく — それは生成された 144 ビットです — 1 つの検証が Argon2id を実行するため、認証されていない呼び出し元が投稿できる限り 速くそれを駆動できるようにすることは、このツールが保護することになっているホストに対する サービス拒否攻撃になるからです。10 回の誤った試行は無料です。それを超えるとクライアントは 指数関数的にバックオフし、グローバルキャップが試行の送信元アドレスの数に関係なく CPU を制限します。

コンテナで NGINX を実行する

NGINX が Docker 内にあり、その設定がバインドマウント上にある場合、systemctl reload nginx は 何もリロードしません。代わりに 2 つのコマンドをコンテナに向けてください — これは CLI と TUI にも当てはまります:``` stop-bots set-nginx-commands
--test "docker exec web nginx -t"
--reload "docker exec web nginx -s reload"

root@kitploit:~
コマンドは単語に分割され、直接実行されます。シェルを経由することはないため、`;`、
`|`、`$VAR` は構文ではなく通常の文字として扱われます。


# コントリビューション

コードの構成、テスト方法、および準拠すべきコーディングルールについては
[CONTRIBUTING.md](https://github.com/ivankovic/stop-bots/blob/main/CONTRIBUTING.md) を参照してください。リリースプロセスについては
[RELEASING.md](https://github.com/ivankovic/stop-bots/blob/main/RELEASING.md) を参照してください。

# 連絡先

[[email protected]](mailto:[email protected]) までご連絡いただけます。

# ライセンス

Copyright (C) 2026 Marko Ivankovic

このプログラムはフリーソフトウェアです。Free Software Foundation が公開する
GNU Affero General Public License(ライセンスのバージョン3、または
それ以降のバージョン)の条件に従って、再配布および/または改変することができます。

ライセンスの全文については [LICENSE](https://github.com/ivankovic/stop-bots/blob/main/LICENSE) ファイルを
参照してください。

## AGPL ソフトウェアを使用できない場合

代替ライセンスは **利用できません**。
ツールをダウンロード
  • Dynamic Protection: 現在サーバーに到達しているもののライブで実用的なビュー — 「Top IPs attempting SSH connection」と「Top User Agents」。それぞれカウントでランク付けされ、NOT BLOCKED/BLOCKED(赤で表示)のタグが付きます。Tab/Shift+Tab は Up/Down が作用する 2 つのパネルを切り替えます。f は共有フィルタ(all / not blocked only / blocked only)を循環します。Enter は選択された NOT BLOCKED 行をブロックし、すでに BLOCKED の場合はブロックを解除します。i は選択されたアドレスを検査します。どのレピュテーションフィードがそれを掲載しているか、公開されたクローラーの範囲内にあるかどうか(これが本物の Googlebot と、そう自称するだけのユーザーエージェントを区別するものです)、どの国に属するか、どのアカウントとしてログインを試みたか。すべてこのホストがすでにダウンロードしたリストから得られます — ここには逆引き DNS や whois ルックアップはありません。PTR レコードはアドレスを保持する誰かが書くものであり、権威があるように読める攻撃者提供のテキストになってしまうからです。
  • Help: キーバインドの完全なリファレンス。
  • ルールボット以外に締め出すもの
    HTTP/1.0 および HTTP/1.1HTTP/2 を話さないクローラーや API クライアント
    Accept ヘッダーなし一部の API クライアントは送信しない
    Accept-Language なしプライバシーツールが削除する
    User-Agent が空/不在スクリプトやヘルスチェックがしばしば省略する
    Host が裸の IPIP でサイトに到達できなくなる
    TLS 1.0 / 1.1ごく古いクライアントのみ

    すべてに 2 つの安全策が適用され、あなたに任されず強制されます:

    • TLS に依存する 2 つのルールは HTTPS の server ブロックにのみ書き込まれます。ブラウザは TLS なしで HTTP/2 を行わないため、プレーンな listen 80 ブロックではすべてのリクエストが HTTP/1.1 です — ブラウザが HTTPS へ向かう途中で行うリダイレクトも含めて。通常、ポート 80 とポート 443 のブロックは同じ server_name を共有するので、設定は両方に届きますが、これらのルールが付くのは TLS の方だけです。ヘッダー形状ルールはプレーン HTTP でも機能し、両方に書き込まれます。
    • いずれかのルールがオンになると、/.well-known/ は常に除外されます。ここは Let's Encrypt が HTTP-01 チャレンジを取得する場所で、HTTP/1.1 で Accept なし、しばしば User-Agent なしです — 除外がなければ、数週間後に証明書の更新が止まります。
    オプション何のためか
    403 Forbidden(既定)ブロックが意図的だったことを伝える。誤って捕まえた人間が対処できる唯一のもの
    404 Not Found何かがブロックされたこと自体を隠す
    410 Gone行儀の良いクローラーに URL を永久に削除するよう求める — 攻撃者ではなくクローラーを締め出す場合は 403 よりこちらを推奨
    429 Too Many Requests礼儀正しいクライアントにバックオフして再試行するよう伝える
    418 I'm a teapotRFC 2324 のジョーク。動作はしますが、IANA 登録されておらず、NGINX は空のボディで送信します
    444 close connectionまったく応答しない。最も低コストだが、サーバーダウンと区別がつかない
    Tarpit403 を返すがボディを毎秒 1 バイトで細々と流すので、クライアントは先に進む代わりに待たされる