Securing SSH access is crucial for any Linux server. SSH allows remote command line access, so leaving it unprotected opens your server up to attacks. UFW (Uncomplicated Firewall) makes it easy to limit SSH access as a barrier against brute force attacks. In this comprehensive guide, we‘ll cover how UFW works, the benefits of limiting services, and step-by-step instructions to properly limit SSH access.
An Introduction to UFW
UFW stands for Uncomplicated Firewall. It‘s the default firewall tool in Ubuntu and Debian-based Linux distributions. The key benefit of UFW is its simple interface. You don‘t need extensive networking knowledge to use it effectively.
Under the hood, UFW is just a frontend for the netfilter/iptables firewall included in the Linux kernel. It abstracts away many complex aspects of iptables rules into a straightforward syntax. For example, this command allows SSH access through UFW:
sudo ufw allow ssh
That single UFW command translates into these iptables rules:
iptables -A ufw-user-input -p tcp --dport 22 -j ACCEPT
iptables -A ufw-user-input -p udp --dport 22 -j ACCEPT
iptables -A ufw-user-output -p tcp --sport 22 -j ACCEPT
iptables -A ufw-user-output -p udp --sport 22 -j ACCEPT
As you can see, UFW makes managing firewall rules much simpler. Now let‘s look at how we can limit services like SSH to prevent attacks.
The Benefits of Limiting Services
Limiting a service like SSH in UFW means restricting the number of parallel connections. For example, you could limit SSH to a maximum of 6 connections over 30 seconds from a single IP address. Any connections above that would get dropped by the firewall.
This technique helps prevent brute force credential attacks. Attackers often try to guess weak login passwords by using scripts to throw hundreds of combinations at a server. But if you limit SSH connections per IP, it blocks the rapid connection attempts that brute forcing relies on.
Limiting is also less restrictive than completely blocking an IP address. For instance, if you accidentally leave FTP open and get scanned by an attacker, limiting would slow them down without fully denying access. Permanent IP blocking could cause issues for legitimate users sharing the same IP.
Limiting SSH Connections with UFW
Limiting a service in UFW just takes a single command. Make sure UFW is enabled and allowing SSH first:
sudo ufw enable
sudo ufw allow ssh
Now limit SSH connections to a maximum of 6 every 30 seconds:
sudo ufw limit ssh
The default threshold values are:
- 6 connections
- Over 30 seconds
- From a single IP address
So any IP making more than 6 SSH connections within a 30 second period would get firewalled. Those numbers provide a reasonable threshold before triggering rate limiting.
You can customize them as well though. Here‘s an example allowing 10 SSH connections per minute:
sudo ufw limit ssh/tcp --limit 10/min
Now let‘s verify the SSH ruleset after applying connection limiting:
sudo ufw status
Status: active
To Action From
-- ------ ----
22 LIMIT Anywhere
22 (v6) LIMIT Anywhere (v6)
The limit action is shown for SSH traffic over both IPv4 and IPv6. Limiting has been successfully applied!
Using GUFW to Limit SSH Graphically
GUFW provides a graphical interface for UFW. That gives you more precision when creating firewall rules. Let‘s look at how to limit SSH access with GUFW rather than the command line.
First, install GUFW:
sudo apt install gufw
Launch the application with:
sudo gufw

Click on the "Rules" button to manage firewall policies. Next, click the + sign to add a new rule.
Fill out the rule details like so:
- Policy: Limit
- Network Category
- Service Subcategory
- Application Filter: ssh
And click "Add" to create the rule.

Now ssh will be rate limited, just as if we used the ufw limit ssh command!
Using the graphical interface allows more precision in defining rules. But for simple rate limiting, the ufw command line works perfectly fine.
Confirming the SSH Limit Rules in iptables
As mentioned earlier, UFW is essentially a frontend for iptables firewall rules. We can verify that directly in iptables to validate the limit policy was applied properly:
sudo iptables -L -n -v
Chain INPUT (policy ACCEPT 399 packets, 23766 bytes)
pkts bytes target prot opt in out source destination
512 30520 ufw-user-input tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 state NEW
512 30520 ufw-user-input udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:22 state NEW
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 411 packets, 125692 bytes)
pkts bytes target prot opt in out source destination
Chain ufw-after-input (1 references)
pkts bytes target prot opt in out source destination
Chain ufw-after-output (1 references)
pkts bytes target prot opt in out source destination
Chain ufw-before-input (1 references)
pkts bytes target prot opt in out source destination
Chain ufw-before-output (1 references)
pkts bytes target prot opt in out source destination
Chain ufw-reject-input (1 references)
pkts bytes target prot opt in out source destination
Chain ufw-reject-output (1 references)
pkts bytes target prot opt in out source destination
Chain ufw-track-input (1 references)
pkts bytes target prot opt in out source destination
0 0 SET tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 state NEW recent: SET name: DEFAULT side: source mask: 255.255.255.255
512 30520 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 state NEW recent: UPDATE seconds: 30 hit_count: 6 name: DEFAULT side: source mask: 255.255.255.255
Chain ufw-track-output (1 references)
pkts bytes target prot opt in out source destination
Focus on these lines:
0 0 SET tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 state NEW recent: SET name: DEFAULT side: source mask: 255.255.255.255
512 30520 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22 state NEW recent: UPDATE seconds: 30 hit_count: 6 name: DEFAULT side: source mask: 255.255.255.255
That implements the rate limiting logic in iptables by:
- Creating a list to track sources
- Allowing connections if under 6 within 30 seconds
- Dropping connections over that threshold
So UFW did in fact translate our simple limit command into the appropriate iptables ruleset behind the scenes!
Wrapping Up
Limiting SSH connections with UFW provides powerful protection against brute force attacks. It‘s more flexible than fully blocking IPs while still acting as deterrent against rapid scans.
UFW makes it easy to implement this rate limiting firewall feature. Both the command line and graphical tools like GUFW offer simple interfaces. Yet UFW tapped into advanced connection tracking and filtering capabilities of iptables under the hood.
I hope this guide was helpful for learning how to properly limit SSH access! Let me know if you have any other questions about securing services with UFW.


