Discourse はどのように UFW をバイパスできるのでしょうか?ポート 22 のみを有効にし、他のすべてのポートは閉じたはずです。しかし、フォーラムは機能していました。どうして可能なのでしょうか?
DigitalOcean のドロップレットですが、それは関係ないはずです。また、ワンクリックインストールではなく、公式の方法です。
これは純粋なサポート質問ではありませんが、ここには「初心者による愚かな基本的な質問」というカテゴリがありません ![]()
Discourse はどのように UFW をバイパスできるのでしょうか?ポート 22 のみを有効にし、他のすべてのポートは閉じたはずです。しかし、フォーラムは機能していました。どうして可能なのでしょうか?
DigitalOcean のドロップレットですが、それは関係ないはずです。また、ワンクリックインストールではなく、公式の方法です。
これは純粋なサポート質問ではありませんが、ここには「初心者による愚かな基本的な質問」というカテゴリがありません ![]()
ufw status verbose を実行すると、sshd のみ表示されるということですか?
はい、その通りです。そしてUFWが有効になっていました。
ufw status verbose を実行したときにデフォルトで表示されたのは何ですか?
あなたが望んでいると思われるものについては、次のように表示されるはずです。
デフォルト: deny (着信), allow (発信), disabled (ルーティング済み)
あなたが説明している動作については、次のように表示されるはずです。
デフォルト: allow (着信), allow (発信), disabled (ルーティング済み)
インコグニートウィンドウまたは別のブラウザでフォーラムを開いてみましたか?キャッシュされたバージョンが表示されるのに簡単に騙されることがあります。私自身も騙されたことがあり、ステージングサイトが全く動作していないのに、別の開発者に「ステージングサイトは問題ない」と言われたことがあります。
22/tcp (OpenSSH) ALLOW IN Anywhere
と、あるべき通りでした。私が常に実行する2つのことは、OpenSSHを許可し、UFWを有効にすることです。
Nginxをインストールする場合のように、必要に応じてポートを開きます。しかし、そのVPSはDiscourse専用だったので、それ以外は何もせず、UFWを完全に忘れていました。
それはありえません。そのフォーラムは数週間生きていました。
Nginx/VarnishをそのVPSに接続して別のポートを開く必要があったときに、この状況に気づきました。開いていたのはポート22だけでした。
編集:
メールを送信するにはどうすればよいですか?ポート587も開いていませんでした😳
これは本当に奇妙です。
デフォルトが拒否に設定されているのかどうか、明確ではありません。「デフォルト」行について具体的に質問している理由は、デフォルトを許可に設定し、特定のポートを許可するように設定することも可能ですが、後者はその構成では何も変更されないためです。
もし他の誰かが Discourse を設定した場合、その人がデフォルトを許可ではなく、HTTP/HTTPS ポートを許可するように変更した可能性はありますか?
これはどこかの SMTP サーバーへの接続だと推測します。Discourse サーバーがポート 587 を使用してその SMTP サーバーに接続しているということです。デフォルトではすべてのポートへのアウトバウンド接続が許可されているため、送信ポリシーを明示的に変更しない限り、UFW はメール送信の妨げにはなりません。
私のミスです ![]()
Default: deny (incoming), allow (outgoing), deny (routed)
いいえ。しかし、allow (outgoing) は何かを送信することを許可しますか?もしそうなら、「初心者による愚かな基本的な質問」というカテゴリはありません」に戻り、新しいことを学びました。
編集:
まだ迷っていますが、deny (incoming はどうですか?
これを見つけました。
短い答えは、Discourse はファイアウォール ルールをバイパスできないということです。OS に関する愚かな質問をする場所は、Stack Exchange のような場所です。(失礼だと思わないでください。そのような答えはそこにあります。初期のリリースから Linux を実行してきましたが、今でもそのような場所で愚かな質問をしています。まだあります!)
その場所は知っています
信号対雑音比が非常に高すぎます。まあ、それは不公平な特徴付けでしたが、そこから関連性の高いものを見つけるのは本当に難しいという意味でした。それは非常に大規模です。
これは実際には非常に良い質問であり、他の誰もまだ尋ねていないことに驚いています。答えは複雑ですが、これまでのところ、このトピックに関する回答は、質問に答えることなく、残念ながら軽視するようなトーンでした。
Discourseがufwをバイパスしているわけではなく、dockerがufwをバイパスして、ufwが存在してもdockerコンテナの公開ポートが機能するようにルールを追加しているのです。
コンテナ宛ての着信パケットは、予想されるかもしれないINPUTテーブルではなく、FORWARDテーブルにヒットします。
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ufw-before-logging-forward all -- any any anywhere anywhere
0 0 ufw-before-forward all -- any any anywhere anywhere
0 0 ufw-after-forward all -- any any anywhere anywhere
0 0 ufw-after-logging-forward all -- any any anywhere anywhere
0 0 ufw-reject-forward all -- any any anywhere anywhere
0 0 ufw-track-forward all -- any any anywhere anywhere
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
8 416 DOCKER-USER all -- any any anywhere anywhere
8 416 DOCKER-ISOLATION-STAGE-1 all -- any any anywhere anywhere
0 0 ACCEPT all -- any docker0 anywhere anywhere ctstate RELATED,ESTABLISHED
4 256 DOCKER all -- any docker0 anywhere anywhere
4 160 ACCEPT all -- docker0 !docker0 anywhere anywhere
0 0 ACCEPT all -- docker0 docker0 anywhere anywhere
0 0 ufw-before-logging-forward all -- any any anywhere anywhere
0 0 ufw-before-forward all -- any any anywhere anywhere
0 0 ufw-after-forward all -- any any anywhere anywhere
0 0 ufw-after-logging-forward all -- any any anywhere anywhere
0 0 ufw-reject-forward all -- any any anywhere anywhere
0 0 ufw-track-forward all -- any any anywhere anywhere
パケットがforwardテーブルにヒットする理由は、dockerがnatテーブルに追加するルールによるものです。
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
210 12734 DOCKER all -- any any anywhere anywhere ADDRTYPE match dst-type LOCAL
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- docker0 any anywhere anywhere
0 0 DNAT tcp -- !docker0 any anywhere anywhere tcp dpt:https to:172.17.0.2:443
107 6848 DNAT tcp -- !docker0 any anywhere anywhere tcp dpt:http to:172.17.0.2:80
nat/PREROUTINGは、パケットをINPUTまたはFORWARDのどちらで処理するかを決定する前に処理されます。
最終的に問題となるのは、システム上でファイアウォールルールを変更する2つのサービスがあることです。ufwはこれらを認識していないため、自分が設定したことしか報告できません。
これに対する解決策は、docker宛てのトラフィックもufwチェーンを通過するようにファイアウォールを再設定することです。
私は、ufwを有効にする前に、彼らの作業をわずかに適応させたものを使用しています。
# https://github.com/chaifeng/ufw-docker から盗用 - 合理的に見える
# forwardをufw-user-inputに追加すると、明示的に開いたポートに転送された接続が
# 可能になります
cat <<EOUFW >> /etc/ufw/after.rules
# BEGIN UFW AND DOCKER
*filter
:ufw-user-forward - [0:0]
:ufw-user-input - [0:0]
:DOCKER-USER - [0:0]
-A DOCKER-USER -j RETURN -s 10.0.0.0/8
-A DOCKER-USER -j RETURN -s 172.16.0.0/12
-A DOCKER-USER -j RETURN -s 192.168.0.0/16
-A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN
-A DOCKER-USER -j ufw-user-forward
-A DOCKER-USER -j ufw-user-input
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 10.0.0.0/8
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 172.16.0.0/12
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 192.168.0.0/16
-A DOCKER-USER -j RETURN
COMMIT
# END UFW AND DOCKER
EOUFW
ありがとうございます。完全な説明でした。
ようこそ、それが私のやり方です ![]()
このトピックは解決しましたが、私のセットアップに関する1つのマイナーな問題が明らかになりました。将来、同様のものを検索する人がいれば説明します。
Nginxが私のすべてのサイト(たくさんのオフ、英語は非常に奇妙な言語です ;))のSSLとその他の処理を担当するVPSが1つありました。NginxはVarnishにリクエストを送信します。Discourseにとっては無用なリバースプロキシですが、いくつかのフィルタリングを行います。Varnishは、Discourseが存在する別のVPSにポート83を使用してリクエストを送信します。両方のVPSは同じポートをリッスンしており、両方のIPのみが許可されています。今まで、私は完全に満足していました。
ポート443 curl -I https://forum.example.tld:443 を使用した場合に何が起こるかを試しました。Discourse側でまだ有効なSSL証明書を持っていたため、うまく機能しました(数週間前にこの変更を行いました)。
@supermathie の回答は、これがなぜ起こるのか、そしてそれを修正する方法を説明しています。もちろん、それによるセキュリティ上の問題は一切ありませんが、非常に迷惑です😝
すごい。それはクレイジースタッフですね!ありがとうございます。
おそらく、Discourseをインストールして、それが機能しないようにしたい人がほとんどいないため、質問されないのでしょう。Dockerが、ファイアウォールを設定したにもかかわらず機能させてしまうと、ほとんどの人は文句を言いません。![]()
非常に興味深い問題ですが、少し難解であり、Discourseの問題ではなく、Dockerの癖です。質問は「ファイアウォールを設定してDiscourseを機能しないようにするにはどうすればよいか?」という問題に集約されます。そのプリルーティングの件を覚えておこうと思います。
もし答えを知っていたら、軽視するような口調にはならなかったでしょう!
今回はこれで助かりました!
軽視するつもりは全くなく、むしろトラブルシューティングを試みていましたが、明らかにDockerが何をしているのかを知らない状態でした。非常に役立つ情報です、回答ありがとうございます!
もしOPまたは他の誰かが変更できるなら、マークされたソリューションを変更する価値があるかもしれません。
これはDockerの問題ですが、これに起因するDiscourseの仮想的なシナリオがいくつか考えられます。例えば、外部からアクセス可能なオフィスサーバーがあるが、Discourseをオフィス内からのみアクセスできるようにUFWを設定したい場合があります。Dockerの追加機能は、そのセットアップを妨げるでしょう。
ただし、その特定のシナリオでは、ハードウェア/ハイパーバイザーファイアウォールで設定し、ホスト上のUFWではなく、そちらを使用するでしょう。
同じgitリポジトリにたどり着きました。ufw/dockerの問題を調べていたのですが、このトピックのことを思い出しました。
具体的に何を変更しましたか(追加された行はわかりますが、それが何を意味するのか?)、そしてこれらの変更はDiscourse専用ですか?
リポジトリのデフォルトコードを使用したところ、ufwの問題はその後修正されたようです。
編集:編集されたコードを使用すると、最初にufw reloadを実行したときに次のエラーが発生します。
エラー:ロギングルールをロードできませんでした
しばらくして自分で解決し、Discourse のインストール用にこの bash スクリプトを作成しました。
ファイアウォールをリセットし、ufw-docker-util (after.rules を編集します) をインストールしてから、ポート 443 と 80 を許可リストに追加します。これで完了です。
また、ロックアウトされないように、ポート 22 を任意の IP から許可します。すべてが機能した後、ポート 22 を再度保護します。
編集: スクリプトは機能しますが、使用後に Discourse を再構築すると失敗します:
fatal: unable to access 'https://github.com/discourse/discourse.git/': Could not resolve host: github.com- このため、これを解決する方法がわからない限り、スクリプトを使用しないでください。
編集 2: Ubuntu では機能しますが、CentOS では機能しません!
以前bashスクリプトを実行した際に、すべてのディレクトリの所有者をwww-data:www-dataに変更しました。そのため、このような作業は私の生活を少し楽にしてくれます ![]()
しかし、一般的にはDockerがUFW/iptablesに完全に追従することを望みます。なぜなら、私はiptables経由でGeoIPブロッキングを使用しているからです(ええ、わかっています — UFWはiptablesのミニマリストUIにすぎません)。
もちろん、私たちはもうDiscourseにはいませんが、ここではコーダーとエンドユーザーが常に互いをよく理解できない理由を見ることができます。コーダーは世界を論理的なブロック、if/then/elseの構築として見ていますが、エンドユーザーはそれを完全なコンテキストとして見ています。つまり — Discourseを使用しているため、たとえDocker内で動作していても、私の視点からは、私のルールに従わないのはDiscourseなのです ![]()
これは#praiseに送られるべきですが、数週間前にフォーラムのURLを変更しました。そして、世界のすべてのスクリプトキディと役に立たないSEOボットが訪問するようになりました。DigitalOceanの2GB/1vCPU VPSで、1時間あたり3000の異なるユーザーエージェントを取得しましたが、Discourseはまったく気にしませんでした。そのようなDDoSのようなラッシュの後、WordPressのインストールは遅くなるかダウンするでしょう。
ですから、Discourse(まあ、Docker)にFail2banや私のルールによる禁止に従うことを強制する必要はありませんが、それらのボットは非常に嫌いです。