iptables SSH – How to Allow Access from Specific IP Only

iptablesssh

I would like to setup iptables rules on remote server in that manner that I am able to access to it only from specific IP address.

The current iptables list looks like this:

root@localhost:~# iptables --list
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     tcp  --  1.2.3.4                 anywhere             tcp dpt:ssh
ACCEPT     tcp  --  2.2.2.2                 anywhere             tcp dpt:ssh
DROP       tcp  --  anywhere                anywhere             tcp dpt:ssh

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain l (0 references)
target     prot opt source               destination

Where 1.2.3.4 and 2.2.2.2 are the IP destinations from where I want to have access to this machine.
And all that works fine. If i type:

ssh root@server-ip-address-here

i have access only from those 2 locations. Any other location is encountering timeout and its not able to reach port 22.

The thing is, i have a domain associated with this server/ip for example, example.com.

Now, what puzzles me is, if i try to access to the ssh using the domain name, im able to reach the port without any kind of issues??

ssh root@example.com
  1. Are you able to explain why this is happening? I was expecting different behaviour (DNS will resolve domain to IP, ssh will try to use that IP to reach the port and it will be blocked).
  2. How i can fully block ssh access (tcp connection) on port 22, for other sources beside those 2 ips (no matter how they try to reach the port)?

Best Answer

The best rule for setting access to your server from a known IP is:

sudo iptables -A INPUT -p tcp -s IP-ADDRESS --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

And in case you wish to change your OUTPUT chain to DROP or REJECT, then you would need the following rule too:

sudo iptables -A OUTPUT -p tcp --sport 22 -m conntrack --ctstate ESTABLISHED -j ACCEPT

But your rule seems to be ok.

If you are connecting to a domain (domain.com for ex.) and reaching a ssh server, you should check if you have set a CDN or reverse proxy for the domain which doesn't have the iptables rule droping the connection. Also a firewall doing NAT could cause a response if that port is not forwarded and the firewall has the ssh service enabled, or anything in the middle between your client and server that has an ssh server running as a matter of fact. Most likely it is the ssh-server of another device, or you have something wrong with your network/setup.

Update after ipv6 comment

If you are using ipv6 you should check the ipv6 rules for iptables:

sudo ip6tables -L

You have, at least, 2 options:

1) If you are allowing everything, you can restrict to the ipv6 address of the ipv4 devices that you are allowing (notice the IPv6-ADDRESS) for the ssh service:

sudo ip6tables -A INPUT -p tcp -s IPv6-ADDRESS --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT

2) Or directly DROP everything coming from IPv6 by default:

sudo ip6tables -P INPUT DROP
sudo ip6tables -P FORWARD DROP