Ubuntu 24.04 UFW Firewall Configuration Practical Guide

Five-step UFW security baseline on Ubuntu 24.04: default deny, allow SSH first, open web ports, IP whitelist, clean up rules by number.
This article covers five key UFW firewall configuration areas on Ubuntu 24.04 LTS that form an introductory security baseline for cloud servers. The core idea is "deny inbound by default, allow outbound," allowing rules one by one as needed. The most critical ordering issue is that SSH must be allowed before enabling the firewall; otherwise, the remote connection will be cut off, and dual-session verification is recommended. Web services can allow ports 80 and 443 at once through built-in application profiles (such as Nginx Full), balancing readability and dependency on installation state. Sensitive services such as databases and admin backends should use source IP whitelists to narrow access. When cleaning up rules, deleting by number causes renumbering, so operate from higher numbers to lower numbers or re-check the list each time.

Securing a cloud server often begins with the step of "controlling network traffic." On a host exposed to the public internet, every open port can become an entry point for automated scanning and vulnerability exploitation. iptables and nftables are powerful, but their rule syntax is complex and unfriendly to developers who have just taken over a server. UFW (Uncomplicated Firewall) was created to solve exactly this problem—it provides a concise command-line interface on top of the underlying network filtering capabilities, turning firewall configuration into a few easy-to-read and easy-to-remember commands.
This article is based on a UFW configuration tutorial for Ubuntu 24.04 LTS and covers five key areas: default policies, SSH lockout prevention, web service ports, IP whitelist restrictions, and rule cleanup. These areas form a complete introductory security baseline for a server.
Default Policies: Deny First, Then Allow as Needed
The core idea of UFW configuration is "deny inbound by default, allow outbound." This policy means that unless you explicitly open a port, all externally initiated connections will be dropped. For servers exposed to the public internet, this is the safest starting point.
In practice, the vast majority of problems stem from getting the order wrong: enabling the firewall first and configuring SSH rules afterward, which results in the remote connection being cut off immediately. The tutorial specifically emphasizes that SSH must be allowed before enabling UFW; otherwise, once disconnected, you can only intervene and fix it through the cloud provider's console (VNC or serial console). This detail may seem basic, but it is the pitfall new users most easily fall into.
UFW's default policies are set with the ufw default command, and a common combination is ufw default deny incoming and ufw default allow outgoing. The "deny" here is not a silent drop (DROP) but returns ICMP port unreachable (REJECT). The two differ subtly in behavior: DROP makes it hard for scanners to determine port status, while REJECT more clearly tells the client that the connection is refused. For most scenarios, REJECT is sufficient and more intuitive; if you want to further hide the host's existence, you can adjust the policy to DROP in /etc/ufw/before.rules. In addition, UFW supports two action keywords, deny and reject, corresponding to silent drop and active rejection respectively, which can be selected according to security needs during configuration.
SSH Lockout Prevention: A Critical Step Before Enabling
On Ubuntu 24.04 LTS, SSH uses port 22 by default. The configuration process should be: first run ufw allow ssh (or explicitly specify 22/tcp), confirm the rule has taken effect, and then run ufw enable. If the server has changed its SSH port, allow the corresponding custom port number instead of mechanically copying 22.
After enabling, it is recommended to keep the current SSH session open and open another terminal to test whether a new connection works properly. This "dual-session verification" approach effectively avoids the embarrassment of locking yourself out. After allowing SSH, add other business rules one by one, and services will not be interrupted throughout the process.
ufw allow ssh works because UFW looks up the port corresponding to ssh in /etc/services (default 22/tcp) and expands it into a port rule. This means that if the system services file has been modified or a non-standard port is used, you must explicitly write the port number, for example ufw allow 2222/tcp. In addition, UFW rules are in a "pending" state before being enabled; ufw show added can display the list of rules that have not yet been applied, while ufw status shows inactive when not enabled. Understanding this state difference helps you repeatedly check rules before enabling and avoid missing critical allow entries.
Web Services: Allow 80 and 443
For servers running websites or APIs, the HTTP (80) and HTTPS (443) ports need to be opened. UFW includes built-in application profiles, so you can directly use semantic commands such as ufw allow 'Nginx Full' or ufw allow 'Apache Full' to allow both ports at once, which is clearer than specifying port numbers one by one.
There is a noteworthy design trade-off here: UFW's application profiles come from the /etc/ufw/applications.d/ directory and are automatically registered when Nginx or Apache is installed. The advantage of using application profiles is strong rule readability—during operations handover, you can tell at a glance which service a rule serves; the disadvantage is that it depends on the application installation state, and on minimal systems the corresponding profile may not exist, in which case you still need to fall back to the port-number syntax.
UFW's application profiles are essentially predefined combinations of ports and protocols, stored in INI-format files under /etc/ufw/applications.d/. Each profile contains a title, description, and port list. ufw app list lists the currently available profiles, and ufw app info 'Nginx Full' shows exactly which ports that profile opens. In addition to Nginx and Apache, common services such as OpenSSH and CUPS also come with profiles. If a self-deployed service has no existing profile, you can manually create a file with the same name and write the port definitions, then run ufw app update to refresh, so that rules can be managed by semantic names just like built-in services.
IP Restrictions: Put Management Ports Behind a Whitelist
Services such as database ports, admin backends, and internal APIs should not be open to the entire internet. UFW supports specifying the source IP in rules, for example allowing only a fixed address to access port 3306. The syntax can be ufw allow from 203.0.113.10 to any port 3306, or you can further narrow the scope with proto tcp.
This source-address-based restriction is a direct way to reduce the "attack surface" from the entire internet to a few trusted networks. It is especially effective for office networks or jump host scenarios that require a fixed egress IP. Note that if the management side uses a dynamic IP, the whitelist will frequently become invalid; in that case, it is better to layer on a VPN or bastion host solution rather than relying solely on IP rules.
Rule Cleanup: Numbering, Viewing, and Deleting
As rules accumulate, outdated entries will inevitably need to be deleted. UFW offers two deletion methods: delete by rule content (ufw delete allow 80), or delete by number. The latter requires first running ufw status numbered to view the numbered rule list, then using ufw delete <number> to remove precisely.
There is an easily overlooked detail when deleting by number: each time a rule is deleted, the numbers of subsequent rules are rearranged. Therefore, when deleting multiple rules consecutively, you should operate from higher numbers to lower numbers, or re-check the list after each deletion to avoid deleting the wrong rule. This behavior is consistent across UFW versions and is a matter of usage habits and experience.
The numbers output by ufw status numbered are dynamically generated by UFW according to the current rule order and are not persistent identifiers. Internally, UFW maintains a linked list in the order rules were added, and deletion changes the indices of subsequent nodes, so number rearrangement is inevitable. In addition to deletion by number, ufw delete also accepts a complete rule description (such as ufw delete allow from 203.0.113.10 to any port 3306 proto tcp). This method is unaffected by number changes and is suitable for scripted batch cleanup. If there are many rules, you can also directly edit the /etc/ufw/user.rules file and then run ufw reload, but manual editing must be done carefully, as syntax errors may cause abnormal firewall behavior.
Summary
UFW's value is not that it is more powerful than iptables, but that it turns the security idea of "deny by default, allow as needed" into a few low-barrier commands. The configuration process on Ubuntu 24.04 LTS can be summarized as: first allow SSH, then enable the firewall, then open web ports according to business needs, layer IP restrictions on sensitive services, and finally periodically clean up redundant rules using the numbered view. Complete these five steps, and the basic network protection for a cloud server is in place.
Related articles

Chain of Thought Isn't Just for AI: How Humans Can Use CoT to Improve Thinking Quality
Chain of Thought isn't just a prompt trick for large models. Starting from a Hacker News discussion, this article analyzes why CoT works for human thinking too, breaks down actionable ways to transfer it, and highlights the key differences between human CoT and machine CoT.
Cloudflare Teams Up with OpenAI: Closi…
Cloudflare Teams Up with OpenAI: Closing the Loop from Vulnerability Discovery to Defense with AI
Cloudflare uses OpenAI Daybreak to investigate security vulnerabilities and generate reviewable remediation plans, while developers use Codex to boost coding efficiency and quality.

Orca Multi-Agent Orchestration in Practice: A Guide to Parallel Collaboration with Claude and Codex
Orca is Stable AI's free open-source agent workbench supporting 34 agents like Claude Code and Codex in parallel. Learn its Git worktree isolation, multi-model orchestration, and mobile management.