<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> <article> <!--$Id$--> <articleinfo> <title>Shorewall and Bridged Firewalls</title> <authorgroup> <author> <firstname>Tom</firstname> <surname>Eastep</surname> </author> </authorgroup> <pubdate><?dbtimestamp format="Y/m/d"?></pubdate> <copyright> <year>2004</year> <year>2005</year> <year>2006</year> <holder>Thomas M. Eastep</holder> </copyright> <legalnotice> <para>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 <quote><ulink url="GnuCopyright.htm">GNU Free Documentation License</ulink></quote>.</para> </legalnotice> </articleinfo> <caution> <para><emphasis role="bold">This article applies to Shorewall 3.0 and later. If you are running a version of Shorewall earlier than Shorewall 3.0.0 then please see the documentation for that release.</emphasis></para> </caution> <section> <title>Background</title> <para>Systems where Shorewall runs normally function as <firstterm>routers</firstterm>. 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 <firstterm>bridge</firstterm>. Bridges are layer-2 devices in the OSI model (think of a bridge as an ethernet switch).</para> <para>Some differences between routers and bridges are:</para> <orderedlist> <listitem> <para>Routers determine packet destination based on the destination IP address while bridges route traffic based on the destination MAC address in the ethernet frame.</para> </listitem> <listitem> <para>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.</para> </listitem> <listitem> <para>In most configurations, routers don't forward broadcast packets while a bridges do.</para> <note> <para>Section 4 of RFC 1812 describes the conditions under which a router may or must forward broadcasts.</para> </note> </listitem> </orderedlist> </section> <section> <title>Requirements</title> <warning> <para><emphasis role="bold">SUPPORT FOR BRIDGING AS DESCRIBED IN THIS ARTICLE MIGHT BE DISCONTINUED IN THE FUTURE.</emphasis> The underlying Netfilter features that Shorewall Bridge/Firewall support relies on are being removed and it is not certain whether Shorewall will be able to continue to support bridge/firewalls in the way described here.</para> <para>In <ulink url="NewBridge.html">another article</ulink>, I describe how to configure a bridge/firewall which will work with future kernel versions.</para> </warning> <para>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 <ulink url="SimpleBridge.html">Simple Bridge documentation</ulink> for details.</para> <para>In order to use Shorewall as a bridging firewall:</para> <itemizedlist> <listitem> <para>Your kernel must contain bridge support (CONFIG_BRIDGE=m or CONFIG_BRIDGE=y).</para> </listitem> <listitem> <para>Your kernel must contain bridge/netfilter integration (CONFIG_BRIDGE_NETFILTER=y).</para> </listitem> <listitem> <para>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 <ulink url="http://bridge.sf.net">http://bridge.sf.net</ulink>). Bering and Bering uCLibc users must find and install ipt_physdev.o for their distribution and add <quote>ipt_physdev</quote> to /etc/modules.</para> </listitem> <listitem> <para>Your iptables must contain physdev match support. iptables 1.2.9 and later contain this support.</para> </listitem> <listitem> <para>You must have the bridge utilities (bridge-utils) package installed.</para> </listitem> </itemizedlist> </section> <section> <title>Application</title> <para>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).</para> <graphic fileref="images/bridge.png" /> <para>There are a several key differences in this setup and a normal Shorewall configuration:</para> <itemizedlist> <listitem> <para>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.</para> </listitem> <listitem> <para>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.</para> </listitem> <listitem> <para><command>traceroute</command> doesn't detect the Bridge/Firewall as an intermediate router.</para> </listitem> <listitem> <para>If the router runs a DHCP server, the hosts connected to the LAN can use that server without having <command>dhcrelay</command> running on the Bridge/Firewall.</para> </listitem> </itemizedlist> <warning> <para>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.</para> </warning> <para>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 <emphasis role="bold">router</emphasis> would still be configured with IP addresses in 192.168.1.0/24 as shown below.<graphic fileref="images/bridge3.png" /></para> </section> <section> <title>Configuring the Bridge</title> <para>Configuring the bridge itself is quite simple and uses the <command>brctl</command> utility from the bridge-utils package. Bridge configuration information may be found at <ulink url="http://bridge.sf.net">http://bridge.sf.net</ulink>.</para> <para>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 <filename>/etc/network/interfaces</filename> file for a two-port bridge with a static IP address:</para> <blockquote> <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</programlisting> </blockquote> <para>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 <link linkend="bridge-router">bridge/router</link>.</para> <important> <para>Get your bridge configuration working first, including bridge startup at boot, before you configure and start Shorewall.</para> </important> <para>The bridge may have its IP address assigned via DHCP. Here's an example of an /etc/sysconfig/network/ifcfg-br0 file from a <trademark>SUSE</trademark> system:</para> <blockquote> <programlisting>BOOTPROTO='dhcp' REMOTE_IPADDR='' STARTMODE='onboot' UNIQUE='3hqH.MjuOqWfSZ+C' WIRELESS='no' MTU=''</programlisting> </blockquote> <para>Here's an /etc/sysconfig/network-scripts/ifcfg-br0 file for a <trademark>Mandriva</trademark> system:</para> <blockquote> <programlisting>DEVICE=br0 BOOTPROTO=dhcp ONBOOT=yes</programlisting> </blockquote> <para>On both the <trademark>SUSE</trademark> and Mandriva systems, a separate script is required to configure the bridge itself.</para> <para>Here are scripts that I used on a <trademark>SUSE</trademark> 9.1 system.</para> <blockquote> <para><filename>/etc/sysconfig/network/ifcfg-br0</filename></para> <programlisting>BOOTPROTO='dhcp' REMOTE_IPADDR='' STARTMODE='onboot' UNIQUE='3hqH.MjuOqWfSZ+C' WIRELESS='no' MTU=''</programlisting> <para><filename>/etc/init.d/bridge</filename><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</programlisting></para> </blockquote> <para>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.</para> <blockquote> <para><filename>/etc/sysconfig/network-scripts/ifcfg-br0:</filename></para> <programlisting>DEVICE=br0 TYPE=Bridge IPADDR=192.168.50.14 NETMASK=255.255.255.0 ONBOOT=yes</programlisting> <para><filename>/etc/sysconfig/network-scripts/ifcfg-eth0:</filename><programlisting>DEVICE=eth0 TYPE=ETHER BRIDGE=br0 ONBOOT=yes</programlisting><filename>/etc/sysconfig/network-scripts/ifcfg-eth1:</filename><programlisting>DEVICE=eth1 TYPE=ETHER BRIDGE=br0 ONBOOT=yes</programlisting></para> </blockquote> <para>Florin Grad at <trademark>Mandriva</trademark> provides this script for configuring a bridge:</para> <blockquote> <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</programlisting> <para>The <filename>/etc/sysconfig/bridge file</filename>:</para> <programlisting>BRIDGE_INTERFACE=br0 #The name of your Bridge INTERFACES="eth0 eth1" #The physical interfaces to be bridged</programlisting> </blockquote> <para>Andrzej Szelachowski contributed the following.</para> <blockquote> <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.brige executable and added the following line to /etc/rc.d/rc.local /etc/rc.d/rc.bridge </programlisting> </blockquote> <para>Joshua Schmidlkofer writes:</para> <blockquote> <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" </programlisting> </blockquote> <para>Users who successfully configure bridges on other distributions, with static or dynamic IP addresses, are encouraged to send <ulink url="mailto:webmaster@shorewall.net">me</ulink> their configuration so I can post it here.</para> </section> <section> <title>Configuring Shorewall</title> <para>Bridging in Shorewall is enabled using the BRIDGING option in <filename>/etc/shorewall/shorewall.conf</filename>:</para> <programlisting>BRIDGING=Yes</programlisting> <para>In the scenario pictured above, there would probably be two zones defined -- one for the internet and one for the local LAN so in <filename>/etc/shorewall/zones</filename>:</para> <programlisting>#ZONE TYPE OPTIONS fw firewall net ipv4 loc ipv4 #LAST LINE - ADD YOUR ENTRIES ABOVE THIS ONE - DO NOT REMOVE</programlisting> <para>A conventional two-zone policy file is appropriate here — <filename>/etc/shorewall/policy</filename>:</para> <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</programlisting> <para>Only the bridge device itself is configured with an IP address so only that device is defined to Shorewall in <filename>/etc/shorewall/interfaces</filename>:</para> <programlisting>#ZONE INTERFACE BROADCAST OPTIONS - br0 192.168.1.255 #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE</programlisting> <para>The zones are defined using the <filename>/etc/shorewall/hosts</filename> file. Assuming that the router is connected to <filename class="devicefile">eth0</filename> and the switch to <filename class="devicefile">eth1</filename>:</para> <programlisting>#ZONE HOST(S) OPTIONS net br0:eth0 loc br0:eth1 #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS LINE -- DO NOT REMOVE</programlisting> <para>When Shorewall is stopped, you want to allow only local traffic through the bridge — <filename><filename>/etc/shorewall/routestopped</filename></filename>:</para> <programlisting>#INTERFACE HOST(S) OPTIONS br0 192.168.1.0/24 routeback #LAST LINE -- ADD YOUR ENTRIES BEFORE THIS ONE -- DO NOT REMOVE</programlisting> <para>The <filename>/etc/shorewall/rules</filename> file from the two-interface sample is a good place to start for defining a set of firewall rules.</para> </section> <section id="bridge-router"> <title>Combination Router/Bridge</title> <para>A system running Shorewall doesn't have to be exclusively a bridge or a router -- it can act as both. Here's an example:<graphic fileref="images/bridge2.png" /></para> <para>This is basically the same setup as shown in the <ulink url="shorewall_setup_guide.htm">Shorewall Setup Guide</ulink> 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:</para> <orderedlist> <listitem> <para>The <filename>/etc/shorewall/proxyarp</filename> file is empty in this configuration.</para> </listitem> <listitem> <para>The <filename>/etc/shorewall/interfaces</filename> file is as follows:<programlisting>#ZONE INTERFACE BROADCAST OPTIONS - br0 detect routefilter loc eth1 detect</programlisting></para> </listitem> <listitem> <para>The <filename>/etc/shorewall/hosts</filename> file would have:</para> <programlisting>#ZONE HOSTS OPTIONS net br0:eth0 dmz br0:eth2</programlisting> </listitem> <listitem> <para>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.</para> </listitem> </orderedlist> </section> <section> <title>Limitations</title> <para>Bridging doesn't work with some wireless cards — see <ulink url="http://bridge.sf.net">http://bridge.sf.net</ulink>.</para> </section> <section> <title>Other Links</title> <itemizedlist> <listitem> <para><ulink url="http://wiki.buenosaireslibre.org/HowTos_2fBridgedFirewall">Here is an article in Spanish </ulink>detailing bridging a public and local network using Shorewall. This is another router/bridge configuration.</para> </listitem> </itemizedlist> </section> </article>