UFW on an Ubuntu VPS: open, close and check ports safely
TL;DR: UFW (Uncomplicated Firewall) is the front end Ubuntu uses to manage its Linux firewall. The safe pattern is: deny all incoming traffic by default, allow only SSH, HTTP and HTTPS, add narrow rules for anything else, and enable the firewall last. Always allow SSH before you enable UFW, and keep your current session open while you test a second one. For services such as VNC or databases, restrict access to your own IP or use an SSH tunnel instead of opening the port to the internet. Be aware that Docker can publish ports in a way that bypasses UFW.
What UFW does and does not do
UFW sits on top of the kernel's packet filtering and turns a long, error-prone rule syntax into short commands. It filters traffic by port, protocol and address, which is exactly what most small servers need.
It does not replace other security measures. A firewall limits which ports are reachable, but it cannot fix a vulnerable application on an open port. Combine it with SSH hardening and fail2ban, and keep software patched.
The safe order of operations
The classic mistake is enabling a firewall that blocks SSH while you are connected over SSH. Follow this order and you will not lock yourself out.
- Check the current state.
sudo ufw status verbose
- Set sensible defaults. Block everything incoming, allow everything outgoing.
sudo ufw default deny incoming
sudo ufw default allow outgoing
- Allow SSH first. If you moved SSH to another port, use that port instead of 22.
sudo ufw allow OpenSSH
- Allow web traffic if the server hosts a site.
sudo ufw allow 80,443/tcp
- Enable the firewall.
sudo ufw enable
- Test from a second terminal before you close the first. Open a new SSH connection. If it works, you are safe. If it does not, fix it in the original session.
If you ever lock yourself out, most providers offer a web console that bypasses SSH, which lets you correct the rules.
Rules most servers need
For a typical web server, the full rule set is short:
| Purpose | Command |
|---|---|
| SSH | sudo ufw allow OpenSSH |
| HTTP and HTTPS | sudo ufw allow 80,443/tcp |
| SSH with brute-force rate limiting | sudo ufw limit OpenSSH |
| Custom SSH port, for example 2222 | sudo ufw allow 2222/tcp |
The limit rule denies connections from an address that tries to connect six or more times within thirty seconds, which slows basic brute-force attempts. It complements, rather than replaces, key-based SSH logins.
Opening a port for one IP only
When something needs a port reachable but only by you, restrict the rule to your address:
sudo ufw allow from 203.0.113.4 to any port 5432 proto tcp
Replace 203.0.113.4 with your own IP and the port with the service you need. This is the right pattern for administrative tools, database ports and internal APIs. If your home or office IP changes, the rule stops matching, so keep a way in that does not depend on it.
For a range, use CIDR notation, such as 192.0.2.0/24.
Services you should not expose: VNC and databases
People often search for how to allow VNC through the firewall on Ubuntu. VNC usually listens on port 5900 or 5901 and is a common attack target, so avoid opening it to the whole internet. There are two safer options:
Restrict to your IP:
sudo ufw allow from 203.0.113.4 to any port 5901 proto tcp
Better: use an SSH tunnel and open nothing. From your computer:
ssh -L 5901:localhost:5901 user@your-server
Then point the VNC client at localhost:5901. The traffic travels inside the encrypted SSH connection, and the VNC port stays closed to the world.
The same logic applies to MySQL (3306), PostgreSQL (5432), Redis (6379) and similar. They should listen on localhost, or be reachable only from specific IPs, not open to everyone.
Checking, removing and reloading rules
List rules with numbers so you can remove the right one:
sudo ufw status numbered
sudo ufw delete 3
You can also delete by repeating the rule with delete in front:
sudo ufw delete allow 80/tcp
After editing configuration files, reload without dropping the firewall:
sudo ufw reload
To confirm what is actually listening on your server, regardless of the firewall, run sudo ss -tulpn. Anything listening publicly that you do not recognise deserves investigation. UFW also logs blocked connections once you enable logging with sudo ufw logging on, which helps when you wonder why a connection fails.
Also check that IPv6 handling matches your needs. In /etc/default/ufw, IPV6=yes makes UFW apply rules to IPv6 as well, which you want if your server has an IPv6 address.
The Docker gotcha
Docker writes its own firewall rules when you publish a container port, for example with -p 8080:80. Those rules can take effect before UFW's, which means a published port may be reachable from the internet even though UFW shows it as blocked.
Ways to deal with it:
- Bind published ports to localhost, for example
-p 127.0.0.1:8080:80, and put Nginx in front. - Publish only the ports you truly need.
- Test from outside, using a port scan or a device on another network, rather than trusting
ufw status.
This catches many people out, and it is worth reviewing before you run databases or dashboards in containers. See our notes on Docker Compose on a small VPS.
Provider firewalls and the Windows question
Many VPS providers also offer a network-level firewall or security group outside your server. If both exist, a port must be allowed in both, and a mismatch is a common reason a service seems unreachable. Check the provider panel when a UFW rule does not seem to work.
You may also see questions about allowing a website through Windows Firewall. That is a different tool on a different operating system, managed through Windows Defender Firewall settings. UFW applies only to Ubuntu and Debian-family Linux servers. If your server runs Windows, see our comparison of Windows hosting vs Linux hosting.
Once the firewall is in place, work through the rest of the first ten things to do on a new Linux VPS.
FAQs
Will enabling UFW disconnect my SSH session?
Not if you allowed SSH first. Existing connections are normally preserved, but test a new connection before you close the old one.
Which ports should be open on a web server?
Normally only SSH, 80 and 443. Everything else should stay closed unless you have a specific reason.
Is UFW enough to secure my server?
No. It limits exposure but does not patch software or stop attacks on open services. Use it with SSH hardening, fail2ban, updates and backups.
How do I open a port for a specific IP?
Use sudo ufw allow from <ip> to any port <port> proto tcp, replacing the address and port.
Why can I still reach a Docker container even though UFW blocks the port?
Docker adds firewall rules that can bypass UFW. Bind the published port to localhost, or use a reverse proxy.
How do I see which ports are open to the internet?
Run sudo ss -tulpn to see listening services and sudo ufw status verbose for the rules, then confirm with a scan from outside the server.
I locked myself out. What now?
Use your provider's web console to log in, then fix the rule or disable UFW with sudo ufw disable, correct the configuration and enable it again.
Should I change the default SSH port?
It reduces noise from automated scans but is not a security measure on its own. If you change it, allow the new port in UFW before restarting SSH.
Conclusion
UFW is simple enough to set up in minutes: deny by default, allow SSH first, open only what you need, enable it last and test from a second session. Restrict sensitive ports by IP or tunnel them over SSH, and remember that Docker can bypass the rules you think are protecting you.
A correct firewall is one layer. HostCloud's VPS plans give you the root access to build the rest. See https://hostcloud.in.
Sources:
