mirror of
https://gitlab.com/shorewall/code.git
synced 2024-12-23 14:48:51 +01:00
3a70185284
- Anatomy - Bridge (Perl) Signed-off-by: Tom Eastep <teastep@shorewall.net>
985 lines
34 KiB
XML
985 lines
34 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
|
<article>
|
|
<!--$Id$-->
|
|
|
|
<articleinfo>
|
|
<title>Bridged Firewalls</title>
|
|
|
|
<authorgroup>
|
|
<author>
|
|
<firstname>Tom</firstname>
|
|
|
|
<surname>Eastep</surname>
|
|
</author>
|
|
</authorgroup>
|
|
|
|
<pubdate><?dbtimestamp format="Y/m/d"?></pubdate>
|
|
|
|
<copyright>
|
|
<year>2007</year>
|
|
|
|
<year>2009</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 4.4 and
|
|
later.</emphasis></para>
|
|
</caution>
|
|
|
|
<section id="Background">
|
|
<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/firewall may be
|
|
part of only a single network (see below).</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>In most configurations, routers don't forward broadcast packets
|
|
while 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 id="Requirements">
|
|
<title>Requirements</title>
|
|
|
|
<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 and later kernel series but must
|
|
be patched into the 2.4 kernels (see <ulink
|
|
url="http://bridge.sf.net">http://bridge.sf.net</ulink>).</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>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.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>You must have the bridge utilities (bridge-utils) package
|
|
installed.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
|
|
<section id="Application">
|
|
<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 id="Bridge">
|
|
<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
|
|
|
|
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</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.bridge 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 id="Shorewall">
|
|
<title>Configuring Shorewall</title>
|
|
|
|
<para>As described above, Shorewall bridge support requires the
|
|
<firstterm>physdev match</firstterm> 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:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>When a packet being sent through a bridge entered the firewall
|
|
on another interface and was being forwarded to the bridge.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>When a packet originating on the firewall itself is being sent
|
|
through a bridge.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>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.</para>
|
|
|
|
<para>To deal with the asymmetric nature of the new physdev match,
|
|
Shorewall supports a new type of zone - a <firstterm>Bridge
|
|
Port</firstterm> (BP) zone. Bridge port zones have a number of
|
|
restrictions:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>BP zones may only be associated with bridge ports.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>All ports associated with a given BP zone must be on the same
|
|
bridge.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Policies from a non-BP zone to a BP are disallowed.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Rules where the SOURCE is a non-BP zone and the DEST is a BP
|
|
zone are disallowed.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>In /etc/shorewall/zones, BP zones are specified using the <emphasis
|
|
role="bold">bport</emphasis> (or <emphasis role="bold">bport4</emphasis>)
|
|
keyword. If your version of <filename>shorewall.conf</filename> contains
|
|
the <emphasis role="bold">BRIDGING</emphasis> option, it must be set to
|
|
<emphasis role="bold">No</emphasis>.</para>
|
|
|
|
<para>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
|
|
<filename>/etc/shorewall/zones</filename>:</para>
|
|
|
|
<programlisting>#ZONE TYPE OPTIONS
|
|
fw firewall
|
|
world ipv4
|
|
net:world bport
|
|
loc:world bport</programlisting>
|
|
|
|
<para>The <emphasis>world</emphasis> zone can be used when defining rules
|
|
whose source zone is the firewall itself (remember that fw-><BP
|
|
zone> rules are not allowed).</para>
|
|
|
|
<para>A conventional two-zone policy file is appropriate here —
|
|
<filename>/etc/shorewall/policy</filename>:</para>
|
|
|
|
<programlisting>#SOURCE DEST POLICY LOGLEVEL LIMIT
|
|
loc net ACCEPT
|
|
net all DROP info
|
|
all all REJECT info</programlisting>
|
|
|
|
<para>In <filename>/etc/shorewall/shorewall.conf</filename>:</para>
|
|
|
|
<programlisting>IMPLICIT_CONTINUE=No</programlisting>
|
|
|
|
<para>Bridges use a special syntax in
|
|
<filename>/etc/shorewall/interfaces</filename>. Assuming that the router
|
|
is connected to <filename class="devicefile">eth0</filename> and the
|
|
switch to <filename class="devicefile">eth1</filename>:</para>
|
|
|
|
<programlisting>#ZONE INTERFACE OPTIONS
|
|
world br0 bridge
|
|
net br0:eth0
|
|
loc br0:eth1</programlisting>
|
|
|
|
<para>The <emphasis>world</emphasis> zone is associated with the bridge
|
|
itself which is defined with the <emphasis role="bold">bridge</emphasis>
|
|
option. Bridge port entries may not have any OPTIONS.</para>
|
|
|
|
<note>
|
|
<para>When a bridge is configured without an IP address, the
|
|
<option>optional</option> option must also be specified.</para>
|
|
</note>
|
|
|
|
<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</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="Multiple">
|
|
<title>Multiple Bridges with Wildcard Ports</title>
|
|
|
|
<para>It is sometimes required to configure multiple bridges on a single
|
|
firewall/gateway. The following seemingly valid configuration results in a
|
|
compile-time error</para>
|
|
|
|
<simplelist>
|
|
<member>ERROR: Duplicate Interface Name (p+)</member>
|
|
</simplelist>
|
|
|
|
<para><filename>/etc/shorewall/zones</filename>:</para>
|
|
|
|
<programlisting> #ZONE TYPE
|
|
fw firewall
|
|
world ipv4
|
|
z1:world bport4
|
|
z2:world bport4</programlisting>
|
|
|
|
<para><filename>/etc/shorewall/interfaces</filename>:</para>
|
|
|
|
<programlisting> #ZONE INTERFACE OPTIONS
|
|
world br0 bridge
|
|
world br1 bridge
|
|
z1 br0:p+
|
|
z2 br1:p+</programlisting>
|
|
|
|
<para>The reason is that the Shorewall implementation requires each bridge
|
|
port to have a unique name. The <option>physical</option> interface option
|
|
was added in Shorewall 4.4.4 to work around this problem. The above
|
|
configuration may be defined using the following in
|
|
<filename>/etc/shorewall/interfaces</filename>:</para>
|
|
|
|
<programlisting> #ZONE INTERFACE OPTIONS
|
|
world br0 bridge
|
|
world br1 bridge
|
|
z1 br0:x+ physical=p+
|
|
z2 br1:y+ physical=p+</programlisting>
|
|
|
|
<para>In this configuration, 'x+' is the logical name for ports p+ on
|
|
bridge br0 while 'y+' is the logical name for ports p+ on bridge
|
|
br1.</para>
|
|
|
|
<para>If you need to refer to a particular port on br1 (for example
|
|
p1023), you write it as y1023; Shorewall will translate that name to p1023
|
|
when needed.</para>
|
|
|
|
<para>Example from /etc/shorewall/rules:</para>
|
|
|
|
<programlisting> #ACTION SOURCE DEST PROTO DPORT
|
|
REJECT z1:x1023 z1:x1024 tcp 1234</programlisting>
|
|
</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, which is also know as a brouter. 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/zones</filename> file is
|
|
modified:</para>
|
|
|
|
<programlisting>#ZONE TYPE OPTIONS
|
|
fw firewall
|
|
pub ipv4 #zone containing all public addresses
|
|
net:pub bport4
|
|
dmz:pub bport4
|
|
loc ipv4</programlisting>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>The <filename>/etc/shorewall/interfaces</filename> file is as
|
|
follows:<programlisting>#ZONE INTERFACE OPTIONS
|
|
pub br0 routefilter,bridge
|
|
net br0:eth0
|
|
dmz br0:eth2
|
|
loc eth1</programlisting></para>
|
|
</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>
|
|
|
|
<listitem>
|
|
<para>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:</para>
|
|
|
|
<para><filename>/etc/shorewall/params</filename>:</para>
|
|
|
|
<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</programlisting>
|
|
|
|
<para><filename>/etc/shorewall/policy</filename>:</para>
|
|
|
|
<programlisting>#SOURCE DEST POLICY LEVEL
|
|
loc <emphasis role="bold">pub</emphasis> ACCEPT
|
|
loc $FW REJECT info
|
|
loc all REJECT info
|
|
|
|
$FW <emphasis role="bold">pub</emphasis> 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</programlisting>
|
|
|
|
<para><filename>/etc/shorewall/rules</filename>:</para>
|
|
|
|
<programlisting>#ACTION SOURCE DEST PROTO DPORT SPORT
|
|
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 </programlisting>
|
|
</listitem>
|
|
</orderedlist>
|
|
</section>
|
|
|
|
<section id="veth">
|
|
<title>Using Back-to-back veth Devices to Interface with a Bridge</title>
|
|
|
|
<para>Beginning with Shorewall 4.4.26, Shorewall has limited support for
|
|
using back-to-back veth devices to interface with a bridge. This approach
|
|
has the advantage that traffic between any pair of zones can be filtered.
|
|
The disadvantage is the complexity of the approach.</para>
|
|
|
|
<para>This configuration is shown in the following diagram.</para>
|
|
|
|
<graphic align="center" fileref="images/veth1.png"/>
|
|
|
|
<para>In this configuration, veth0 is assigned the internal IP address;
|
|
br0 does not have an IP address.</para>
|
|
|
|
<para>Traffic from the <emphasis role="bold">net</emphasis> and <emphasis
|
|
role="bold">fw</emphasis> zones to the <emphasis
|
|
role="bold">zone<emphasis>i</emphasis></emphasis> zones goes thru
|
|
veth0->veth1->ethN->. Traffic from the <emphasis
|
|
role="bold">zone<emphasis>i</emphasis></emphasis> zones to the <emphasis
|
|
role="bold">fw</emphasis> and <emphasis role="bold">net</emphasis> zones
|
|
takes the reverse path: ethN->veth1->veth0. As a consequence,
|
|
traffic between <emphasis role="bold">net</emphasis>,<emphasis
|
|
role="bold">fw</emphasis> and <emphasis
|
|
role="bold">zone<emphasis>i</emphasis></emphasis> goes through Netfilter
|
|
twice: once in the routed firewall (eth0,veth0) and once in the bridged
|
|
firewall (eth1,eth2,eth3,veth1).</para>
|
|
|
|
<para>The back-to-back veth devices (veth0 and veth1) are created using
|
|
this command:</para>
|
|
|
|
<programlisting>ip link add type veth</programlisting>
|
|
|
|
<para>If you have veth devices and want to assign specific names to the
|
|
created devices, use this format:</para>
|
|
|
|
<programlisting>ip link add name FOO type veth peer name BAR</programlisting>
|
|
|
|
<para>Here's an /etc/network/interfaces stanza that configures veth0,
|
|
veth1 and the bridge:</para>
|
|
|
|
<programlisting>auto veth0
|
|
iface veth0 inet static
|
|
address 10.10.10.1
|
|
netmask 255.255.255.0
|
|
network 10.10.10.0
|
|
broadcast 10.10.10.255
|
|
|
|
pre-up /sbin/ip link add name veth0 type veth peer name veth1
|
|
pre-up /sbin/ip link set eth1 up
|
|
pre-up /sbin/ip link set eth2 up
|
|
|
|
pre-up /sbin/ip link set eth3 up
|
|
pre-up /sbin/ip link set veth1 up
|
|
pre-up /usr/sbin/brctl addbr br0
|
|
pre-up /usr/sbin/brctl addif br0 eth1
|
|
pre-up /usr/sbin/brctl addif br0 eth2
|
|
pre-up /usr/sbin/brctl addif br0 eth3
|
|
pre-up /usr/sbin/brctl addif br0 veth1
|
|
|
|
pre-down /usr/sbin/brctl delif br0 eth1
|
|
pre-down /sbin/ip link set eth2 down
|
|
pre-down /usr/sbin/brctl delif br0 eth2
|
|
pre-down /sbin/ip link set eth2 down
|
|
pre-down /usr/sbin/brctl delif br0 eth3
|
|
pre-down /sbin/ip link set eth3 down
|
|
pre-down /usr/sbin/brctl delif br0 veth1
|
|
pre-down /sbin/ip link set veth1 down
|
|
|
|
post-down /usr/sbin/brctl delbr br0
|
|
post-down /sbin/ip link del veth0</programlisting>
|
|
|
|
<para>In <ulink url="manpages/shorewall.net.html">shorewall.conf</ulink>
|
|
(5), we need this:</para>
|
|
|
|
<programlisting>ZONE_BITS=3</programlisting>
|
|
|
|
<para>This does two things:</para>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<para>It enables <firstterm>automatic packet
|
|
marking</firstterm>.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>It allows up to 7 <replaceable>marked</replaceable> zones (2**3
|
|
- 1). Zones are marked unless they have <option>nomark</option> in the
|
|
OPTIONS column of their entry in <ulink
|
|
url="manpages/shorewall-zones.html">shorewall-zones </ulink>(5).
|
|
Packets originating in a marked zone have a mark assigned
|
|
automatically by Shorewall.</para>
|
|
</listitem>
|
|
</orderedlist>
|
|
|
|
<para>For this configuration, we need several additional zones as shown
|
|
here:</para>
|
|
|
|
<programlisting>#ZONE TYPE OPTIONS IN_OPTIONS OUT_OPTIONS
|
|
fw firewall
|
|
net ipv4
|
|
zone1 bport
|
|
zone2 bport
|
|
zone3 bport
|
|
<emphasis role="bold">loc ipv4 nomark
|
|
col ipv4 nomark</emphasis></programlisting>
|
|
|
|
<note>
|
|
<para><emphasis role="bold">col</emphasis> is <emphasis
|
|
role="bold">loc</emphasis> spelled backward.</para>
|
|
</note>
|
|
|
|
<programlisting>#ZONE INTERFACES BROADCAST OPTIONS
|
|
net eth0 ...
|
|
- br0 ...
|
|
zone1 br0:eth1 ...
|
|
zone2 br0:eth2 ...
|
|
zone3 br0:eth3 ...
|
|
loc veth0 ...
|
|
col br0:veth1 ...</programlisting>
|
|
|
|
<para>Several things to note here</para>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<para>We have defined two unmarked zones: <emphasis
|
|
role="bold">loc</emphasis> and <emphasis role="bold">col</emphasis>.
|
|
This allows traffic from the <emphasis
|
|
role="bold">zone</emphasis><emphasis><emphasis
|
|
role="bold">i</emphasis></emphasis> zones to the fw and net zones to
|
|
retain the mark of their originating bport zones. It also allows
|
|
traffic from the <emphasis role="bold">fw</emphasis> and <emphasis
|
|
role="bold">net</emphasis> zones to the <emphasis
|
|
role="bold">zonei</emphasis> zones to retain the <emphasis
|
|
role="bold">fw</emphasis> and <emphasis role="bold">net</emphasis>
|
|
marks respectively.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>That means that traffic entering the bridge on veth1 will have a
|
|
different mark value, depending on whether it originated in the
|
|
<emphasis role="bold">net</emphasis> zone or in the <emphasis
|
|
role="bold">fw</emphasis> zone.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Similarly, traffic arriving on the veth0 interface will have a
|
|
mark that indicates which of the <emphasis
|
|
role="bold">zonei</emphasis> zones each packet originated on.</para>
|
|
</listitem>
|
|
</orderedlist>
|
|
|
|
<para>The basic idea here is that we want to filter traffic to the
|
|
<emphasis role="bold">zonei</emphasis> zones as it leaves veth1 and we
|
|
want to filter traffic from those zones as it leaves veth0. So we use this
|
|
type of polices:</para>
|
|
|
|
<programlisting>#SOURCE DEST POLICY
|
|
fw loc ACCEPT
|
|
net loc ACCEPT
|
|
net all DROP:info
|
|
zone1 col ACCEPT
|
|
zone2 col ACCEPT
|
|
zone3 col ACCEPT
|
|
all all REJECT:info</programlisting>
|
|
|
|
<para>Rules allowing traffic from the net to zone2 look like this:</para>
|
|
|
|
<programlisting>#ACTION SOURCE DEST PROTO DPORT SPORT ORIGDEST RATE USER MARK
|
|
ACCEPT col zone2 tcp 22 - - - - <emphasis
|
|
role="bold">net</emphasis></programlisting>
|
|
|
|
<para>or more compactly:</para>
|
|
|
|
<programlisting>#ACTION SOURCE DEST PROTO DPORT
|
|
ACCEPT col <emphasis role="bold">zone2</emphasis> tcp 22 ; mark=<emphasis
|
|
role="bold">net</emphasis></programlisting>
|
|
|
|
<para>Similarly, rules allowing traffic from the firewall to zone3:</para>
|
|
|
|
<programlisting>#ACTION SOURCE DEST PROTO DPORT
|
|
ACCEPT col <emphasis role="bold">zone3</emphasis> tcp 22 ; mark=<emphasis
|
|
role="bold">fw</emphasis></programlisting>
|
|
|
|
<para>The important point here is that, when ZONE_BITS is non-zero, you
|
|
are allowed to place zone names in the MARK column. Shorewall will
|
|
automatically replae the name with the zone's mark value.</para>
|
|
|
|
<para>Suppose that you want to forward tcp port 80 to 192.168.4.45 in
|
|
zone3:</para>
|
|
|
|
<programlisting>#ACTION SOURCE DEST PROTO DPORT SPORT ORIGDEST RATE USER MARK
|
|
DNAT- net loc:172.168.4.45 tcp 80
|
|
ACCEPT col zone3:172.168.4.45 tcp 80 - - - - <emphasis
|
|
role="bold">net</emphasis></programlisting>
|
|
|
|
<para>Rules allowing traffic from the <emphasis
|
|
role="bold">zonei</emphasis> zones to the <emphasis
|
|
role="bold">net</emphasis> zone look like this:</para>
|
|
|
|
<programlisting>#ACTION SOURCE DEST PROTO DPORT SPORT ORIGDEST RATE USER MARK
|
|
ACCEPT loc net tcp 21 - - - - <emphasis
|
|
role="bold">zone1</emphasis></programlisting>
|
|
|
|
<para>And to the firewall:</para>
|
|
|
|
<programlisting>#ACTION SOURCE DEST PROTO DPORT SPORT ORIGDEST RATE USER MARK
|
|
ACCEPT zone2 col tcp - - - - <emphasis
|
|
role="bold">zone2</emphasis></programlisting>
|
|
</section>
|
|
|
|
<section id="Limitations">
|
|
<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>
|
|
</article>
|