6.1.7 Working with Linux firewalls
Firewalls are an integral part of security for any operating system, including Linux. They function as a barrier between Your system and the external world, controlling incoming and outgoing network traffic according to predefined security rules. In Linux, there are several tools for firewall management, each with its own features and applications.
Configuring firewalls is a critical aspect of protecting Linux servers and workstations from unauthorized access, various types of attacks, and potential vulnerabilities. A properly configured firewall allows You to restrict access to Your system, permitting only authorized traffic and blocking everything else.
In the Linux context, firewalls typically operate at the kernel level, directly affecting the operating system’s network stack. This ensures high efficiency and performance when filtering network traffic, which is especially important for high-load servers and systems with limited resources.
Important: before making any changes to firewall settings, always create backups of the current configuration. Incorrect configuration can lead to loss of system access, which is especially important during remote administration.
Comparative Characteristics of Linux Firewalls
IPTables
- Advantages: versatile and flexible, low-level access, high performance
- Disadvantages: complex syntax, complicated management, lack of built-in preservation methods
- Recommended for: experienced administrators, situations requiring detailed control
UFW
- Advantages: simple syntax, easy to use, integrated into Ubuntu/Debian
- Disadvantages: less flexible than IPTables, limited capabilities for complex scenarios
- Recommended for: beginners, simple configurations, workstations
FirewallD
- Advantages: dynamic management, security zones, simple syntax for complex settings
- Disadvantages: relatively new system, less documented than IPTables
- Recommended for: modern RHEL/CentOS/Fedora/AlmaLinux/RockyLinux systems, servers with different security requirements
IPTables
IPTables is a traditional and universal tool for firewall configuration in Linux, which directly interacts with the Linux kernel’s packet filtering functions (Netfilter).
Basic IPTables Concepts
IPTables organizes filtering rules into tables, chains, and rules:
-
Tables: define the type of packet processing (filter, nat, mangle, raw, security)
- filter: used for packet filtering (allowing or blocking traffic)
- nat: used for network address translation
- mangle: allows modification of packet headers
- raw: used for setting exceptions from connection tracking
- security: used for network access control rules (SELinux)
-
Chains: groups of rules for a specific type of traffic
- INPUT: controls packets destined for the local system
- OUTPUT: controls packets created by the local system
- FORWARD: controls packets being routed through the system
- PREROUTING: for packets before routing decisions are made
- POSTROUTING: for packets after routing decisions are made
-
Rules: specific conditions and actions for packets
- Actions (targets): ACCEPT, DROP, REJECT, LOG, RETURN, and others
- Conditions: protocol, IP address, port, connection state, etc.
Basic IPTables Commands
Key Table for IPTables
Key | Description |
---|---|
-A (–append) |
Adds a new rule to the end of the specified chain |
-D (–delete) |
Removes a rule from the chain (by number or exact match) |
-I (–insert) |
Inserts a rule at the specified position in the chain |
-R (–replace) |
Replaces a rule at the specified position |
-L (–list) |
Lists all rules in the specified chain |
-F (–flush) |
Removes all rules from the specified chain |
-P (–policy) |
Sets the default policy for the chain |
-N (–new-chain) |
Creates a new user chain |
-X (–delete-chain) |
Deletes an empty user chain |
-t (–table) |
Specifies the table (filter, nat, mangle, raw, security) |
-p (–protocol) |
Specifies the protocol (tcp, udp, icmp, all) |
-s (–source) |
Specifies the source address/subnet |
-d (–destination) |
Specifies the destination address/subnet |
-i (–in-interface) |
Specifies the incoming network interface |
-o (–out-interface) |
Specifies the outgoing network interface |
--dport |
Specifies the destination port (used with -p) |
--sport |
Specifies the source port (used with -p) |
-j (–jump) |
Specifies the action (ACCEPT, DROP, REJECT, LOG, etc.) |
-m (–match) |
Loads a match extension (state, limit, conntrack, etc.) |
--line-numbers |
Shows line numbers when listing rules |
--state |
Specifies connection state (NEW, ESTABLISHED, RELATED, INVALID) |
--ctstate |
Specifies connection state for the conntrack module |
--limit |
Limits the rate of packet processing |
--limit-burst |
Specifies the initial value of the counter for limiting |
--log-prefix |
Adds a prefix to log entries |
--icmp-type |
Specifies the ICMP message type |
--to-port |
Specifies the target port for REDIRECT |
--to-destination |
Specifies the target address for DNAT |
Viewing current rules:
- sudo iptables -L -v -n
Display all rules:
Viewing rules with line numbers:
- sudo iptables -L --line-numbers
Viewing rules for a specific table:
- sudo iptables -t nat -L -v
Adding a rule: allowing incoming SSH connection:
- sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
Adding a rule with IP address restriction:
- sudo iptables -A INPUT -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT
Blocking all other incoming connections:
- sudo iptables -A INPUT -j DROP
Adding a rule at the beginning of the chain:
- sudo iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT
Removing a rule by number:
- sudo iptables -D INPUT 3
Removing a rule by content:
- sudo iptables -D INPUT -p tcp --dport 80 -j ACCEPT
Saving rules (Debian/Ubuntu):
- sudo netfilter-persistent save
Saving rules (CentOS/RHEL):
- sudo service iptables save
Basic Configuration Example
Clearing all rules:
- sudo iptables -F
Setting default policies:
- sudo iptables -P INPUT DROP
- sudo iptables -P FORWARD DROP
- sudo iptables -P OUTPUT ACCEPT
Allowing local connections:
- sudo iptables -A INPUT -i lo -j ACCEPT
Allowing established connections:
- sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Allowing SSH:
- sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
Allowing HTTP and HTTPS:
- sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
- sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
Allowing ICMP (ping):
- sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
Logging and blocking all other connections:
- sudo iptables -A INPUT -j LOG --log-prefix "IPTables-Dropped: "
- sudo iptables -A INPUT -j DROP
Advanced IPTables Features
Limiting the number of new connections:
- sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m limit --limit 3/minute --limit-burst 3 -j ACCEPT
Blocking specific IP addresses:
- sudo iptables -A INPUT -s 10.0.0.5 -j DROP
Setting up port forwarding:
- sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
Setting up NAT for internal network access to the external network:
- sudo iptables -t nat -A POSTROUTING -o eth0 -s 192.168.1.0/24 -j MASQUERADE
Important: IPTables commands are applied immediately but are not saved after reboot without additional actions. Use appropriate tools to save the configuration according to Your distribution.
UFW (Uncomplicated Firewall)
UFW is a layer on top of IPTables, designed to simplify firewall management. It is most commonly used in Ubuntu and Debian-based distributions. UFW was created to provide an easy-to-use interface that hides the complexities of IPTables while maintaining its power.
UFW Working Principle
UFW uses the principle of allow/deny rules for services and ports. Instead of complex IPTables commands, UFW allows the use of simple commands with keywords like “allow
”, “deny
”, “reject
” and others. This makes it ideal for beginning administrators or for systems with uncomplicated security requirements.
UFW rules are processed in the order they are added, from first to last. When a matching rule is found, processing stops. If no rule matches a packet, the default policy is applied.
Basic UFW Commands
Key Table for UFW
Key | Description |
---|---|
enable |
Activates the firewall |
disable |
Deactivates the firewall |
status |
Shows the current firewall status |
status verbose |
Shows detailed firewall status |
status numbered |
Shows rules with numbers |
default |
Sets the default policy (allow/deny) |
allow |
Allows connections (port, service, address) |
deny |
Blocks connections without notification |
reject |
Blocks connections with notification |
delete |
Deletes a rule (by number or content) |
insert |
Inserts a rule at the specified position |
route |
Manages packet forwarding rules |
logging |
Manages logging mode (on/off/low/medium/high/full) |
app list |
Shows a list of available application profiles |
app info |
Shows information about an application profile |
from |
Specifies the connection source (IP address, network) |
to |
Specifies the connection destination |
port |
Specifies a port or port range |
proto |
Specifies the protocol (tcp/udp) |
on |
Specifies a network interface |
comment |
Adds a comment to a rule |
Installing UFW:
- sudo apt install ufw
Activating UFW:
- sudo ufw enable
Deactivating UFW:
- sudo ufw disable
Checking status:
- sudo ufw status verbose
Status check result:
Setting default policies:
- sudo ufw default deny incoming
- sudo ufw default allow outgoing
Allowing a service by name:
- sudo ufw allow ssh
Allowing a port by number:
- sudo ufw allow 80/tcp
Allowing a port range:
- sudo ufw allow 6000:6007/tcp
Blocking a port:
- sudo ufw deny 23/tcp
Rejecting requests with notification:
- sudo ufw reject 80/tcp
Deleting a rule:
- sudo ufw delete allow 80/tcp
Allowing access for a specific application from profiles:
- sudo ufw app list
- sudo ufw allow 'Nginx Full'
Using Numeric Ordinal Numbers
Viewing rules with numbers:
- sudo ufw status numbered
When you enter the command, you will see a list of rules and their numbers:
Deleting a rule by number:
- sudo ufw delete 2
Defining Additional Parameters
Allowing access from a specific IP address:
- sudo ufw allow from 192.168.1.100
Allowing access to a specific port from a specific IP address:
- sudo ufw allow from 192.168.1.100 to any port 22
Allowing access from a specific subnet:
- sudo ufw allow from 192.168.1.0/24
Allowing access from a specific subnet to a specific port:
- sudo ufw allow from 192.168.1.0/24 to any port 3306
Allowing access through a specific interface:
- sudo ufw allow in on eth1 to any port 80
Setting up port forwarding (requires additional settings):
- sudo ufw route allow proto tcp from any to any port 80
Enabling logging:
- sudo ufw logging on
- sudo ufw logging medium
Reminder: after activating UFW, make sure You have added a rule to allow SSH or another remote access method, otherwise You may lose access to the system.
FirewallD
FirewallD is a modern firewall management framework that is the standard for Red Hat-based distributions (RHEL, CentOS, AlmaLinux, RockyLinux). It uses the concept of zones and services to simplify management.
Basic FirewallD Concepts:
-
Zones: predefined sets of rules for different trust levels
- public: for untrusted zones, public networks
- home: for home networks, most computers in the network are trusted
- work: for work networks, most computers are trusted
- trusted: all connections are accepted
- dmz: for computers in a demilitarized zone
- external: for use in routers with NAT
- internal: for the internal side of a gateway
- block: rejects all incoming connections
- drop: drops all incoming connections without notifications
-
Services: definitions for standard programs (
http
,ssh
,ftp
, etc.)- Each service contains information about ports, protocols, and modules
- Allows the use of understandable names instead of port numbers
-
Permanent and temporary rules:
- Temporary: active until reboot or service restart
- Permanent: saved after reboot (option
--permanent
)
Zones are a central concept in FirewallD and represent different levels of trust for network connections. Each zone can be configured with its own set of firewall rules, and network interfaces can be assigned to specific zones according to their security needs. This allows easy management of different network environments from a single system.
Basic FirewallD Management
Before starting to configure firewall rules, it’s important to be able to check the current state of the system and perform basic FirewallD management. This allows the administrator to understand the existing configuration and effectively make changes.
Key Table for FirewallD
Key | Description |
---|---|
--state |
Shows the state of the FirewallD service |
--reload |
Reloads the configuration |
--complete-reload |
Complete reload, including all modules |
--runtime-to-permanent |
Saves current temporary rules as permanent |
--permanent |
Marks a change as permanent (saved after reboot) |
--get-default-zone |
Shows the default zone |
--set-default-zone |
Sets the default zone |
--get-zones |
Lists all available zones |
--get-active-zones |
Lists active zones with assigned interfaces |
--zone |
Specifies a zone for an operation |
--list-all |
Lists all parameters of a specified zone |
--list-all-zones |
Lists parameters of all zones |
--new-zone |
Creates a new zone |
--get-services |
Lists all available services |
--get-icmptypes |
Lists all available ICMP types |
--add-service |
Adds a service to a zone |
--remove-service |
Removes a service from a zone |
--add-port |
Adds a port to a zone |
--remove-port |
Removes a port from a zone |
--add-protocol |
Adds a protocol to a zone |
--remove-protocol |
Removes a protocol from a zone |
--add-interface |
Binds an interface to a zone |
--remove-interface |
Removes an interface from a zone |
--add-source |
Adds a source (IP/network) to a zone |
--remove-source |
Removes a source (IP/network) from a zone |
--add-masquerade |
Enables masquerading (NAT) for a zone |
--remove-masquerade |
Disables masquerading for a zone |
--add-forward-port |
Adds a port forwarding rule |
--remove-forward-port |
Removes a port forwarding rule |
--add-rich-rule |
Adds an advanced rule to a zone |
--remove-rich-rule |
Removes an advanced rule from a zone |
--query-masquerade |
Checks the state of masquerading for a zone |
--new-service |
Creates a new service |
--service |
Specifies a service for configuration |
--set-description |
Sets a description for a service/zone |
--add-port-to-service |
Adds a port to a service |
--info-service |
Shows information about a service |
--timeout |
Sets a temporary rule for a specified period |
Check if the FirewallD service is running:
- sudo firewall-cmd --state
If the service is running, you will see running
:
Check the FirewallD version:
- sudo firewall-cmd --version
Get a list of all available zones in the system:
- sudo firewall-cmd --get-zones
View active zones along with their assigned interfaces:
- sudo firewall-cmd --get-active-zones
Examine the settings of a specific zone in detail:
- sudo firewall-cmd --zone=public --list-all
For a complete system audit, you can view all zones along with their settings:
- sudo firewall-cmd --list-all-zones
View all zones together with settings:
Managing services and ports. FirewallD uses the concept of “services” for convenient access management to standard programs. Viewing available services:
- sudo firewall-cmd --get-services
Check which services are allowed in a specific zone:
- sudo firewall-cmd --zone=public --list-services
Add permission for a service on a permanent basis:
- sudo firewall-cmd --zone=public --add-service=http --permanent
For temporary testing, you can add a service without the --permanent
parameter:
- sudo firewall-cmd --zone=public --add-service=https
Remove permission for a service:
- sudo firewall-cmd --zone=public --remove-service=http --permanent
For non-standard programs, you can allow access by port number:
- sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
Remove permission for a port:
- sudo firewall-cmd --zone=public --remove-port=8080/tcp --permanent
After making changes, you need to apply them:
- sudo firewall-cmd --reload
Advanced Settings and Zone Management
FirewallD provides flexible capabilities for network security configuration, allowing the creation of complex rules for different network environments.
Zone and interface configuration. Set the default zone for all new connections:
- sudo firewall-cmd --set-default-zone=home
Bind a network interface to a specific zone:
- sudo firewall-cmd --zone=trusted --add-interface=eth0 --permanent
Remove an interface from a zone:
- sudo firewall-cmd --zone=trusted --remove-interface=eth0 --permanent
Find out which zone an interface belongs to:
- sudo firewall-cmd --get-zone-of-interface=eth0
For specific needs, you can create your own zone:
- sudo firewall-cmd --permanent --new-zone=myzone
- sudo firewall-cmd --reload
Service configuration and advanced rules. Get detailed information about a service:
- sudo firewall-cmd --info-service=http
Create your own service for a non-standard program:
- sudo firewall-cmd --permanent --new-service=myservice
- sudo firewall-cmd --permanent --service=myservice --set-description="My Custom Service"
- sudo firewall-cmd --permanent --service=myservice --add-port=12345/tcp
- sudo firewall-cmd --reload
For more complex network interaction scenarios, FirewallD supports masquerading (NAT) and port forwarding:
- sudo firewall-cmd --zone=external --add-masquerade --permanent
Check the masquerading state for a zone:
- sudo firewall-cmd --zone=external --query-masquerade
Configure port forwarding within a single server:
- sudo firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toport=8080 --permanent
Forward traffic to another host:
- sudo firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.1.10 --permanent
Advanced Rules and Security
For implementing complex network security policies, FirewallD supports so-called “rich rules,” which provide maximum flexibility in configuration.
Add a rule to allow HTTP access from a specific IP address:
- sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.10" service name="http" accept' --permanent
Block access from a specific IP address:
- sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.10" reject' --permanent
Limit the number of incoming connections to enhance security:
- sudo firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" service name="http" accept limit value="5/m"' --permanent
Important:
FirewallD rules added without the --permanent
parameter will be lost after system or service restart. Always use --permanent
for permanent changes and execute --reload
to apply changes.
Conclusion
Linux firewalls provide convenient tools for protecting Your systems from unauthorized access and network attacks. The choice of a specific tool depends on Your needs, level of experience, and the Linux distribution You are using.
IPTables remains the best low-level tool for experienced administrators, UFW offers a simplified interface for basic needs, and FirewallD provides a balance between simplicity and functionality with support for dynamic management.
Regardless of the chosen tool, it is important to follow best security practices and regularly update the firewall configuration according to changing security requirements and the needs of Your infrastructure.
Best Security Practices:
- Principle of least privilege: allow only necessary traffic and block everything else.
- Regular audits: periodically check firewall rules for compliance with current security requirements.
- Change documentation: maintain a log of all changes to the firewall configuration.
- Backup: always create backups of the configuration before making changes.
- Testing: verify changes in a test environment before applying them to production systems.
Never rely exclusively on a firewall for the security of Your system. A firewall is just one component of a comprehensive security strategy, which should also include timely updates, proper user and permission management, system monitoring, and other security measures.