Linux Configure Firewall Using Shorewall Under RHEL / CentOS

A properly configured firewall can greatly increase the security of RHEL / CentOS based system. How do I configure a shorewall based firewall for CentOS or Red Hat Enterprise Linux system with an Internet connection? How do I install and configure shorewall to protect the following small business network?

Tutorial details
Difficulty level Advanced
Root privileges Yes
Requirements CentOS/RHEL
Est. reading time N/A
The Shoreline Firewall (also known as “Shorewall”), is a Netfilter (iptables) based firewall that can be used on a dedicated firewall system, a multi-function gateway/ router/server or on a standalone GNU/Linux system.

What is Shorewall?

Usually, you write a complicated set of firewall rules using /etc/sysconfig/iptables or shell scripts. However, with shorewall you describe your firewall/gateway requirements using entries in a set of configuration files. Shorewall reads those configuration files and with the help of the iptables, iptables-restore, ip and tc utilities, Shorewall configures Netfilter and the Linux networking subsystem to match your requirements. Shorewall is not a simple and easy to use GUI tool.

Sample setup

Fig.01: CentOS+Shorewall

  1. (firewall) – CentOS / RHEL based server. You need to install shorewall on this system. This server has two network interfaces. eth0 is connected to the LAN, and eth1 is connected to the internet. You also need to install reverse proxy server such as lighttpd or nginx on this server so it can load balance traffic between three Apache backends.
  2. Apache{1..3} – Apache web servers.
  3. Mysqld – MySQL database server.
  4. The default firewall policy is to drop all traffic. Allow all connection requests from your lan network (eth0) to the Internet (eth1) and/or to the other servers hosted on the lan. Drop all connection requests from the Internet (eth1) to your firewall (fw) or lan networks; these ignored connection requests will be logged using the info syslog priority (log level). Finally, open port 80 and 443 from the the Internet. The firewall reject all other connection requests; these rejected connection requests will be logged using the info syslog priority (log level).

Install shorewall on CentOS or RHEL

First, turn on EPEL repo and type the following yum command to install shorewall package ( Debian / Ubuntu Linux user read this faq for more information ) :
# yum install shorewall
Sample outputs:

Loaded plugins: protectbase, rhnplugin
0 packages excluded due to repository protections
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package shorewall.noarch 0:4.5.4-1.el6 will be installed
--> Processing Dependency: shorewall-core = 4.5.4-1.el6 for package: shorewall-4.5.4-1.el6.noarch
--> Processing Dependency: perl(Digest::SHA) for package: shorewall-4.5.4-1.el6.noarch
--> Running transaction check
---> Package perl-Digest-SHA.x86_64 1:5.47-127.el6 will be installed
---> Package shorewall-core.noarch 0:4.5.4-1.el6 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
 Package            Arch      Version             Repository               Size
 shorewall          noarch    4.5.4-1.el6         epel                    517 k
Installing for dependencies:
 perl-Digest-SHA    x86_64    1:5.47-127.el6      rhel-x86_64-server-6     62 k
 shorewall-core     noarch    4.5.4-1.el6         epel                     64 k
Transaction Summary
Install       3 Package(s)
Total download size: 643 k
Installed size: 2.1 M
Is this ok [y/N]: y
Downloading Packages:
(1/3): perl-Digest-SHA-5.47-127.el6.x86_64.rpm           |  62 kB     00:00     
(2/3): shorewall-4.5.4-1.el6.noarch.rpm                  | 517 kB     00:00     
(3/3): shorewall-core-4.5.4-1.el6.noarch.rpm             |  64 kB     00:00     
Total                                           1.0 MB/s | 643 kB     00:00     
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
  Installing : 1:perl-Digest-SHA-5.47-127.el6.x86_64                        1/3 
  Installing : shorewall-core-4.5.4-1.el6.noarch                            2/3 
  Installing : shorewall-4.5.4-1.el6.noarch                                 3/3 
  Verifying  : shorewall-4.5.4-1.el6.noarch                                 1/3 
  Verifying  : shorewall-core-4.5.4-1.el6.noarch                            2/3 
  Verifying  : 1:perl-Digest-SHA-5.47-127.el6.x86_64                        3/3 
  shorewall.noarch 0:4.5.4-1.el6                                                
Dependency Installed:
  perl-Digest-SHA.x86_64 1:5.47-127.el6   shorewall-core.noarch 0:4.5.4-1.el6  

A note about config files

  1. The default configuration directory is located at /etc/shorewall/.
  2. Shorewall global configuration file is located at /etc/shorewall/shorewall.conf. This file sets options that apply to Shorewall as a whole.
  3. The /etc/shorewall/zones file declares your network zones. Rules about what traffic to allow and what traffic to deny are expressed in terms of zones.
  4. The /etc/shorewall/interfaces file serves to define the firewall’s network interfaces to Shorewall.
  5. The /etc/shorewall/policy file defines the high-level policy for connections between zones defined in /etc/shorewall/zones.
  6. To provide exceptions to policies, add rules to /etc/shorewall/rules. Use this file to open or close ports and so on.
  7. To blacklist IPs, applications, MAC address, and subnets use the /etc/shorewall/blacklist file.

Rule status and ordering

The ordering of shorewall is very important as when a rule has been matched that action is performed and then no other action is performed.

  1. For each connection request entering the firewall, the request is first checked against the /etc/shorewall/rules file.
  2. If no rule in that file matches the connection request then the first policy in /etc/shorewall/policy that matches the request is applied.
  3. If there is a default action defined for the policy in /etc/shorewall/shorewall.conf then that action is invoked before the policy is enforced.


Shorewall uses the concept of zones. You need to define the network using a set of zones as follows for the two network-interface configuration:

#NAME                  DESCRIPTION
fw                     The firewall itself
wan                    The Internet
lan                    Your Local Network

Configure /etc/shorewall/zones

Edit the file /etc/shorewall/zones, enter:
# vi /etc/shorewall/zones
Update the file as follows:

fw      firewall
wan     ipv4                            
lan     ipv4

Shorewall recognizes the firewall system as its own zone. The name of the zone designating the firewall itself (usually ‘fw’ as shown in the above file) is stored in the shell variable $FW which may be used throughout the Shorewall configuration to refer to the firewall zone. The wan and lan are our standard IPv4 Shorewall zone type and is the default if you leave this column empty.

Configure /etc/shorewall/interfaces

Next, you need define the hosts in a zone. You can associate the zone with a network interface using the /etc/shorewall/interfaces file. In the two-interface sample, the two zones are defined using that file as follows. Edit the file /etc/shorewall/interfaces, enter:
# vi /etc/shorewall/interfaces
Append the following entires:

wan     eth1    -       routefilter,blacklist,tcpflags,logmartians,nosmurfs
lan     eth0

The above file defines the net zone as all IPv4 hosts interfacing to the firewall. The wan zone as all IPv4 hosts interfacing through eth1 and the lan as all IPv4 hosts interfacing through eth0. The wan interface eth1 has additional advanced protection from the common internet attacks:

  1. routefilter – Turn on kernel route filtering for this interface i.e. turn on anti-spoofing measurements.
  2. blacklist – Check packets arriving on this interface against the /etc/shorewall/blacklist file. The blacklist file is used to perform static blacklisting. You can blacklist by source address (IP or MAC), or by application.
  3. tcpflags – Packets arriving on this interface are checked for certain illegal combinations of TCP flags such as x mas or null or invalid packets. Packets found to have such a combination of flags are dropped (see the settings of TCP_FLAGS_DISPOSITION option in shorewall.conf) after having been logged in /var/log/messages file (see the setting of TCP_FLAGS_LOG_LEVEL in shorewall.conf).
  4. logmartians – Turn on kernel martian logging (logging of packets with impossible source addresses). It is strongly suggested that if you set routefilter on an interface that you also set logmartians.
  5. nosmurfs – Filter packets for smurfs (packets with a broadcast address as the source) i.e. turn on anti-smurf protection.

Configure /etc/shorewall/policy

You express your default policy for connections from one zone to another zone in the /etc/shorewall/policy. file. The basic choices for policy are:

  1. ACCEPT – Accept the connection.
  2. DROP – Ignore the connection request.
  3. REJECT – Return an appropriate error to the connection request.
  4. Connection request logging may be specified as part of a policy and it is conventional (and highly recommended) to log DROP and REJECT policies.

Edit the file /etc/shorewall/policy, enter:
# vi /etc/shorewall/policy
Append the policy:

## allow lan to all and firewall to all (outgoing to internet) but no traffic from wan/internet to lan or firewall itself 
lan     all     ACCEPT
$FW     all     ACCEPT
wan     all     DROP    info
# this must be last rule
all     all     REJECT  info

Save and close the file.

Configure /etc/shorewall/rules

Entries in this file govern connection establishment by defining exceptions to the policies layed out in /etc/shorewall/policy file. Use this file to open or close TCP/UDP ports. You can allows access to applications server such as FTP, HTTP, HTTPS and many more as defined in /usr/share/shorewall/macro.* files. The syntax is as follows:

                               PORT(S) PORT(S) LIMIT   GROUP



For example, to open port 22 from wan (internet) to firewall, enter:

ACCEPT     wan           $FW       tcp        22

You have a policy of ignoring all connection attempts from the wan zone (from the Internet), the above exception to that policy allows you to connect to the SSH server running on your firewall. You can now open port 80 and 443 that allows to connect to the reverse proxy server running on firewall:

## open port 443 from the wan to the nginx running on on your firewall.
HTTPS/ACCEPT    wan     $FW:              -       443
## open port 80 from the wan to the nginx running on and on your firewall.
HTTP/ACCEPT     wan     $FW:,   -       80

The wan / internet interface should not receive any packets whose source is in one of the ranges reserved by RFC 1918 (i.e., private or “non-routable” addresses). If packet mangling or connection-tracking match is enabled in your kernel, packets whose destination addresses are reserved by RFC 1918 are also rejected. Add the following DROP rule:

Rfc1918/DROP    wan     $FW

The following exception allows you to ping your firewall from the wan/internet:

Ping/ACCEPT     wan     $FW

Save and close the file. Please note that both Ping and Rfc1918 are macros defined in /usr/share/shorewall/macro.Ping file. To view ping macro type:
# cat /usr/share/shorewall/macro.Ping
Sample outputs:

# Shorewall version 4 - Ping Macro
# /usr/share/shorewall/macro.Ping
#       This macro handles 'ping' requests.
#                               PORT(S) PORT(S) LIMIT   GROUP
PARAM   -       -       icmp    8

To see list of all supported macros, enter:
# ls /usr/share/shorewall/macro.*
Sample outputs:

Fig.02: Macro list (click to enlarge)

Configure /etc/shorewall/blacklist

Edit the file /etc/shorewall/blacklist, enter:
# vi /etc/shorewall/blacklist
Block subnet and IP address:

Save and close the file.

Check the firewall configuration for errors

Type the following command:
# vi /etc/shorewall/shorewall.conf
Find the line:
Replace with:
Save and close the file. Shorewall uses a “compile” then “execute” approach. The Shorewall configuration compiler reads the configuration files and generates a shell script. Errors in the compilation step cause the script to be discarded and the command to be aborted. If the compilation step doesn’t find any errors then the shell script is executed. To check for errors, enter:
# shorewall check
Sample outputs:

Fig.03: Checking firewall configuration for error

Save existing firewall rules

Use iptables-save command to dump the contents of an IP Table in easily parseable format to screen or a file:
# iptables-save > /root/old.firewall.config
However, I recommend that you use the following commands to save and disable iptables service on CentOS/RHEL:
# service iptables save
# service iptables stop
# chkconfig iptables off

How do I start / stop / restart shorewall?

Type the following commands (warning poorly configured firewall rules may block out your remote access including ssh, so be careful when you type the following commands):
# service shorewall start
# service shorewall stop
# service shorewall restart
# service shorewall status

# /etc/init.d/shorewall start
# /etc/init.d/shorewall stop
# /etc/init.d/shorewall restart
# /etc/init.d/shorewall status

To turn on shorewall at boot time, enter:
# chkconfig shorewall on

How do I list firewall rules?

Type the following command:
# shorewall show
# shorewall show | less

How do I see the IP connections currently being tracked by the firewall?

# shorewall show connections

How do I see firewall logs?

# shorewall show hits
# shorewall show hits|less

How do I displays my kernel/iptables capabilities?

# shorewall show capabilities
The shorewall command and firewall configurations allows many more options. I recommend that you read shorewall command man page for more information.

How do I list all macros?

# shorewall show macros
# shorewall show Web

Sample outputs:

Shorewall 4.5.4 Macro Web at - Thu Dec 20 03:50:27 CST 2012
# Shorewall version 4 - Web Macro
# /usr/share/shorewall/macro.Web
#	This macro handles WWW traffic (secure and insecure).  This
#	macro is deprecated - use of macro.HTTP and macro.HTTPS instead
#	is recommended.
PARAM	-	-	tcp	80	# HTTP (plaintext)
PARAM	-	-	tcp	443	# HTTPS (over SSL)

🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 3 comments so far... add one

CategoryList of Unix and Linux commands
Disk space analyzersdf duf ncdu pydf
File Managementcat cp mkdir tree
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Modern utilitiesbat exa
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg glances gtop jobs killall kill pidof pstree pwdx time vtop
Searchingag grep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
3 comments… add one
  • Jalal Hajigholamali Dec 20, 2012 @ 2:55

    Very nice and useful article

  • Omn1padm3hum Dec 27, 2012 @ 19:10

    Great work for getting a fw up and running with all the basic essential info needed.
    Thank you

  • TimeLord Jan 2, 2013 @ 13:18

    You can use fw instead of $FW

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum