<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Shorewall-perl and Bridged Firewalls</title><link rel="stylesheet" href="html.css" type="text/css" /><meta name="generator" content="DocBook XSL Stylesheets V1.73.2" /></head><body><div class="article" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title"><a id="id257527"></a>Shorewall-perl and Bridged Firewalls</h2></div><div><div class="authorgroup"><div class="author"><h3 class="author"><span class="firstname">Tom</span> <span class="surname">Eastep</span></h3></div></div></div><div><p class="copyright">Copyright © 2007 Thomas M. Eastep</p></div><div><div class="legalnotice"><a id="id292634"></a><p>Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover, and with no Back-Cover Texts. A copy of the license is included in the section entitled “<span class="quote"><a class="ulink" href="GnuCopyright.htm" target="_self">GNU Free Documentation License</a></span>”.</p></div></div><div><p class="pubdate">2008/12/15</p></div></div><hr /></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#Background">Background</a></span></dt><dt><span class="section"><a href="#Requirements">Requirements</a></span></dt><dt><span class="section"><a href="#Application">Application</a></span></dt><dt><span class="section"><a href="#Bridge">Configuring the Bridge</a></span></dt><dt><span class="section"><a href="#Shorewall">Configuring Shorewall</a></span></dt><dt><span class="section"><a href="#bridge-router">Combination Router/Bridge</a></span></dt><dt><span class="section"><a href="#Limitations">Limitations</a></span></dt></dl></div><div class="caution" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Caution</h3><p><span class="bold"><strong>This article applies to Shorewall-perl 4.0 and later. If you are running a version of Shorewall earlier than Shorewall 4.0.0-Beta4 or you are not running Shorewall-perl then please see <a class="ulink" href="3.0/NewBridge.html" target="_self">this article</a>.</strong></span></p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="Background"></a>Background</h2></div></div></div><p>Systems where Shorewall runs normally function as <em class="firstterm">routers</em>. In the context of the Open System Interconnect (OSI) reference model, a router operates at layer 3, Shorewall may also be deployed on a GNU Linux System that acts as a <em class="firstterm">bridge</em>. Bridges are layer 2 devices in the OSI model (think of a bridge as an Ethernet switch).</p><p>Some differences between routers and bridges are:</p><div class="orderedlist"><ol type="1"><li><p>Routers determine packet destination based on the destination IP address, while bridges route traffic based on the destination MAC address in the Ethernet frame.</p></li><li><p>As a consequence of the first difference, routers can be connected to more than one IP network while a bridge may be part of only a single network.</p></li><li><p>In most configurations, routers don't forward broadcast packets while bridges do.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>Section 4 of RFC 1812 describes the conditions under which a router may or must forward broadcasts.</p></div></li></ol></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="Requirements"></a>Requirements</h2></div></div></div><p>Note that if you need a bridge but do not need to restrict the traffic through the bridge then any version of Shorewall will work. See the <a class="ulink" href="SimpleBridge.html" target="_self">Simple Bridge documentation</a> for details.</p><p>In order to use Shorewall as a bridging firewall:</p><div class="itemizedlist"><ul type="disc"><li><p>Your kernel must contain bridge support (CONFIG_BRIDGE=m or CONFIG_BRIDGE=y).</p></li><li><p>Your kernel must contain bridge/netfilter integration (CONFIG_BRIDGE_NETFILTER=y).</p></li><li><p>Your kernel must contain Netfilter physdev match support (CONFIG_IP_NF_MATCH_PHYSDEV=m or CONFIG_IP_NF_MATCH_PHYSDEV=y). Physdev match is standard in the 2.6 kernel series but must be patched into the 2.4 kernels (see <a class="ulink" href="http://bridge.sf.net" target="_self">http://bridge.sf.net</a>). Bering and Bering uCLibc users must find and install ipt_physdev.o for their distribution and add “<span class="quote">ipt_physdev</span>” to /etc/modules.</p></li><li><p>Your iptables must contain physdev match support and must support multiple instances of '-m physdev' in a single rule. iptables 1.3.6 and later contain this support.</p></li><li><p>You must have the bridge utilities (bridge-utils) package installed.</p></li></ul></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="Application"></a>Application</h2></div></div></div><p>The following diagram shows a typical application of a bridge/firewall. There is already an existing router in place whose internal interface supports a network, and you want to insert a firewall between the router, and the systems in the local network. In the example shown, the network uses RFC 1918 addresses but that is not a requirement; the bridge would work exactly the same if public IP addresses were used (remember that the bridge doesn't deal with IP addresses).</p><div><img src="images/bridge.png" /></div><p>There are a several key differences in this setup and a normal Shorewall configuration:</p><div class="itemizedlist"><ul type="disc"><li><p>The Shorewall system (the Bridge/Firewall) has only a single IP address even though it has two Ethernet interfaces! The IP address is configured on the bridge itself, rather than on either of the network cards.</p></li><li><p>The systems connected to the LAN are configured with the router's IP address (192.168.1.254 in the above diagram) as their default gateway.</p></li><li><p><span class="command"><strong>traceroute</strong></span> doesn't detect the Bridge/Firewall as an intermediate router.</p></li><li><p>If the router runs a DHCP server, the hosts connected to the LAN can use that server without having <span class="command"><strong>dhcrelay</strong></span> running on the Bridge/Firewall.</p></li></ul></div><div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Warning</h3><p>Inserting a bridge/firewall between a router and a set of local hosts only works if those local hosts form a single IP network. In the above diagram, all of the hosts in the loc zone are in the 192.168.1.0/24 network. If the router is routing between several local networks through the same physical interface (there are multiple IP networks sharing the same LAN), then inserting a bridge/firewall between the router and the local LAN won't work.</p></div><p>There are other possibilities here -- there could be a hub or switch between the router and the Bridge/Firewall and there could be other systems connected to that switch. All of the systems on the local side of the <span class="bold"><strong>router</strong></span> would still be configured with IP addresses in 192.168.1.0/24 as shown below.</p><div><img src="images/bridge3.png" /></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="Bridge"></a>Configuring the Bridge</h2></div></div></div><p>Configuring the bridge itself is quite simple and uses the <span class="command"><strong>brctl</strong></span> utility from the bridge-utils package. Bridge configuration information may be found at <a class="ulink" href="http://bridge.sf.net" target="_self">http://bridge.sf.net</a>.</p><p>Unfortunately, many Linux distributions don't have good bridge configuration tools, and the network configuration GUIs don't detect the presence of bridge devices. Here is an excerpt from a Debian <code class="filename">/etc/network/interfaces</code> file for a two-port bridge with a static IP address:</p><div class="blockquote"><blockquote class="blockquote"><pre class="programlisting">auto br0 iface br0 inet static address 192.168.1.253 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 pre-up /sbin/ip link set eth0 up pre-up /sbin/ip link set eth1 up pre-up /usr/sbin/brctl addbr br0 pre-up /usr/sbin/brctl addif br0 eth0 pre-up /usr/sbin/brctl addif br0 eth1 pre-down /usr/sbin/brctl delif br0 eth0 pre-down /sbin/ip link set eth0 down pre-down /usr/sbin/brctl delif br0 eth1 pre-down /sbin/ip link set eth1 down post-down /usr/sbin/brctl delbr br0</pre></blockquote></div><p>While it is not a requirement to give the bridge an IP address, doing so allows the bridge/firewall to access other systems and allows the bridge/firewall to be managed remotely. The bridge must also have an IP address for REJECT rules and policies to work correctly — otherwise REJECT behaves the same as DROP. It is also a requirement for bridges to have an IP address if they are part of a <a class="link" href="#bridge-router" title="Combination Router/Bridge">bridge/router</a>.</p><div class="important" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Important</h3><p>Get your bridge configuration working first, including bridge startup at boot, before you configure and start Shorewall.</p></div><p>The bridge may have its IP address assigned via DHCP. Here's an example of an /etc/sysconfig/network/ifcfg-br0 file from a <span class="trademark">SUSE</span>™ system:</p><div class="blockquote"><blockquote class="blockquote"><pre class="programlisting">BOOTPROTO='dhcp' REMOTE_IPADDR='' STARTMODE='onboot' UNIQUE='3hqH.MjuOqWfSZ+C' WIRELESS='no' MTU=''</pre></blockquote></div><p>Here's an /etc/sysconfig/network-scripts/ifcfg-br0 file for a <span class="trademark">Mandriva</span>™ system:</p><div class="blockquote"><blockquote class="blockquote"><pre class="programlisting">DEVICE=br0 BOOTPROTO=dhcp ONBOOT=yes</pre></blockquote></div><p>On both the <span class="trademark">SUSE</span>™ and Mandriva systems, a separate script is required to configure the bridge itself.</p><p>Here are scripts that I used on a <span class="trademark">SUSE</span>™ 9.1 system.</p><div class="blockquote"><blockquote class="blockquote"><p><code class="filename">/etc/sysconfig/network/ifcfg-br0</code></p><pre class="programlisting">BOOTPROTO='dhcp' REMOTE_IPADDR='' STARTMODE='onboot' UNIQUE='3hqH.MjuOqWfSZ+C' WIRELESS='no' MTU=''</pre><p><code class="filename">/etc/init.d/bridge</code></p><pre class="programlisting">#!/bin/sh ################################################################################ # Script to create a bridge # # (c) 2004 - Tom Eastep (teastep@shorewall.net) # # Modify the following variables to match your configuration # #### BEGIN INIT INFO # Provides: bridge # Required-Start: coldplug # Required-Stop: # Default-Start: 2 3 5 # Default-Stop: 0 1 6 # Description: starts and stops a bridge ### END INIT INFO # # chkconfig: 2345 05 89 # description: GRE/IP Tunnel # ################################################################################ PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin INTERFACES="eth1 eth0" BRIDGE="br0" MODULES="tulip" do_stop() { echo "Stopping Bridge $BRIDGE" brctl delbr $BRIDGE for interface in $INTERFACES; do ip link set $interface down done } do_start() { echo "Starting Bridge $BRIDGE" for module in $MODULES; do modprobe $module done sleep 5 for interface in $INTERFACES; do ip link set $interface up done brctl addbr $BRIDGE for interface in $INTERFACES; do brctl addif $BRIDGE $interface done } case "$1" in start) do_start ;; stop) do_stop ;; restart) do_stop sleep 1 do_start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 esac exit 0</pre></blockquote></div><p>Axel Westerhold has contributed this example of configuring a bridge with a static IP address on a Fedora System (Core 1 and Core 2 Test 1). Note that these files also configure the bridge itself, so there is no need for a separate bridge config script.</p><div class="blockquote"><blockquote class="blockquote"><p><code class="filename">/etc/sysconfig/network-scripts/ifcfg-br0:</code></p><pre class="programlisting">DEVICE=br0 TYPE=Bridge IPADDR=192.168.50.14 NETMASK=255.255.255.0 ONBOOT=yes</pre><p><code class="filename">/etc/sysconfig/network-scripts/ifcfg-eth0:</code></p><pre class="programlisting">DEVICE=eth0 TYPE=ETHER BRIDGE=br0 ONBOOT=yes</pre><p><code class="filename">/etc/sysconfig/network-scripts/ifcfg-eth1:</code></p><pre class="programlisting">DEVICE=eth1 TYPE=ETHER BRIDGE=br0 ONBOOT=yes</pre></blockquote></div><p>Florin Grad at <span class="trademark">Mandriva</span>™ provides this script for configuring a bridge:</p><div class="blockquote"><blockquote class="blockquote"><pre class="programlisting">#!/bin/sh # chkconfig: 2345 05 89 # description: Layer 2 Bridge # [ -f /etc/sysconfig/bridge ] && . /etc/sysconfig/bridge PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin do_stop() { echo "Stopping Bridge" for i in $INTERFACES $BRIDGE_INTERFACE ; do ip link set $i down done brctl delbr $BRIDGE_INTERFACE } do_start() { echo "Starting Bridge" for i in $INTERFACES ; do ip link set $i up done brctl addbr br0 for i in $INTERFACES ; do ip link set $i up brctl addif br0 $i done ifup $BRIDGE_INTERFACE } case "$1" in start) do_start ;; stop) do_stop ;; restart) do_stop sleep 1 do_start ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 esac exit 0</pre><p>The <code class="filename">/etc/sysconfig/bridge file</code>:</p><pre class="programlisting">BRIDGE_INTERFACE=br0 #The name of your Bridge INTERFACES="eth0 eth1" #The physical interfaces to be bridged</pre></blockquote></div><p>Andrzej Szelachowski contributed the following.</p><div class="blockquote"><blockquote class="blockquote"><pre class="programlisting">Here is how I configured bridge in Slackware: 1) I had to compile bridge-utils (It's not in the standard distribution) 2) I've created rc.bridge in /etc/rc.d: ######################### #! /bin/sh ifconfig eth0 0.0.0.0 ifconfig eth1 0.0.0.0 #ifconfig lo 127.0.0.1 #this line should be uncommented if you don't use rc.inet1 brctl addbr most brctl addif most eth0 brctl addif most eth1 ifconfig most 192.168.1.31 netmask 255.255.255.0 up #route add default gw 192.168.1.1 metric 1 #this line should be uncommented if #you don't use rc.inet1 ######################### 3) I made rc.bridge executable and added the following line to /etc/rc.d/rc.local /etc/rc.d/rc.bridge </pre></blockquote></div><p>Joshua Schmidlkofer writes:</p><div class="blockquote"><blockquote class="blockquote"><pre class="programlisting">Bridge Setup for Gentoo #install bridge-utils emerge bridge-utils ## create a link for net.br0 cd /etc/init.d ln -s net.eth0 net.br0 # Remove net.eth*, add net.br0 and bridge. rc-update del net.eth0 rc-update del net.eth1 rc-update add net.br0 default rc-update add bridge boot /etc/conf.d/bridge: #bridge contains the name of each bridge you want created. bridge="br0" # bridge_<bridge>_devices contains the devices to use at bridge startup. bridge_br0_devices="eth0 eth1" /etc/conf.d/net iface_br0="10.0.0.1 broadcast 10.0.0.255 netmask 255.255.255.0" #for dhcp: #iface_br0="dhcp" #comment this out if you use dhcp. gateway="eth0/10.0.0.1" </pre></blockquote></div><p>Users who successfully configure bridges on other distributions, with static or dynamic IP addresses, are encouraged to send <a class="ulink" href="mailto:webmaster@shorewall.net" target="_self">me</a> their configuration so I can post it here.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="Shorewall"></a>Configuring Shorewall</h2></div></div></div><p>As described above, Shorewall bridge support requires the <em class="firstterm">physdev match</em> feature of Netfilter/iptables. Physdev match allows rules to be triggered based on the bridge port that a packet arrived on and/or the bridge port that a packet will be sent over. The latter has proved to be problematic because it requires that the evaluation of rules be deferred until the destination bridge port is known. This deferral has the unfortunate side effect that it makes IPSEC Netfilter filtration incompatible with bridges. To work around this problem, in kernel version 2.6.20 the Netfilter developers decided to remove the deferred processing in two cases:</p><div class="itemizedlist"><ul type="disc"><li><p>When a packet being sent through a bridge entered the firewall on another interface and was being forwarded to the bridge.</p></li><li><p>When a packet originating on the firewall itself is being sent through a bridge.</p></li></ul></div><p>Notice that physdev match was only weakened with respect to the destination bridge port -- it remains fully functional with respect to the source bridge port.</p><p>To deal with the asymmetric nature of the new physdev match, Shorewall-perl supports a new type of zone - a <em class="firstterm">Bridge Port</em> (BP) zone. Bridge port zones have a number of restrictions:</p><div class="itemizedlist"><ul type="disc"><li><p>BP zones may only be associated with bridge ports.</p></li><li><p>All ports associated with a given BP zone must be on the same bridge.</p></li><li><p>Policies from a non-BP zone to a BP are disallowed.</p></li><li><p>Rules where the SOURCE is a non-BP zone and the DEST is a BP zone are disallowed.</p></li></ul></div><p>In /etc/shorewall/zones, BP zones are specified using the <span class="bold"><strong>bport</strong></span> (or <span class="bold"><strong>bport4</strong></span>) keyword. Shorewall perl requires that BRIDGING=No in <code class="filename">shorewall.conf</code>.</p><p>In the scenario pictured above, there would probably be two BP zones defined -- one for the Internet and one for the local LAN so in <code class="filename">/etc/shorewall/zones</code>:</p><pre class="programlisting">#ZONE TYPE OPTIONS fw firewall world ipv4 net:world bport loc:world bport #LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONE - DO NOT REMOVE</pre><p>The <span class="emphasis"><em>world</em></span> zone can be used when defining rules whose source zone is the firewall itself (remember that fw-><BP zone> rules are not allowed).</p><p>A conventional two-zone policy file is appropriate here — <code class="filename">/etc/shorewall/policy</code>:</p><pre class="programlisting">#SOURCE DEST POLICY LOG LIMIT:BURST loc net ACCEPT net all DROP info all all REJECT info #LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONE - DO NOT REMOVE</pre><p>Bridges use a special syntax in <code class="filename">/etc/shorewall/interfaces</code>. Assuming that the router is connected to <code class="filename">eth0</code> and the switch to <code class="filename">eth1</code>:</p><pre class="programlisting">#ZONE INTERFACE BROADCAST OPTIONS world br0 detect bridge net br0:eth0 loc br0:eth1 #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE</pre><p>The <span class="emphasis"><em>world</em></span> zone is associated with the bridge itself which is defined with the <span class="bold"><strong>bridge</strong></span> option. Bridge port entries may not have any OPTIONS.</p><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Note</h3><p>When a bridge is configured without an IP address, the <code class="option">optional</code> option must also be specified.</p></div><p>When Shorewall is stopped, you want to allow only local traffic through the bridge — <code class="filename"><code class="filename">/etc/shorewall/routestopped</code></code>:</p><pre class="programlisting">#INTERFACE HOST(S) OPTIONS br0 192.168.1.0/24 routeback #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE</pre><p>The <code class="filename">/etc/shorewall/rules</code> file from the two-interface sample is a good place to start for defining a set of firewall rules.</p></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="bridge-router"></a>Combination Router/Bridge</h2></div></div></div><p>A system running Shorewall doesn't have to be exclusively a bridge or a router -- it can act as both, which is also know as a brouter. Here's an example:</p><div><img src="images/bridge2.png" /></div><p>This is basically the same setup as shown in the <a class="ulink" href="shorewall_setup_guide.htm" target="_self">Shorewall Setup Guide</a> with the exception that the DMZ is bridged rather than using Proxy ARP. Changes in the configuration shown in the Setup Guide are as follows:</p><div class="orderedlist"><ol type="1"><li><p>The <code class="filename">/etc/shorewall/proxyarp</code> file is empty in this configuration.</p></li><li><p>The <code class="filename">/etc/shorewall/zones</code> file is modified:</p><pre class="programlisting">#ZONE TYPE OPTIONS fw firewall pub ipv4 #zone containing all public addresses net:pub bport4 dmz:pub bport4 loc ipv4</pre></li><li><p>The <code class="filename">/etc/shorewall/interfaces</code> file is as follows:</p><pre class="programlisting">#ZONE INTERFACE BROADCAST OPTIONS pub br0 detect routefilter,bridge net br0:eth0 dmz br0:eth2 loc eth1 detect</pre></li><li><p>The DMZ systems need a route to the 192.168.201.0/24 network via 192.0.2.176 to enable them to communicate with the local network.</p></li><li><p>This configuration does not support separate fw->dmz and fw->net policies/rules; similarly, it does not support separate loc->dmz and loc->net rules. This will make it a bit trickier to configure the rules. I suggest something like the following:</p><p><code class="filename">/etc/shorewall/params</code>:</p><pre class="programlisting">SERVERS=192.0.2.177,192.0.2.178 #IP Addresses of hosts in the DMZ DMZ=pub:$SERVERS #Use in place of 'dmz' in rule DEST NET=pub:!$SERVERS #Use in place of 'net' in rule DEST</pre><p><code class="filename">/etc/shorewall/policy</code>:</p><pre class="programlisting">#SOURCE DEST POLICY LEVEL loc <span class="bold"><strong>pub</strong></span> ACCEPT loc $FW REJECT info loc all REJECT info $FW <span class="bold"><strong>pub</strong></span> REJECT info $FW loc REJECT info $FW all REJECT info dmz net REJECT info dmz $FW REJECT info dmz loc REJECT info dmz all REJECT info net dmz DROP info net $FW DROP info net loc DROP info net all DROP info # THE FOLLOWING POLICY MUST BE LAST all all REJECT info</pre><p><code class="filename">/etc/shorewall/rules</code>:</p><pre class="programlisting">#ACTION SOURCE DEST PROTO DEST SOURCE # PORT(S) PORT(S) ACCEPT all all icmp 8 ACCEPT loc $DMZ tcp 25,53,80,443,... ACCEPT loc $DMZ udp 53 ACCEPT loc $NET ACCEPT $FW $DMZ udp 53 ACCEPT $FW $DMZ tcp 53 </pre></li></ol></div></div><div class="section" lang="en" xml:lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="Limitations"></a>Limitations</h2></div></div></div><p>Bridging doesn't work with some wireless cards — see <a class="ulink" href="http://bridge.sf.net" target="_self">http://bridge.sf.net</a>.</p></div></div></body></html>