Ssh – iptables unable to block local ssh connection

iptablesnetworkingssh

Here is my question: Why is iptables unable to prevent SSH from connecting to localhost?

A more detailed description follows.

During a process of experimentation with iptables I came across the following curiosity that I'd like to understand. Even when I set every policy to DROP, I'm still able to access the machine locally via SSH.

Here is what I'm doing.

First I use iptables to set all POLICY values to DROP:

cat <<HEREDOC | sudo iptables-restore

*filter
:INPUT DROP
:FORWARD DROP
:OUTPUT DROP
COMMIT

*mangle
:PREROUTING DROP
:INPUT DROP
:FORWARD DROP
:OUTPUT DROP
:POSTROUTING DROP
COMMIT

*nat
:PREROUTING DROP
:POSTROUTING DROP
:OUTPUT DROP
:INPUT DROP
COMMIT

*raw
:PREROUTING DROP
:OUTPUT DROP
COMMIT
HEREDOC

Then I try to connect via SSH:

ssh localhost

And, much to my surprise, this works! I'm presented with a new shell session as if there were no firewall. As a sanity check I then try to ping localhost, which results in the following error message:

ping: sendmsg: Operation not permitted

This seems to suggest that the firewall is in fact operational. Finally I try to SSH using an IP address

ssh 127.0.0.1

This hangs, as I would have expected.

So my best guest is that SSH is doing something differently when it's passed the string "localhost" as an argument – something that doesn't actually involve the loopback interface. If this is in fact the case then my question becomes, "What exactly is ssh doing?"

Best Answer

Most probably, localhost resolves to an IPv6 address (::1) which is not filtered by iptables (use ip6tables).

The output of:

strace -e connect ssh localhost

will tell you what IP address and what protocol are used.

Related Question