iptablesルールを適用するとSSHセッションが失われる

iptablesルールを適用するとSSHセッションが失われる

SSH と iptables だけでは説明できない問題があります。簡単に言うと、リモート ホスト (Ubuntu 18.04 を実行) に SSH で接続し、iptables ルールを適用するスクリプトを実行すると、実行中の SSH セッションが失われます。再度接続することはできますが、実行中のセッションは失われます。

スクリプトはコマンドを使用して iptables ルールをフラッシュしnetfilter-persistent flush、次の形式でこのルールセットを適用しますiptables-save

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -m state --state INVALID -j DROP
-A INPUT -s x.x.x.x/XX -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j LOG --log-prefix "INPUT DROP: "
-A FORWARD -j LOG --log-prefix "FORWARD DROP: "
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -m state --state INVALID -j DROP
-A OUTPUT -d x.x.x.x/XX -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A OUTPUT -d x.x.x.x/32 -p udp -m udp --dport 53 -j ACCEPT
-A OUTPUT -d x.x.x.x/32 -p udp -m udp --dport 123 -j ACCEPT
-A OUTPUT -d x.x.x.x/32 -p tcp -m tcp --dport 3128 -j ACCEPT
-A OUTPUT -j LOG --log-prefix "OUTPUT DROP: "
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

スクリプトが完了すると、セッションが失われ、両方向でブロックされた SSH パケットが表示されます/var/log/kern.log。接続追跡情報が失われた場合はこれが意味をなしますが、接続は引き続き確認できますconntrack -L(サーバーは VM なので、SSH 接続が失われた場合でも確認できます)。

さらに奇妙なことに、 を実行するとnetfilter-persistent flush && ./myscript接続は維持されますが、2 つのコマンドを続けて実行すると接続が失われます。また、VM TTY で 2 つのコマンドを実行しても、接続は失われません。

この動作を説明できる人はいますか?

答え1

デフォルトのポリシーは「DROP」に設定されています。

したがって、フラッシュしてからルールを追加するまでの間は、パケットは受け入れられず、接続が失われます...

スクリプトがルールの追加に失敗した場合は、お手上げです。

ポリシーを受け入れに設定し、一致しなかったものをすべてドロップするルールを (各チェーンの) 最後に追加する必要があります...

関連情報