これは実際には非常に良い質問であり、他の誰もまだ尋ねていないことに驚いています。答えは複雑ですが、これまでのところ、このトピックに関する回答は、質問に答えることなく、残念ながら軽視するようなトーンでした。
Discourseがufwをバイパスしているわけではなく、dockerがufwをバイパスして、ufwが存在してもdockerコンテナの公開ポートが機能するようにルールを追加しているのです。
何が起こっているのか?
コンテナ宛ての着信パケットは、予想されるかもしれないINPUTテーブルではなく、FORWARDテーブルにヒットします。
dockerインストール前
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
dockerインストール後
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