| |

LFCS 110 ๐Ÿง UFW โ€” Rules and Profiles

โฑ๏ธ Estimated read: 9 min | |

The previous chapter established the default policies and the critical safety step of allowing SSH before enabling the firewall. This chapter focuses on the rule syntax that extends beyond simple allow and deny commands. UFW rules can restrict traffic by source address, destination port, network interface, protocol, and application profile. The LFCS exam tests the ability to construct a rule that matches a specific scenarioโ€””allow MySQL only from the application subnet on eth1″โ€”and the ability to manage rules by number when the list grows long.

Key point: UFW rules are evaluated in order, and the first match wins. A broad allow rule will shadow a more specific deny rule that appears after it. The status numbered command is essential for identifying and deleting the correct rule.


Why rule syntax and profiles matter

The source restriction problem. ufw allow 22 opens SSH to the entire internet. A production server should restrict administrative access to a trusted subnet or a bastion host. The from keyword adds a source condition to the rule, and the to any port syntax specifies the destination port. The rule becomes ufw allow from 10.0.1.0/24 to any port 22 proto tcp, which allows SSH only from the internal network .

The interface problem. A server with multiple network interfacesโ€”one public, one privateโ€”should not expose services on the public interface if they are intended for internal use only. The in on <interface> syntax binds the rule to a specific interface. ufw allow in on eth1 to any port 3306 opens MySQL only on the private interface, leaving the public interface closed .

The application profile problem. A service like Nginx requires TCP port 80 and TCP port 443. Writing two rules is manageable. Writing ten rules for a complex application is not. An application profile bundles the ports and protocols under a single name. ufw allow 'Nginx Full' opens both ports, and the rule appears in the status output as “Nginx Full” rather than “80,443/tcp” .

The rule ordering problem. UFW evaluates rules sequentially. If ufw allow 22 is added before ufw deny from 203.0.113.50 to any port 22, the deny rule is never reached because the allow rule matches first. The status numbered command shows the order, and delete removes a rule by number, allowing the administrator to reorder the rules correctly .

The trade-off. UFW’s syntax is readable but limited. Complex conditionsโ€”multiple source ranges, time-based rules, connection state matchingโ€”require editing /etc/ufw/before.rules directly. For the exam, the rule syntax covered here is sufficient.


a. Allow and deny with source, destination, and interface

The full UFW rule syntax allows conditions on the source address, the destination address, the port, the protocol, and the interface. The order of the keywords is flexible, but the most readable form follows the pattern: ufw [allow|deny|reject|limit] [in|out] [on interface] [from source] [to destination] [port port] [proto protocol].

# Allow SSH from a specific subnet
sudo ufw allow from 10.0.1.0/24 to any port 22 proto tcp

# Allow MySQL from the app server only
sudo ufw allow from 10.0.1.50 to any port 3306 proto tcp

# Allow HTTP only on the private interface
sudo ufw allow in on eth1 to any port 80 proto tcp

# Deny all traffic from a specific IP
sudo ufw deny from 203.0.113.50

The to any keyword is required when specifying a source but not a destination address. The port keyword specifies the destination port. The proto keyword is optional; without it, the rule applies to both TCP and UDP .

The deny action drops the packet silently. The reject action sends an ICMP response, which makes the connection fail immediately. The limit action allows the connection but rate-limits it to six connections per 30 seconds per source IP .


b. Managing rules by number

As the rule list grows, deleting rules by their full specification becomes error-prone. The status numbered command assigns a number to each rule, and delete <number> removes it.

# Show rules with numbers
sudo ufw status numbered
# [ 1] 22/tcp                     ALLOW IN    Anywhere
# [ 2] 80/tcp                     ALLOW IN    Anywhere
# [ 3] 443/tcp                    ALLOW IN    Anywhere
# [ 4] 22/tcp                     LIMIT IN    Anywhere

# Delete rule 4
sudo ufw delete 4

The numbering is dynamic. When a rule is deleted, the numbers of the subsequent rules shift. The status numbered command must be run again before the next deletion .

Rules can be inserted at a specific position with ufw insert <N> <rule>. This is useful when a deny rule must be placed before a broad allow rule. ufw insert 1 deny from 203.0.113.50 places the deny rule at the top of the list, ensuring it is evaluated first .


c. Application profiles

Application profiles are stored in /etc/ufw/applications.d/ as INI-format files. Each profile has a name, a title, a description, and one or more port specifications. The ufw app list command shows the profiles available on the system, and ufw app info <name> shows the ports and protocols that a profile opens .

# List profiles
sudo ufw app list
# Available applications:
#   Nginx Full
#   Nginx HTTP
#   Nginx HTTPS
#   OpenSSH

# Show profile details
sudo ufw app info 'Nginx Full'
# Ports: 80,443/tcp

# Allow the profile
sudo ufw allow 'Nginx Full'

The profile name in the status output is the profile name, not the port list. This makes the rule list more readable: “Nginx Full” instead of “80,443/tcp” .

A custom profile is created by writing an INI file to /etc/ufw/applications.d/. The file must have a section name in brackets, and the ports field accepts comma-separated ports, ranges (8000:8100), and protocols (8080/tcp).

[MyApp]
title=My Custom Application
description=Internal API on port 8080
ports=8080/tcp

After creating the file, ufw app list shows the profile, and ufw allow MyApp applies it .


Complete Example Session

# ============================================
# PART 1: ADD A SOURCE-RESTRICTED RULE
# ============================================

sudo ufw allow from 10.0.1.0/24 to any port 22 proto tcp
# SSH is now allowed only from the internal subnet.
# ============================================
# PART 2: ADD AN INTERFACE-SPECIFIC RULE
# ============================================

sudo ufw allow in on eth1 to any port 3306 proto tcp
# MySQL is allowed only on the private interface.
# ============================================
# PART 3: ADD A DENY RULE FOR A SPECIFIC IP
# ============================================

sudo ufw deny from 203.0.113.50
# All traffic from this IP is dropped.
# ============================================
# PART 4: ADD A RATE-LIMITED RULE
# ============================================

sudo ufw limit ssh/tcp
# SSH is allowed but rate-limited.
# ============================================
# PART 5: VIEW RULES WITH NUMBERS
# ============================================

sudo ufw status numbered
# [ 1] 22/tcp                     ALLOW IN    10.0.1.0/24
# [ 2] 3306/tcp                   ALLOW IN    Anywhere                   on eth1
# [ 3] Anywhere                   DENY IN     203.0.113.50
# [ 4] 22/tcp                     LIMIT IN    Anywhere
# ============================================
# PART 6: INSERT A RULE AT THE TOP
# ============================================

sudo ufw insert 1 deny from 198.51.100.0/24
# The deny rule is now evaluated before all allow rules.
# ============================================
# PART 7: LIST APPLICATION PROFILES
# ============================================

sudo ufw app list
# Available applications:
#   Nginx Full
#   Nginx HTTP
#   Nginx HTTPS
#   OpenSSH
# ============================================
# PART 8: ALLOW A PROFILE
# ============================================

sudo ufw allow 'Nginx Full'
# HTTP and HTTPS are opened.
# ============================================
# PART 9: DELETE A RULE BY NUMBER
# ============================================

sudo ufw delete 4
# The limit rule is removed.

The nine parts trace the rule syntax: source restriction, interface binding, IP deny, rate limiting, numbered listing, insertion, profile listing, profile allowance, and numbered deletion.


Quick Reference

Rule Syntax

ConditionSyntax
Source IPfrom 10.0.1.50
Source subnetfrom 10.0.1.0/24
Destination portto any port 22
Protocolproto tcp
Interfacein on eth0
Directionin, out

Rule Actions

ActionEffect
allowPermit traffic
denyDrop silently
rejectDrop with ICMP response
limitRate limit (6 connections per 30s)

Rule Management

CommandPurpose
ufw status numberedShow rules with numbers
ufw delete <N>Delete rule by number
ufw insert <N> <rule>Insert rule at position N
ufw app listList application profiles
ufw app info <name>Show profile details

Best Practices

โœ… Do This:

sudo ufw allow from 10.0.1.0/24 to any port 22 proto tcp
<!-- Restrict SSH to a trusted subnet -->             # โœ…
sudo ufw insert 1 deny from 203.0.113.50
<!-- Place deny rules before allow rules -->          # โœ…
sudo ufw status numbered
<!-- Check rule order before deleting -->             # โœ…

โŒ Don’t Do This:

# Allow a service to the entire internet without a source restriction
<!-- Use from when the service is internal -->        # โŒ
# Assume a deny rule after an allow rule will take effect
<!-- First match wins; the deny is never reached -->  # โŒ
# Delete a rule by number without re-checking
<!-- Numbers shift after each deletion -->            # โŒ

Common Pitfalls

PitfallWhy It HappensFix
Deny rule ignoredPlaced after a broad allow ruleInsert at top or reorder
Rule numbering mismatchDeleted a rule before re-checkingRun status numbered again
Profile not foundApplication not installedInstall package or create custom profile
Interface rule not matchingWrong interface nameVerify with ip link
IPv6 rule not appliedIPv6 disabled in /etc/default/ufwSet IPV6=yes and reload

Real-World Examples

1. SSH from Subnet

sudo ufw allow from 10.0.1.0/24 to any port 22 proto tcp

2. MySQL on Private Interface

sudo ufw allow in on eth1 to any port 3306 proto tcp

3. Deny IP

sudo ufw deny from 203.0.113.50

4. Rate Limit SSH

sudo ufw limit ssh/tcp

5. Insert Deny at Top

sudo ufw insert 1 deny from 198.51.100.0/24

6. List Profiles

sudo ufw app list

7. Allow Profile

sudo ufw allow 'Nginx Full'

8. Show Numbered

sudo ufw status numbered

9. Delete by Number

sudo ufw delete 3

10. Custom Profile

[MyApp]
title=My App
ports=8080/tcp

Visual

Rule Evaluation Order

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Incoming packet                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Rule 1: DENY from 203.0.113.50              โ”‚
โ”‚  โ”œโ”€ Match โ†’ DROP                             โ”‚
โ”‚  โ””โ”€ No match โ†’ continue                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Rule 2: ALLOW 22/tcp from 10.0.1.0/24       โ”‚
โ”‚  โ”œโ”€ Match โ†’ ACCEPT                           โ”‚
โ”‚  โ””โ”€ No match โ†’ continue                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Default: deny incoming                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The first match wins. Deny rules must be placed before allow rules.

Application Profile Expansion

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ufw allow 'Nginx Full'                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  /etc/ufw/applications.d/nginx               โ”‚
โ”‚  [Nginx Full]                                โ”‚
โ”‚  ports=80,443/tcp                            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                   โ”‚
                   โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  Two rules created:                          โ”‚
โ”‚  80/tcp ALLOW                                โ”‚
โ”‚  443/tcp ALLOW                               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The profile is a shortcut. The underlying rules are identical to the port commands.


Summary

ItemValue
Source restrictionfrom <ip/subnet>
Destination portto any port <N>
Protocolproto tcp
Interface bindingin on <iface>
Deny silentlydeny
Reject with ICMPreject
Rate limitlimit (6 per 30s)
Rule numberingstatus numbered
Delete by numberdelete <N>
Insert at topinsert 1 <rule>

Key takeaways:

  • UFW rules are evaluated in order. A deny rule placed after a broad allow rule is never reached. insert places a rule at a specific position, and status numbered shows the current order.
  • Source and interface restrictions narrow the rule. from 10.0.1.0/24 limits the rule to a subnet. in on eth1 limits it to an interface. Both can be combined.
  • Application profiles bundle ports. ufw allow 'Nginx Full' is equivalent to allowing port 80 and port 443. The profile is stored in /etc/ufw/applications.d/ and can be custom-created.
  • Numbered deletion is the safe deletion. Deleting by the full rule specification is error-prone. status numbered provides the index, and delete <N> removes the rule. Re-check the numbers after each deletion.
  • limit is rate limiting, not a firewall. It allows the connection but throttles repeated attempts. It does not block the port.

Remember: The rule syntax is the language of UFW. The from, to, port, proto, and on keywords compose into a rule that matches a specific scenario. The profile is a shortcut for common services. The numbered list is the management tool. The exam tests the composition of the rule, not just the action.

Was this helpful?


Stop using slow, ad-bloated tool sites! ๐Ÿคฎ

๐Ÿ”Ž Search “KandZ Tools” on Google to use many professional utilities for free.

KandZ.me is the ultimate minimalist hub for:
โœ… Finance (Mortgage, Interest, Inflation)
โœ… Tech (Base64, JSON, Dev Suite, IP)
โœ… Health (BMI, BMR, TDEE)
โœ… Productivity (Timer, Workspace, QR)

โšก๏ธ Fast & Private
๐Ÿ”’ No data leaves your device
๐Ÿ’Ž 100% Free

๐Ÿ”— Use it now: https://tools.kandz.me
๐Ÿ”– Bookmark itโ€”youโ€™ll need it later!