Table of Contents#
- Prerequisites
- Understanding Firewalld Basics
- Step-by-Step Guide: Open Port for a Specific IP 3.1 Check Firewalld Status 3.2 Identify the Target Zone 3.3 Add a Temporary Rich Rule 3.4 Verify the Temporary Rule 3.5 Make the Rule Permanent 3.6 Verify Permanent Rules
- Managing Firewalld Rules 4.1 Remove a Rule 4.2 Allow a Subnet Instead of Single IP 4.3 Allow UDP Ports 4.4 Use Service Names Instead of Port Numbers
- Troubleshooting Common Issues
- Advanced Tips
- Conclusion
- References
Prerequisites#
Before you begin, ensure you have:
- A Linux system with Firewalld installed (most modern RHEL-based distros include it by default).
- Root or sudo privileges to execute firewall commands.
- The specific IPv4/IPv6 address (or subnet) of the machine that needs access to the port.
- The port number and protocol (TCP/UDP) of the service you want to expose (e.g., SSH uses TCP port 22, DNS uses UDP port 53).
Understanding Firewalld Basics#
Firewalld operates using two key concepts:
- Zones: Predefined rule sets that apply to network interfaces. Common zones include:
public: For untrusted public networks (default zone for most systems).internal: For trusted internal networks.trusted: Allows all incoming traffic (use sparingly).
- Rich Rules: Flexible, human-readable rules that let you create granular policies (e.g., allow a specific IP to access a specific port). Unlike basic port opening commands, rich rules target traffic from specific sources, making them ideal for our task.
Step-by-Step Guide: Open Port for a Specific IP#
Let’s walk through the process of allowing a trusted IP (e.g., 192.168.1.100) to access TCP port 22 (SSH) on your server.
3.1 Check Firewalld Status#
First, confirm Firewalld is running and enabled to start on boot:
# Check current status
sudo systemctl status firewalld
# Start Firewalld if it’s not running
sudo systemctl start firewalld
# Enable Firewalld to start automatically at boot
sudo systemctl enable firewalld3.2 Identify the Target Zone#
Rules are applied to zones, so you need to know which zone your server’s network interface uses. To list active zones:
sudo firewall-cmd --get-active-zonesThis will output something like:
public
interfaces: eth0
In this example, the default zone is public.
3.3 Add a Temporary Rich Rule#
Temporary rules are applied immediately but will be lost if Firewalld restarts or the server reboots. Use this to test your rule first:
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" accept'Let’s break down each part of the rule:
family="ipv4": Target IPv4 traffic (use"ipv6"for IPv6 addresses).source address="192.168.1.100": Allow traffic from this specific IP.port protocol="tcp" port="22": Allow access to TCP port 22.accept: Permit the traffic that matches the rule.
3.4 Verify the Temporary Rule#
Confirm the rule was added successfully:
sudo firewall-cmd --zone=public --list-rich-rulesYou should see your rule listed in the output.
3.5 Make the Rule Permanent#
To ensure the rule persists across reboots, either: Option 1: Convert temporary rules to permanent:
sudo firewall-cmd --runtime-to-permanentOption 2: Add the rule as permanent directly (recommended for new rules):
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" accept' --permanentThen reload Firewalld to apply the permanent changes:
sudo firewall-cmd --reload3.6 Verify Permanent Rules#
Check that the permanent rule is saved:
sudo firewall-cmd --zone=public --list-rich-rules --permanentManaging Firewalld Rules#
4.1 Remove a Rule#
To remove a temporary rule:
sudo firewall-cmd --zone=public --remove-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" accept'To remove a permanent rule:
sudo firewall-cmd --zone=public --remove-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" accept' --permanent
sudo firewall-cmd --reload4.2 Allow a Subnet Instead of Single IP#
If you want to allow an entire subnet (e.g., 192.168.1.0/24) to access a port, modify the source address to include the subnet mask:
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="80" accept' --permanent
sudo firewall-cmd --reload4.3 Allow UDP Ports#
To allow access to a UDP port (e.g., DNS on port 53), change the port protocol to udp:
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="udp" port="53" accept' --permanent
sudo firewall-cmd --reload4.4 Use Service Names Instead of Port Numbers#
For well-known services, you can use firewalld service names instead of raw port numbers. This is more readable and automatically handles the correct protocol:
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" service name="ssh" accept' --permanent
sudo firewall-cmd --reloadTo list available services: firewall-cmd --get-services.
Troubleshooting Common Issues#
If your rule isn’t working, check these common problems:
- Incorrect Zone: Ensure you applied the rule to the zone your server’s interface uses (check with
firewall-cmd --get-active-zones). - IP Address Typos: Double-check the source IP address in your rule.
- Protocol Mismatch: Use
tcpfor services like SSH, HTTP, or HTTPS;udpfor DNS, DHCP, or streaming services. - Rule Not Permanent: If the rule disappears after a reboot, you forgot to add the
--permanentflag or run--runtime-to-permanent. - Firewall Blocking Elsewhere: Ensure no other firewalls (e.g., cloud provider firewalls like AWS Security Groups) are blocking the traffic.
- Conflicting Rules: Check for conflicting rules with
firewall-cmd --zone=<zone> --list-all. A broader rule may override your rich rule. - nftables Backend Issues: If using firewalld 2.0+ with the nftables backend, ensure no leftover iptables rules are interfering. Check with
nft list ruleset.
To test if the port is accessible from the trusted IP, use nc (netcat) or curl:
# From the trusted IP machine
nc -zv your-server-ip 22Or for HTTP/HTTPS services:
curl -I http://your-server-ip:80Advanced Tips#
-
Log Allowed Connections: Add logging to your rule to track access attempts from the trusted IP:
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" log prefix="SSH_Access" level="info" accept' --permanent sudo firewall-cmd --reloadLogs will be stored in
/var/log/messagesor/var/log/syslog. -
Deny All Other Access to the Port: To ensure only your trusted IP can access the port, deny all other traffic to that port (add this rule after your accept rule):
sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" port protocol="tcp" port="22" reject' --permanent sudo firewall-cmd --reloadWarning: Only do this if you’re sure you won’t lock yourself out of the server.
-
Use Custom Zones: For better organization, create a custom zone for trusted IPs and apply rules to it:
sudo firewall-cmd --new-zone=trusted-ips --permanent sudo firewall-cmd --reload sudo firewall-cmd --zone=trusted-ips --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" accept' --permanentThen assign your server's interface to this zone if needed.
-
Control Rule Execution Order with Priorities: Rich rules support a
priorityfield (range: -32768 to 32767) that controls their execution order. Lower values are evaluated first, and negative priorities run before other firewalld primitives:sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="22" priority="100" accept' --permanent sudo firewall-cmd --reload -
Check Your Firewalld Version: Knowing your version helps determine which features are available (e.g., nftables backend, zone priorities):
sudo firewall-cmd --versionFirewalld 2.0+ (2023) uses nftables as the default backend and supports zone priorities.
Conclusion#
Opening a port for a specific IP address using Firewalld is a critical security practice that reduces your server’s attack surface by restricting access to trusted sources only. By leveraging rich rules, you can create granular policies tailored to your needs.
Remember to always test your rules before making them permanent, and verify that the traffic flows as expected. Check your firewalld version with firewall-cmd --version to confirm which features are available on your system. For more complex scenarios, refer to Firewalld’s official documentation.