IPアドレス範囲をブロックする方法

こんにちは。Discourseフォーラムにリクエストを大量に送信している迷惑な/16サブネットを一時的にブロックしようとしています。以下を試しました。

しかし、/var/discourse/shared/standalone/log/var-log/nginx/access.logで同じ範囲からの新しいリクエストがまだ大量に発生しています。

これらはDiscourseで設定されているため、IPアドレスはNGINXではなくDiscourseによってブロックされていると確信しており、NGINXのログに表示されます。ブロックしているのはDiscourseであり、nginxではありません。NGINXのログに表示されないようにブロックしたい場合は、ファイアウォールでブロックできます。

「いいね!」 1

ジェイさん、ありがとうございます。アプリケーションレベルでブロックした場合でも、Nginxのログに表示されるという点については、おっしゃる通りです。しかし、アプリケーションレベルでのブロックも、期待通りには機能していません。VPN経由で接続し、自分のIPアドレスを「Screened IPs」リストに追加しましたが、それでもフォーラムを閲覧できてしまいました。「Screened IPs」は「Blocked IPs」ではなく、「IPアドレスからのアカウント登録のみを防ぐ」という意味なのかもしれません。

私が求めているのは、Discourseアプリが、これらのアドレスからのリクエストに対して、要求されたページへのアクセスを拒否すること、特に、これらのリクエストがCPUを占有しているため、それらのページをレンダリングしないことです。

Discourse は、/admin/users からユーザーレコードを確認した場合、禁止されている IP のいずれかからアクセスしていることを認識しますか? (Cloudflare のようなプロキシを使用している場合、Discourse はユーザーの IP ではなくプロキシの IP を認識している可能性があります。)

はい、VPNに接続すると、Discourseのユーザーアカウントの最後のIPアドレスにVPNから割り当てられたIPアドレスが表示されます。しかし、シークレットブラウジングウィンドウを開いて新しいアカウントを登録しようとすると、許可されません。

IPアドレスからの新規登録は許可されていません。

そのため、「スクリーニングされたIP」は登録専用であり、ウェブサイトへのアクセスを完全に禁止するものではないようです。

さらに厄介なことに、ホストサーバー上の ufw は、Docker 内部では期待どおりにブロックしないようです。

「いいね!」 1

これをどこに文書化しているか分かりませんが、最近何度か話題に上がっています。

「スクリーニング済みIP」は、一致するIPからの登録とログインをブロックしますが、既存のセッションはブロックしません。

これをどこかに文書化しているか(している場合)分かりません。

「いいね!」 3

確認ありがとうございます。

IPアドレスまたはIPアドレス範囲からのリクエストを拒否する最も簡単な方法はどのようなものでしょうか?これを見つけましたが、これは私が求めていること(ブラックリストではなくホワイトリスト)の逆のように思えます。また、コンテナ内のNginx設定をいじるのは、完全にハックな仕事のように感じます。

UFWまたはIPTABLESを使用するのが最も簡単な方法だと思います。これにより、Discourseが関与する前にリクエストが停止します。ファイアウォールを操作することには常に漠然とした恐怖を感じていますが、ポート443のみを対象とする場合は危険はありません。

Digital Oceanにはヒントがあります:https://www.digitalocean.com/community/tutorials/ufw-essentials-common-firewall-rules-and-commands。例をGoogleで検索するだけです。

まさに私も同じことを恐れていました。しかし、ホストで有効にしても、問題のあるIP範囲をブロックしていません。どうやら、Dockerコンテナに拒否ルールを適用するには、複雑なルールのセットが必要なようです。

ああ。そうですね。それは全くその通りです。私は、DockerベースのWebサーバーからDockerベースのPostgresデータベースへのアクセスをブロックしました(おそらくあなたの問題ではありません)。

別のアイデアです:Geo Blocking plugin

ありがとうございます。私もそれを検討していましたが、国全体ではなく、数値IP範囲をブロックすることはできないようです。

最近インストールしていませんが、確かできるはずです。

(強調は追加しました)

しかし、これを見つけました:

ですから、そこには好きなネットワークを入力できるということだと思います。

「いいね!」 1
/var/discourse/launcher enter app
apt install nano
nano /etc/nginx/conf.d/discourse.conf

そして server { ブロックに以下を追加します:

## 2025-10-27
deny 12.34.0.0/16;

その後、保存して以下を実行します:

nginx -t
service nginx reload

なぜ Nginx の access.log12.34.x.x からのアクセスがまだ表示されるのか完全には理解できませんが、CPU 使用率が正常に戻ったため、機能しているようです。信じられないほど複雑なプロセスだと思いますが、サイトを復旧させるにはこれで十分です。

はい、ただし、現在はAS番号のみを受け付け、1.2.3.0/24のようなCIDR表記は受け付けません。

「いいね!」 1

これでうまくいきましたか?私ならこうしますが、
sv restart nginx
エラーが出なかったのなら、私の考えは間違っています。

Nginxはまだそれらを見ていますか?それらを処理していると表示されますか?Railsのproduction.logでそれらを確認できますか?

ああ。AS番号に関するWikipediaのページにもっと注意を払うべきだったかもしれません。

どちらも systemd コマンドにマッピングされた古いエイリアスだと思いますので、systemctl restart nginx が最も適切でしょう。
編集: systemctl は Docker 内では機能しないようです。違いに関する説明は次のとおりです。

はい、access.log には次のように表示されています。

[28/Oct/2025:00:29:27 +0000] "myforum.com" 12.34.56.78 "GET /permalink/12345 HTTP/1.1" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36" "-" 403 691 "-" - 0.000 "-" "-" "-" "-" "-" "-" "-" "

主にパーマリンクにヒットしているようです(古いフォーラムプラットフォームから移行しました)。パーマリンクには、deny ルールを回避できるような抜け穴がありますか? まだ production.log を確認していません。

全体として、アクセスログを検査するための GUI がなく、アプリレベルの IP ブロックリストもないことは、Discourse のかなり重大な制限だと考えられます。まれなケースですが、これらのボット/スクレイパー/クローラー攻撃を受けた場合、設定ファイルや不可解なコマンドをいじくり回すことなく、すぐにソースを特定して軽減したいと考えます。特に、Docker コンテナの奥深くにある奇妙な抽象化をすべて考慮すると、なおさらです。私が移行した非常に古いフォーラムプラットフォームでは、調整可能な時間枠で最も多くのリクエストを行ったユーザーまたは IP の簡単なリストが表示され、CPU 時間を最も多く消費したユーザーおよび/IP でフィルタリングすることもできました。これにより、問題のあるアドレスまたは範囲をすばやく特定でき、それらをブロックリストに追加するためのポイントアンドクリックインターフェイスがあり、それらの IP からのリクエストに対して 404 をスローしました。

deny ルールがある場合、nginx では引き続きログが記録されます。そして、クライアントがアクセスを拒否されたことを意味する 403 がそこにあるため、正しく機能しています。

これらのリクエストは Discourse に転送されていません。ブロックが正しく機能しているかどうかを知りたい場合は、次のいずれかを行う必要があります。

  • 代わりに Discourse の production.log を確認する
  • nginx ログを確認するが、HTTP レスポンスコードフィールドに 403 が含まれるエントリはすべて無視する。
「いいね!」 3

このトピックは解決しましたか?解決策として選択できる投稿は @rgj または @pfaffman のどちらかがありますか?この件では協力されたようですね!

:handshake:

こんにちは。この問題は、現時点では「通常の」方法では解決できないと思います。「Screened IPs」の管理インターフェースは、ほとんどのユーザーが期待するような動作をせず、実際に機能する方法は、DiscourseのDockerコンテナ内をいじる必要があるため、少なくとも私の意見では、ソリューションというよりはダーティハックのようなものです。これがもう少し注目されると素晴らしいのですが: