Limit SSH access by IP address
This article describes how to specify which IP addresses can reach the SSH daemon on your server.
Note: All of the methods described here can result in inadvertently blocking yourself or other important traffic from reaching your server. Please exercise care.
Blocking SSH Traffic Before it Reaches Your Server
Ideally, IP address limitations should be implemented before the unwanted traffic even reaches your server:
- If you have a hardware firewall, see Add an access-list rule with Firewall Manager v2
- If you are using one of our cloud platforms, you can limit traffic via a platform-based firewall:
- On SDDC Flex, see Configure and manage networks
- On OpenStack Flex, see Creating a Rackspace OpenStack Flex Network
- On OpenStack Public Cloud, see Using security groups
Blocking SSH Traffic at Your Server
If you are unable to block unwanted traffic before it reaches your server, Linux has several facilities for limiting which IP addresses can connect to your SSH daemon. This article will present two different approaches:
- A "permissive" configuration that allows all but known malicious IP addresses.
- A "restrictive" configuration that allows only trusted IP addresses.
It is generally safer to use the "restrictive" configuration if possible.
Permissive Configuration
The permissive configuration allows access to everyone except the specified IP addresses.
iptables
For a permissive configuration place your iptables rules to drop traffic from specific IP addresses before your rule to allow all (other) SSH traffic.
# iptables -A INPUT -s 192.168.0.3 -p tcp --dport 22 -j DROP
# iptables -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
# service iptables save
# iptables -L
UFW
For a permissive configuration place your UFW rules to deny specific IP addresses before your rule to allow all (other) SSH traffic.
# ufw deny proto tcp from 192.168.0.3 to any port 22
# ufw allow ssh
# ufw status numbered
Firewalld
There are various ways to build a permissive configuration with Firewalld. A simple way is to add the SSH service and all unwanted IP addresses to the "drop" zone then add the SSH service to the default zone (usually "public").
# firewall-cmd --permanent --add-source=192.168.0.3 --zone=drop
# firewall-cmd --permanent --add-service=ssh
# firewall-cmd --reload
# firewall-cmd --list-all --zone=drop
# firewall-cmd --list-all
/etc/ssh/sshd_config
You can configure the SSH daemon itself to create a permissive configuration (see man 5 sshd_config
for details). To do this you need to add a "Match Address" block to the end of /etc/ssh/sshd_config to override aspects of the main configuration. In this case, we will be disabling login methods for unwanted IP addresses.
# Put this at the end of /etc/ssh/sshd_config to block unwanted IP addresses
Match Address 192.168.0.3
PasswordAuthentication no
PubkeyAuthentication no
After making these changes, use sshd -t
to check for syntax errors, then restart your SSH server daemon (systemctl reload sshd
on RedHat or systemctl restart ssh
on Debian/Ubuntu).
Restrictive Configuration
This configuration allows only specific IP addresses and drops other incoming SSH traffic.
iptables
For a restrictive configuration place your iptables rules to allow specific IP addresses before your rule to drop all (other) SSH traffic.
# iptables -A INPUT --source 192.168.0.8 -p tcp --dport 22 -j ACCEPT
# iptables -A INPUT -p tcp -m tcp --dport 22 -j DROP
# service iptables save
# iptables -L
UFW
For a restrictive configuration place your UFW rules to allow specific IP addresses before your rule to deny all (other) SSH traffic.
# ufw allow proto tcp from 192.168.0.8 to any port 22
# ufw deny ssh
# ufw status numbered
Firewalld
There are various ways to build a restrictive configuration with Firewalld. A simple way is to add the SSH service and all trusted IP addresses to the "trusted" zone then remove the SSH service from the default zone (usually "public").
# firewall-cmd --permanent --add-service=ssh --zone=trusted
# firewall-cmd --permanent --add-source=192.168.0.8 --zone=trusted
# firewall-cmd --permanent --remove-service=ssh
# firewall-cmd --reload
# firewall-cmd --list-all --zone=trusted
# firewall-cmd --list-all
/etc/ssh/sshd_config
You can configure the SSH daemon itself to create a restrictive configuration (see man 5 sshd_config
for details). To do this you disable logins in the main body of /etc/ssh/sshd_config then add a "Match Address" section to the end so trusted IP addresses can login.
# Disable logins in the main body of /etc/sshd_config
PasswordAuthentication no
PubkeyAuthentication no
# Put this at the end to allow trusted IP addresses to login
Match Address 192.168.0.8
PasswordAuthentication yes
PubkeyAuthentication yes
After making these changes, use sshd -t
to check for syntax errors, then restart your SSH server daemon (systemctl reload sshd
on RedHat or systemctl restart ssh
on Debian/Ubuntu).
Updated 11 days ago