Introduction / Why This Is Needed
UFW (Uncomplicated Firewall) is an easy-to-use interface for managing iptables on Linux. It's ideal for quickly setting up basic protection for a server or workstation without diving into complex iptables rules. With this guide, you'll configure a firewall in 10-15 minutes that will block unwanted incoming traffic and allow only the connections you permit (e.g., for a web server or SSH).
After completing this guide, you will have a working firewall with default rules and the necessary ports open.
Prerequisites / Preparation
Before you begin, ensure that:
- You have access to a Linux terminal (Ubuntu, Debian, Mint, or derivatives).
- You have sudo (administrator) privileges.
- Critically important: An existing SSH connection to the server is already established, and you do not plan to interrupt it before configuring the SSH rules. Otherwise, you may lose access to the server.
- You know which ports and protocols must be open for your services (e.g.,
22/tcpfor SSH,80/tcpfor HTTP,443/tcpfor HTTPS).
Step 1: Installation and Pre-Approval for SSH
UFW is usually pre-installed on Ubuntu/Debian. If it's not present, install it:
sudo apt update
sudo apt install ufw -y
Important: Before enabling the firewall, immediately allow the SSH port (default 22). This ensures your active SSH connection won't be dropped when the firewall activates.
# Allow incoming connections on port 22 (SSH) from any IP
sudo ufw allow ssh
# Or explicitly specify the port and protocol (if SSH listens on a non-standard port)
# sudo ufw allow 2222/tcp
Step 2: Configuring Default Policies
Set a "deny" policy for incoming traffic and an "allow" policy for outgoing traffic. This is a security foundation: anything not explicitly allowed is denied.
# Deny all incoming connections by default
sudo ufw default deny incoming
# Allow all outgoing connections by default (the server can initiate network connections)
sudo ufw default allow outgoing
💡 Tip: Using a
deny outgoingpolicy is not recommended for most servers, as it will break package manager functionality (apt update), DNS queries, and updates.
Step 3: Adding Rules for Your Services
Add rules for each port/service that must be accessible from outside. Below are examples for a typical web server.
# HTTP (port 80)
sudo ufw allow http
# HTTPS (port 443)
sudo ufw allow https
# If database access (e.g., MySQL) is needed ONLY from a specific IP:
# sudo ufw allow from 10.0.0.5 to any port 3306
# Allow ping (ICMP) — optional, for diagnostics
sudo ufw allow icmp
Review the added rules:
sudo ufw status numbered
The output will look similar to:
Status: active
Logging: off
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
80/tcp ALLOW Anywhere
443/tcp ALLOW Anywhere
Step 4: Activating the Firewall
After verifying all rules, activate UFW:
sudo ufw enable
The system will ask for confirmation. Confirm, and the firewall will start working immediately.
⚠️ Important: If you forgot to add the SSH rule (
allow ssh) before runningufw enable, your current SSH connection may be terminated. In that case, you will need access through your VPS control panel console or KVM.
Step 5: Management and Verification
Checking Status
sudo ufw status verbose
Shows detailed information, including default policies and outgoing rules.
Viewing Logs (if enabled)
Enable logging for debugging (set level low or medium):
sudo ufw logging low
Logs will be in /var/log/ufw.log (or accessible via journalctl -u ufw).
Deleting/Modifying a Rule
- Find the rule number via
sudo ufw status numbered. - Delete a rule by its number:
sudo ufw delete 3 - To modify a rule, delete the old one and add a new one.
Disabling the Firewall (last resort)
sudo ufw disable
Do not do this on a production server without extreme necessity!
Verifying the Result
- Local Check: From the server itself, confirm the firewall is active:
sudo ufw status
Should showStatus: active. - External Check: Try connecting to the open ports (SSH, HTTP, HTTPS) from another computer. Connections should succeed.
- Checking Closed Ports: Try connecting to a port you did not allow (e.g., 3306 if MySQL wasn't opened). The connection should be rejected (timeout or "connection refused").
- Viewing Rules in iptables (for confirmation):
sudo iptables -L -n -v
You will see chains created by UFW (ufw-user-input, etc.).
Common Issues
❌ "Connection timed out" after enabling UFW
Cause: The SSH rule was not added before ufw enable, or you connected from an IP not allowed (if the allow ssh rule is IP-restricted).
Solution:
- Gain access via your VPS provider's console or KVM.
- Add a rule for your current IP:
sudo ufw allow from <your_IP> to any port 22. - Reconnect.
❌ Rule not applied, port still closed
Cause: Possible conflict with another rule (a later deny rule overrides allow). Or the service is listening only on 127.0.0.1, not 0.0.0.0.
Solution:
- Check rule order:
sudo ufw status numbered. Rules are evaluated top-down. - Ensure the service (e.g., nginx) is listening on all interfaces:
sudo ss -tulpn | grep :80. - If needed, delete the conflicting rule and re-add it.
❌ Package manager (apt update) fails with errors
Cause: By default, ufw default allow outgoing permits all outgoing connections. If you changed the policy to deny outgoing, DNS queries and HTTP access to repositories will be blocked.
Solution: Revert to the allow outgoing policy or create explicit rules for DNS (port 53) and HTTP/HTTPS to repository addresses.
❌ UFW logs are not being written
Cause: Logging is disabled or the level is set too high (errors only).
Solution: sudo ufw logging low (logs all blocks). Check the file /var/log/ufw.log or run sudo tail -f /var/log/ufw.log.
Advanced Scenarios (Brief)
Blocking a Specific IP
sudo ufw deny from 192.0.2.100
Will block all incoming connections from that address.
Connection Limiting (Brute-Force Protection)
# Limit SSH: max 6 connections per 30 seconds from one IP
sudo ufw limit ssh
UFW automatically creates rules using the conntrack module.
Allowing a Port Range
# Allow ports 6000-6010 (e.g., for X11 forwarding)
sudo ufw allow 6000:6010/tcp
Deleting by Number (for complex rules)
# Rule: deny 80/tcp from IP 1.2.3.4
sudo ufw status numbered
# Output: 3 DENY IN 80/tcp FROM 1.2.3.4
sudo ufw delete 3
Conclusion
You have successfully configured a basic UFW firewall on your Linux server. Key takeaways:
- Always add the SSH rule before enabling the firewall.
- Use the
deny incomingdefault policy. - Only open the ports that are strictly necessary for your services to function.
- For fine-tuning (e.g., different rules for different interfaces), you may need to switch to raw
iptablesornftables.
UFW is excellent for 80% of server protection scenarios. For more complex cases (transparent proxies, complex routing), explore iptables or nftables.