
Your firewall shouldn’t feel like a black box. On a hosting VPS, you want rules that are dull, predictable, and easy to audit.
This UFW firewall setup tutorial shows a safe, hosting-friendly baseline for Ubuntu and Debian. It helps you avoid locking yourself out of SSH or breaking DNS, Let’s Encrypt, email, or your control panel.
The workflow below fits most web stacks. That includes WordPress, WooCommerce, PHP apps, small SaaS sites, and reseller servers.
If you run cPanel/WHM or a full mail stack, UFW still works well as a guardrail. You just need to open the ports your services actually use.
Before you touch UFW: a 5-minute safety checklist
- Console access: Confirm you can reach an out-of-band console (provider panel / rescue mode). On a VPS, make sure your host offers it.
- Know your SSH port: Default is 22, but many servers use 2222 or a custom port.
- Confirm your public IP: If you plan to allowlist SSH, verify the IP you’ll connect from.
- Inventory required ports: Web (80/443), SSH, and any panel or mail ports you truly use.
- Schedule a window: Even careful firewall changes deserve a maintenance window in production.
Ports you typically need on a hosting VPS (quick reference)
Use this as a starting point, not a checklist. Open only what you run.
- Web: 80/tcp (HTTP), 443/tcp (HTTPS)
- SSH: 22/tcp (or your custom port)
- DNS (only if you host DNS): 53/tcp and 53/udp
- Let’s Encrypt validation: HTTP-01 uses 80/tcp; TLS-ALPN-01 uses 443/tcp
- Email (only if you host email): 25/tcp, 587/tcp, 465/tcp, 143/tcp, 993/tcp, 110/tcp, 995/tcp
- Control panels (only if installed):
- cPanel: 2083/tcp, WHM: 2087/tcp, Webmail: 2096/tcp
- Plesk: 8443/tcp
- DirectAdmin: 2222/tcp
If you’re provisioning a fresh server, lock down access first.
Keep the base clean before you tighten firewall rules.
This pairs well with SSH key login and safe sshd hardening.
Step 1: Install UFW and confirm it’s inactive
On Ubuntu/Debian:
sudo apt update
sudo apt install -y ufw
sudo ufw status verbose
Before you add rules, you want Status: inactive.
If UFW is already active, capture what’s there first.
See the “Rollback” section.
Step 2: Set sensible defaults (deny inbound, allow outbound)
This is the baseline for most hosting servers.
Block unsolicited inbound traffic. Allow outbound connections for updates, APIs, monitoring, and DNS lookups.
sudo ufw default deny incoming
sudo ufw default allow outgoing
If you need strict egress control for compliance, add it later.
Do it carefully.
Egress rules can quietly break package updates, SMTP relays, object storage backups, and monitoring agents.
Step 3: Allow SSH first (two safe patterns)
Get SSH right before you enable anything.
Most self-lockouts happen here.
Pattern A: Allow SSH from anywhere (simple, safer for roaming admins)
sudo ufw allow 22/tcp comment 'SSH'
If you use a custom SSH port, replace 22.
Example:
sudo ufw allow 2222/tcp comment 'SSH'
Pattern B: Allowlist SSH to one or more admin IPs (tighter)
Use this if your office or VPN egress IP is stable.
ADMIN_IP="203.0.113.10"
sudo ufw allow from ${ADMIN_IP} to any port 22 proto tcp comment 'SSH from admin IP'
If your IP changes later, add the new allow rule before you remove the old one.
Step 4: Allow web traffic (HTTP/HTTPS) and verify
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
If you use Let’s Encrypt with HTTP-01 (the common path), keep 80 open.
You can run DNS-01 instead, but it adds moving parts.
For a practical TLS workflow, see our Let’s Encrypt deployment tutorial.
Step 5: Decide whether you host DNS (and open port 53 only if you do)
Most hosting servers use DNS but don’t provide DNS for others.
You only need inbound port 53 if your VPS is authoritative/recursive for external clients.
If you do host DNS
sudo ufw allow 53/tcp comment 'DNS TCP'
sudo ufw allow 53/udp comment 'DNS UDP'
If you manage your own zones and DNSSEC, you’re likely running BIND9 or similar.
This complements our BIND9 DNSSEC setup guide.
If you don’t host DNS
Do nothing.
Outbound DNS still works with the default “allow outgoing”.
Step 6: Add email ports only if the server handles mail
Mail ports attract abuse and noise.
Open the minimum you actually need.
A common baseline for a VPS that sends and receives mail directly:
sudo ufw allow 25/tcp comment 'SMTP inbound'
sudo ufw allow 587/tcp comment 'Submission'
sudo ufw allow 465/tcp comment 'SMTPS'
sudo ufw allow 143/tcp comment 'IMAP'
sudo ufw allow 993/tcp comment 'IMAPS'
If you run POP3, add 110/995.
If you relay outbound mail through a smart host (common for deliverability), you may not need inbound 25 at all.
Deliverability also depends on DNS and TLS alignment, not just open ports.
Keep this handy: email authentication setup (SPF/DKIM/DMARC/PTR).
Step 7: Control panel rules (cPanel/WHM, Plesk, DirectAdmin)
Panels are admin surfaces, not public services.
Expose only what’s required.
Restrict access to your admin IPs whenever you can.
cPanel/WHM (typical ports)
If your server uses cPanel:
# WHM
sudo ufw allow 2087/tcp comment 'WHM'
# cPanel
sudo ufw allow 2083/tcp comment 'cPanel'
# Webmail
sudo ufw allow 2096/tcp comment 'Webmail'
Tighter option (recommended): allowlist those ports to an admin IP range.
Keep them closed to the public internet.
If you go that route, plan a VPN or bastion/jump host for staff access.
Plesk
sudo ufw allow 8443/tcp comment 'Plesk'
DirectAdmin
sudo ufw allow 2222/tcp comment 'DirectAdmin'
Step 8: Enable UFW safely (and keep your SSH session open)
Before enabling, open a second SSH session.
Keep the original session connected while you test the new one.
sudo ufw status numbered
sudo ufw enable
You’ll get a warning prompt. Answer y.
Then confirm the state and what’s listening:
sudo ufw status verbose
sudo ss -tulpn | sed -n '1,30p'
From your workstation, test:
- SSH: connect again (new session) and ensure it succeeds
- HTTP:
curl -I http://YOUR_DOMAIN - HTTPS:
curl -I https://YOUR_DOMAIN
Step 9: Add rate-limited SSH rules (optional, good for noisy servers)
UFW can rate-limit new connections.
It won’t replace Fail2Ban, but it cuts down on brute-force noise.
sudo ufw limit 22/tcp comment 'Limit SSH brute-force'
If you already have an allow 22/tcp rule, remove it after adding the limit rule.
See “Rule cleanup”.
For better incident visibility, pair this with log monitoring and Fail2Ban basics.
Step 10: Turn on UFW logging (low volume, useful during changes)
Enable logging while you validate your rules.
If you don’t need it long-term, turn it back off later.
sudo ufw logging low
Check recent denies:
sudo journalctl -u ufw --no-pager -n 50 2>/dev/null || true
sudo tail -n 50 /var/log/ufw.log
Rule cleanup: keep the policy readable
Rules accumulate over time, especially on servers that change roles.
Use numbered output and delete what no longer applies.
sudo ufw status numbered
Delete by number (example deletes rule 3):
sudo ufw delete 3
A smaller ruleset is easier to audit.
It’s also faster to reason about during an incident.
Hosting-specific hardening patterns (the parts people skip)
Allowlist admin surfaces, not public traffic
Your sites usually need public 80/443.
Your admin surfaces usually don’t, including SSH and control panels.
If you have multiple admins, a jump host is often the cleanest compromise.
It reduces exposed ports across the fleet.
It also gives you one place to enforce MFA and auditing. See our SSH jump host setup guide.
Don’t open database ports to the internet
Even if a plugin insists it “needs” remote DB access, exposing 3306/5432 publicly is usually asking for trouble.
Bind databases to localhost or a private network.
Then use SSH tunnels or private subnets for remote access.
Remember IPv6 (or disable it deliberately)
If your VPS has IPv6, apply a consistent policy on both stacks.
UFW can manage IPv6 rules too, but only if it’s enabled.
Check:
sudo sysctl net.ipv6.conf.all.disable_ipv6
To ensure UFW applies to IPv6, confirm in /etc/default/ufw:
IPV6=yes
If you don’t use IPv6 and your hosting environment allows disabling it, disable it intentionally at both the OS and provider level.
Don’t leave it half-configured.
Quick diagnostics: “Is UFW blocking my site?”
These checks won’t replace full troubleshooting.
They will tell you quickly whether you’re looking at firewall policy or an app/service problem.
- Is UFW active?
sudo ufw status verbose - Is the service listening?
sudo ss -tulpn | egrep ':(80|443|22)\s' - Are packets hitting the box?
sudo tcpdump -ni any port 443 -c 20(installtcpdumpif needed) - Do you see denies?
sudo tail -n 100 /var/log/ufw.log
If ports are open but you still get 502/504 at the edge, the firewall probably isn’t the culprit.
You’re usually in web server or PHP-FPM territory.
Use this 502/504 troubleshooting tutorial to narrow it down fast.
Rollback plan: how to recover if you made a bad rule
If you still have SSH access, the quickest recovery is to disable UFW.
Then reapply a smaller, known-good set of rules.
sudo ufw disable
If you lost SSH but still have console access, log in through the console and run the same command.
Then confirm SSH works and rebuild the rules before re-enabling UFW.
You can also reset UFW to a clean state (this removes all rules):
sudo ufw reset
Reset is a last resort.
It’s useful when the ruleset is hard to untangle and you want to rebuild from a clear baseline.
Putting it together: a practical UFW ruleset for a simple WordPress VPS
This example assumes: SSH on 22, Nginx/Apache on 80/443, no inbound DNS, no inbound mail, no public control panel.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw limit 22/tcp comment 'Limit SSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw logging low
sudo ufw enable
sudo ufw status verbose
If you later add webmail, a panel, or a mail server, open only the required ports.
For admin-facing services, IP allowlisting is usually worth the extra step.
Summary: a firewall policy you can explain in one minute
A hosting firewall comes down to three ideas: deny inbound by default, allow only the services you run, and lock down admin access more than public web traffic.
With UFW, those ideas map to a ruleset you can read, audit, and roll back quickly.
If you want a server that’s ready for production changes like this—backed by predictable networking and clear upgrade paths—start with a HostMyCode VPS.
If you’d rather hand off firewall baselines, updates, and security maintenance, look at managed VPS hosting.
If you’re standardizing firewall rules across multiple sites, consistency matters more than clever rules. HostMyCode helps by keeping VPS plans predictable, with optional managed support for security baselines.
Pick a HostMyCode VPS if you want full control, or choose managed VPS hosting if you want an experienced team to keep the stack stable.
FAQ
Should I use UFW or raw iptables/nftables on a hosting VPS?
Use UFW if you want a readable ruleset and straightforward day-to-day operations. It programs netfilter underneath.
Raw nftables is also fine, but UFW is usually easier to document and hand off to teammates.
Will UFW break Let’s Encrypt renewals?
Not if 80/tcp and/or 443/tcp are open for the challenge type you’re using.
For most hosting setups using HTTP-01, keep 80 open and make sure your web server serves the ACME validation path.
Do I need to open port 53 for DNS on a normal web server?
No. Open 53/tcp and 53/udp only if your server provides DNS to others (authoritative or recursive).
Typical web servers just need outbound DNS, which stays allowed by default.
Can I allowlist SSH and still get locked out?
Yes, if your IP changes (ISP, mobile hotspot, VPN exit node, office failover).
If your admin IP isn’t stable, allow SSH from anywhere but require keys and add rate limiting. Or place SSH behind a VPN/jump host.
How do I verify UFW is the problem versus the web app?
Check ufw status, confirm the service is listening with ss -tulpn, and look for denies in /var/log/ufw.log.
If ports are open and requests arrive, the failure is usually in the web server or app layer.