diff options
author | Bart De Schuymer <bdschuym@pandora.be> | 2002-07-09 19:41:34 +0000 |
---|---|---|
committer | Bart De Schuymer <bdschuym@pandora.be> | 2002-07-09 19:41:34 +0000 |
commit | 91ca1e2e15846feaf232d51a6d6925d0111a09a9 (patch) | |
tree | 15da7813a11ccddea89725c0bed95f41b24daafd /docs | |
parent | f2f84d7fc5f85210fc6babd038d0cb4d1a63ddb4 (diff) |
*** empty log message ***
Diffstat (limited to 'docs')
-rw-r--r-- | docs/br_fw_ia/br_fw_ia.html | 634 |
1 files changed, 634 insertions, 0 deletions
diff --git a/docs/br_fw_ia/br_fw_ia.html b/docs/br_fw_ia/br_fw_ia.html new file mode 100644 index 0000000..25cf769 --- /dev/null +++ b/docs/br_fw_ia/br_fw_ia.html @@ -0,0 +1,634 @@ +<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN' +'http://www.w3.org/TR/html4/strict.dtd'> +<HTML> + <HEAD> + <TITLE> + ebtables/iptables interaction on a Linux-based bridge + </TITLE> + <META HTTP-EQUIV="Content-Type" CONTENT= + "text/html; charset=iso-8859-1"> + <LINK REL="STYLESHEET" TYPE="text/css" HREF="ebtables.css"> + </HEAD> + <BODY> + <DIV CLASS="bar"> + <DIV CLASS="shadow"> + <H1 ALIGN="center"> + ebtables/iptables interaction on a Linux-based bridge + </H1> + </DIV> + </DIV> + <H3> + <A NAME="top">Table of Contents</A> + </H3> + <OL> + <LI> + <A HREF="#section1">Introduction</A> + </LI> + <LI> + <A HREF="#section2">How frames traverse the + <EM>ebtables</EM> chains</A> + </LI> + <LI> + <A HREF="#section3">A machine used as a bridge and a + router (not a brouter)</A> + </LI> + <LI> + <A HREF="#section4">DNAT'ing bridged packets</A> + </LI> + <LI> + <A HREF="#section5">Chain traversal for bridged IP packets</A> + </LI> + <LI> + <A HREF="#section6">Using a bridge port in <EM>iptables</EM> rules</A> + </LI> + <LI> + <A HREF="#section7">Two possible ways for frames/packets + to pass through the <EM>iptables</EM> PREROUTING, FORWARD and + POSTROUTING chains</A> + </LI> + <LI> + <A HREF="#section8">IP DNAT in the <EM>iptables</EM> PREROUTING + chain on frames/packets entering on a bridge port</A> + </LI> + <LI> + <A HREF="#section9">Using the MAC module extension for + <EM>iptables</EM></A> + </LI> + </OL> + <A NAME="section1"></A> + <P CLASS="section"> + 1. Introduction + </P> + <P> + This document describes how <EM>iptables</EM> and + <EM>ebtables</EM> filtering tables interact on a Linux-based bridge.<BR> + Getting a bridging firewall consists of patching the kernel source + code with two patches. The first patch is called "br-nf" and makes + bridged IP frames/packets go through the <EM>iptables</EM> chains. + The second patch adds <EM>ebtables</EM> support in the kernel. + <EM>Ebtables</EM> filters on the Ethernet layer, while <EM>iptables</EM> + only filters IP packets.<BR> + It is possible to use <EM>ebtables</EM> without compiling the br-nf + code into the kernel. The only reason why the <EM>ebtables</EM> patch + has to be applied after the br-nf patch is because some files are + changed by both patches. + </P> + <A NAME="section2"></A> + <P CLASS="section"> + 2. How frames traverse the <EM>ebtables</EM> chains + </P> + <DIV CLASS="note"> + This section only considers <EM>ebtables</EM>, not + <EM>iptables</EM>. + </DIV> + <P> + First thing to keep in mind is that we are talking about + the Ethernet layer here, so the OSI layer 2 (Data link + layer), or layer 1 (Link layer, Network Access layer) by the TCP/IP Network + Model. All samples below will be explained according to the TCP/IP + Network Model. + </P> + <P> + A packet destined for the local computer according to the + bridge (which works on the Ethernet layer) isn't + necessarily destined for the local computer according to + the IP layer. That's how routing works (MAC destination is + the router, IP destination is the actual box you want to + communicate with). + </P> + <P> + <IMG SRC="bridge2a.png"> + </P> + <P> + <I><B>Figure 2a.</B> General frame traversal scheme</I><BR> + </P> + <P> + </P> + <P> + There are five hooks defined in the Linux bridging code. + The sixth hook (BROUTING) is added by the <EM>ebtables</EM> patch. + The hooks are places in the network + code where software can hook itself in to process the + packets/frames passing that hook. + </P> + <BR> + <BR> + <IMG SRC="bridge2b.png"> + <P> + <I><B>Figure 2b.</B> Ethernet Bridging hooks</I><BR> + </P> + <BR> + <BR> + <IMG SRC="bridge2c.png"> + <P> + <I><B>Figure 2c.</B> Bridging tables (ebtables) traversal + process</I><BR> + </P> + <P> + <EM>Ebtables</EM> has three built in tables: + <B>filter</B>, <B>nat</B> and <B>broute</B>, as shown in Figure 2c. + </P> + <UL> + <LI> + The <FONT COLOR="#00ffff"><B>broute</B></FONT> table has + the BROUTING chain. + </LI> + <LI> + The <FONT COLOR="#00ffff"><B>filter</B></FONT> table has + the FORWARD, INPUT and OUTPUT chains. + </LI> + <LI> + The <FONT COLOR="#00ffff"><B>nat</B></FONT> table has the + PREROUTING, OUTPUT and POSTROUTING chains. + </LI> + </UL> + <BR> + <DIV CLASS="note"> + The filter OUTPUT and nat OUTPUT chains are separated and have + a different usage. + </DIV> + <P> + Figures 2b and 2c give a clear view where the + <EM>ebtables</EM> chains are hooked into the bridge code. + </P> + <P> + When a NIC enslaved to a bridge receives a frame, the frame + will first go through the BROUTING chain. In this special + chain you can choose whether to route or bridge frames, + enabling you to make a brouter. The definitions found on + the Internet for what a brouter actually is differ a bit. + The next definition describes the brouting ability using the + BROUTING chain quite well: + </P> + <DIV CLASS="note"> + A brouter is a device which + bridges some frames/packets (i.e. forwards based on Link layer + information) and routes other frames/packets (i.e. forwards based + on Network layer information). The bridge/route decision is + based on configuration information. + </DIV> + <P> + A brouter can be used, for example, + to act as a normal router for IP traffic between 2 + networks, while bridging specific traffic (NetBEUI, ARP, + whatever) between those networks. The IP routing + table does not use the bridge logical device and the box has + IP addresses assigned to the physical network devices that + also happen to be bridge ports (bridge enslaved NICs).<BR> + The default decision in the BROUTING chain is bridging. + </P> + <P> + Next the frame passes through the PREROUTING chain. + In this chain you can alter the destination MAC address + of frames (DNAT). + If the frame passes this chain, the bridging code will decide where the + frame should be sent. The bridge does this by looking at + the destination MAC address, it doesn't care about the + Network layer addresses (e.g. IP address). + </P> + <DIV CLASS="note"> + Incoming frames on non-forwarding ports of a bridge will + not be seen by <EM>ebtables</EM>, not even by the BROUTING + chain. + </DIV> + <P> + If the bridge decides the frame is destined for the local + computer, the frame will go through the INPUT chain. + In this chain you can filter frames destined for the bridge box. + After traversal of the INPUT chain, the frame will be passed up + to the Network layer code (e.g. to the IP code). + So, a routed IP packet will go through + the <EM>ebtables</EM> INPUT chain, not through the + <EM>ebtables</EM> FORWARD chain. This is logical. + </P> + <BR> + <BR> + <IMG SRC="bridge2d.png"> + <P> + <I><B>Figure 2d.</B> Incoming frames' chain traversal</I><BR> + </P> + <P> + Otherwise the frame should possibly be sent onto another side + of the bridge. If it should, the frame will go through the + FORWARD chain and the POSTROUTING chain. The bridged frames can be + filtered in the FORWARD chain. In the POSTROUTING chain you can alter the MAC + source address (SNAT). + </P> + <BR> + <BR> + <IMG SRC="bridge2e.png"> + <P> + <I><B>Figure 2e.</B> Forwarded frames' chain traversal</I><BR> + </P> + <P> + Locally originated frames will, after the bridging decision, traverse + the nat OUTPUT, the filter OUTPUT and the nat POSTROUTING chains. + The nat OUTPUT chain allows to alter the destination + MAC address and the filter OUTPUT chain allows to + filter frames originating from the bridge box. Note that + the nat OUTPUT chain is traversed after the bridging + decision, so this is actually too late. We should change this. The nat + POSTROUTING chain is the same one as described above. + </P> + <BR> + <BR> + <IMG SRC="bridge2f.png"> + <P> + <I><B>Figure 2f.</B> Outgoing frames' chain traversal</I><BR> + </P> + <DIV CLASS="note"> + It's also possible for routed frames to go + through these three chains when the destination + device is a logical bridge device. + </DIV> + <BR> + <BR> + <A NAME="section3"></A> + <P CLASS="section"> + 3. A machine used as a bridge and a router (not a brouter) + </P> + <P> + Here is the IP code hooks scheme: + </P> + <IMG SRC="bridge3a.png"> + <P> + <I><B>Figure 3a.</B> IP code hooks</I><BR> + </P> + <P> + Here is the iptables packet traversal scheme. + </P> + <BR> + <BR> + <IMG SRC="bridge3b.png"> + <P> + <I><B>Figure 3b.</B> Routing tables (iptables) traversal + process</I><BR> + </P> + <P> + Note that the iptables nat OUTPUT chain is situated after the + routing decision. As commented in the previous section, + this is too late for DNAT. This is solved by rerouting the + IP packet if it has been DNAT'ed, before continuing. + </P> + <P> + Figures 3a and 3b give a clear view where the + <EM>iptables</EM> chains are hooked into the IP code. When the br-nf + patch is compiled into the kernel, the iptables chains are + also hooked in the hooks of the bridging code. However, + this does not mean that they are no longer hooked into their + standard IP code hooks. For IP packets that get into + contact with the bridging code, the br-nf patch will + decide in which place in the network code the <EM>iptables</EM> + chains are traversed. Obviously, it is guaranteed that no chain is + traversed twice by the same packet. All packets that do not come into + contact with the bridge code traverse the <EM>iptables</EM> chains + in the standard way as seen in Figure 3b.<BR> + The following sections try, among other things, + to explain what the br-nf patch does and why it does it. + </P> + <P> + It's possible to see a single IP packet/frame traverse the + nat PREROUTING, filter INPUT, nat OUTPUT, filter OUTPUT and + nat POSTROUTING <EM>ebtables</EM> chains.<BR> + This can happen when the bridge is also used as a router. + The Ethernet frame(s) containing that IP packet will have + the bridge's destination MAC address, while the destination + IP address is not of the bridge. Including the + <EM>iptables</EM> chains and assuming the br-nf code is + compiled into the kernel, this is how the IP packet runs + through the bridge/router (actually there is more going on, + see <A HREF="#section6">section 6</A>): + </P> + <P> + <IMG SRC="bridge3c.png"> + </P> + <P> + <I><B>Figure 3c.</B> Bridge/router routes packet to a + bridge interface (simplistic view)</I><BR> + </P> + <P> + This assumes that the routing decision sends the packet to + a bridge interface. If the routing decision sends the + packet to a physical network card, this is what happens: + </P> + <P> + <IMG SRC="bridge3d.png"> + </P> + <P> + <I><B>Figure 3d.</B> Bridge/router routes packet to a + physical interface (simplistic view)</I><BR> + </P> + <P> + What is obviously "asymmetric" here is that the + <EM>iptables</EM> PREROUTING chain is traversed before the + <EM>ebtables</EM> INPUT chain, however this cannot be + helped without sacrificing other functionality. See the + next section. + </P> + <A NAME="section4"></A> + <P CLASS="section"> + 4. DNAT'ing bridged packets + </P> + <P> + Take an IP packet received by the bridge. Let's assume we + want to do some IP DNAT on it. + Changing the destination address of the packet (IP address + and MAC address) has to happen before the bridge code + decides what to do with the frame/packet. + The decision of the bridge code can be one of these: + <ul> + <li>bridge it, if the destination MAC address is on + another side of the bridge;</li> + <li>flood it over all the forwarding bridge ports, if the + position of the box with the destination MAC is unknown + to the bridge;</li> + <li>pass it to the higher protocol code (the IP code), + if the destination MAC address is that of the bridge or of + one of its ports;</li> + <li>ignore it, if the destination MAC address is located + on the same side of the bridge.</li> + </ul> + </P> + <P> + So, this IP DNAT has to happen very early in the bridge + code. Namely before the bridge code actually does anything. + This is at the same place as where the <EM>ebtables</EM> nat + PREROUTING chain will be traversed (for the same reason). + This should explain the asymmetry encountered in Figures 3c + and 3d. + </P> + <A NAME="section5"></A> + <P CLASS="section"> + 5. Chain traversal for bridged IP packets + </P> + <P> + A bridged packet never enters any network code above layer + 1 (Link layer). So, a bridged IP packet/frame will never enter the + IP code. + Therefore all <EM>iptables</EM> chains will be traversed + while the IP packet is in the bridge code. The chain + traversal will look like this: + </P> + <P> + <IMG SRC="bridge5.png"> + </P> + <P> + <I><B>Figure 5.</B> Chain traversal for bridged IP + packets</I><BR> + </P> + <A NAME="section6"></A> + <P CLASS="section"> + 6. Using a bridge port in <EM>iptables</EM> rules + </P> + <P> + The wish to be able to use physical devices belonging to a + bridge (bridge ports) in <EM>iptables</EM> rules is valid. + Knowing the input bridge ports is necessary to prevent + spoofing attacks. Say br0 has ports eth0 and eth1. If + <EM>iptables</EM> rules can only use br0 there's no way of + knowing when a box on the eth0 side changes its source IP + address to that of a box on the eth1 side, except by + looking at the MAC source address (and then still...). With + the br-nf patch you can use eth0 and eth1 in your + <EM>iptables</EM> rules and therefore catch these attempts. + </P> + <P CLASS="case"> + 6.1. <EM>iptables</EM> wants to use the bridge destination + ports: + </P> + <P> + To make this possible the <EM>iptables</EM> chains have to + be traversed after the bridge code decided where the frame + needs to be sent (eth0, eth1, both or none). This has some + impact on the scheme presented in <A HREF= + "#section3">section 3</A> (so, we are looking at routed + traffic here). It actually looks like this (in the case of + Figure 3c): + </P> + <P> + <IMG SRC="bridge6a.png"> + </P> + <P> + <I><B>Figure 6a.</B> Chain traversal when routing and br-nf + is compiled into the kernel</I><BR> + </P> + <DIV CLASS="note"> + All chains are now traversed while in the bridge code.<BR> + This is the work of the br-nf patch. Obviously this does not + mean that the routed IP packets never enter the IP code. They + just don't pass any <EM>iptables</EM> chains while in the IP code. + </DIV> + <P> + If one does not compile the br-nf code into the kernel, the + chains will be traversed as shown below. However, then one + can only use br0, not eth0/eth1 to filter. + </P> + <P> + <IMG SRC="bridge6b.png"> + </P> + <P> + <I><B>Figure 6b.</B> Chain traversal when routing and br-nf + code is not compiled into the kernel</I><BR> + </P> + <P> + Notice that the <EM>iptables</EM> PREROUTING chain is now in + the natural position in the chain list and too far to be able + to change the bridging decision. More precise: the <EM>iptables</EM> + PREROUTING chain is now traversed when the packet is already + in the IP code. + </P> + <P CLASS="case"> + 6.2. IP DNAT for locally generated packets (so in the + <EM>iptables</EM> nat OUTPUT chain): + </P> + <P> + The 'normal' way locally generated packets would go through + the chains looks like this: + </P> + <P> + <IMG SRC="bridge6c.png"> + </P> + <P> + <I><B>Figure 6c.</B> The 'normal' way for locally generated + packets</I><BR> + </P> + <P> + From <A HREF="#section6">section 6.1</A> we know that this + actually looks like this (due to the br-nf code): + </P> + <P> + <IMG SRC="bridge6d.png"> + </P> + <P> + <I><B>Figure 6d.</B> The 'actual' way for locally generated + packets</I><BR> + </P> + <P> + Note that the <EM>iptables</EM> nat OUTPUT chain is traversed while the + packet is in the IP code, while the <EM>iptables</EM> filter OUTPUT chain + is traversed when the packet has entered the bridge code. + This makes it possible to do DNAT to another device in the + nat OUTPUT chain and lets us use the bridge ports in the + filter OUTPUT chain. + </P> + <P> + Note that in Figures 6a and 6d the <EM>iptables</EM> + POSTROUTING chain is traversed before the <EM>ebtables</EM> + POSTROUTING chain, while it's the way around for Figure 5. + The rule is as follows: + </P> + <DIV CLASS="note"> + for bridged traffic the <EM>ebtables</EM> POSTROUTING chain + is traversed before the <EM>iptables</EM> POSTROUTING chain, + for all other traffic it's the way around. + </DIV> + <A NAME="section7"></A> + <P CLASS="section"> + 7. Two possible ways for frames/packets to pass through the + <EM>iptables</EM> PREROUTING, FORWARD and POSTROUTING + chains + </P> + <P> + With the br-nf patch there are 2 ways a frame/packet can + pass through the 3 given <EM>iptables</EM> chains. The + first way is when the frame is bridged, so the + <EM>iptables</EM> chains are called by the bridge code. The + second way is when the packet is routed. So special care + has to be taken to distinguish between those two, + especially in the <EM>iptables</EM> FORWARD chain. Here's + an example of strange things to look out for: + </P> + <P> + Consider the following situation + </P> + <P> + <IMG SRC="bridge7a.png"> + </P> + <P> + <I><B>Figure 7a.</B> Very basic setup.</I><BR> + </P> + <P> + The default gateway for 172.16.1.2 and + 172.16.1.4 is 172.16.1.1. 172.16.1.1 is the bridge + interface br0 with ports eth1 and eth2. + </P> + <P CLASS="case"> + More details: + </P> + <P> + The idea is that traffic between 172.16.1.4 and 172.16.2 is + bridged, while the rest is routed, using masquerading. + </P> + <P> + <IMG SRC="bridge7b.png"> + </P> + <P> + <I><B>Figure 7b.</B> Traffic flow for the example setup.</I><BR> + </P> + <P> + Here's a possible scheme to use at bootup for the bridge/router: + </P> +<PRE> +iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -d 172.16.1.0/24 -j ACCEPT +iptables -t nat -A POSTROUTING -s 172.16.1.0/24 -j MASQUERADE + +brctl addbr br0 +brctl stp br0 off +brctl addif br0 eth1 +brctl addif br0 eth2 + +ifconfig eth1 0 0.0.0.0 +ifconfig eth2 0 0.0.0.0 +ifconfig br0 172.16.1.1 netmask 255.255.255.0 up + +echo '1' > /proc/sys/net/ipv4/ip_forward +</PRE> + <P> + The catch is in the first line. Because the + <EM>iptables</EM> code gets executed for both bridged + packets and routed packets we need to make a distinction + between the two. We don't really want the bridged frames/packets + to be masqueraded. If we omit the first line then + everything will work too, but things will happen + differently. Let's say 172.16.1.2 pings 172.16.1.4. The + bridge receives the ping request and will transmit it + through its eth1 port after first masquerading the IP + address. So the packet's source IP address will now be + 172.16.1.1 and 172.16.1.4 will respond to the bridge. + Masquerading will change the IP destination of this + response from 172.16.1.1 to 172.16.1.4. Everything works + fine. But it's better not to have this behaviour. Thus, we + use the first line to avoid this. Note that + if we would want to filter the connections to and from the + internet, we would certainly need the first line so we don't + filter the local connections as well. + </P> + <A NAME="section8"></A> + <P CLASS="section"> + 8. IP DNAT in the <EM>iptables</EM> PREROUTING chain on + frames/packets entering on a bridge port + </P> + <P> + Through some groovy play it is assured that (see + /net/bridge/br_netfilter.c) DNAT'ed packets that after + DNAT'ing have the same output device as the input device + they came on (the logical bridge device which we like to + call br0) will go through the <EM>ebtables</EM> FORWARD + chain, not through the <EM>ebtables</EM> INPUT/OUTPUT chains. All + other DNAT'ed packets will be purely routed, so won't go + through the <EM>ebtables</EM> FORWARD chain, will go through + the <EM>ebtables</EM> INPUT chain and might go through the + <EM>ebtables</EM> OUTPUT chain.<BR> + </P> + <A NAME="section9"></A> + <P CLASS="section"> + 9. Using the MAC module extension for <EM>iptables</EM> + </P> + <P> + The side effect explained here occurs when the br-nf code + is compiled in the kernel, the IP packet is routed and the + out device for that packet is a logical bridge device. The + side effect is encountered when filtering on the MAC source + in the <EM>iptables</EM> FORWARD chains. As should be clear + from earlier sections, the traversal of the + <EM>iptables</EM> FORWARD chains is postponed until the + packet is in the bridge code. This is done so we can + filter on the bridge port out device. This has a side + effect on the MAC source address, because the IP code will + have changed the MAC source address to the MAC address of + the bridge device. It is therefore impossible, in the + <EM>iptables</EM> FORWARD chains, to filter on the MAC + source address of the computer sending the packet in + question to the bridge/router. If you really need to filter + on this MAC source address, you should do it in the nat + PREROUTING chain. Agreed, very ugly, but making it possible + to filter on the real MAC source address in the FORWARD + chains would involve a very dirty hack and is probably not + worth it. This of course makes the anti-spoofing remark of + <A HREF="#section5">section 6</A> funny. If I'm [BDS] + pressured enough I could hack something up to make this + unpleasant side effect go away. + </P> + <HR> +<PRE> +Released under the GNU Free Documentation License. +Copyright (c) 2002 Bart De Schuymer <bart.de.schuymer@pandora.be>, + Nick Fedchik <nick@fedchik.org.ua>. +</PRE> + <BR> + <BR> + <BR> + <SMALL>Permission is granted to copy, distribute and/or + modify this document under the terms of the GNU Free + Documentation License, Version 1.1 or any later version + published by the Free Software Foundation, with no Invariant Sections, + with no Front-Cover Texts, and with no Back-Cover Texts. For a copy of the + license, see <A HREF= + "http://www.gnu.org/licenses/fdl.txt">"GNU Free Documentation License"</A>.</SMALL> <BR> + <BR> + <P> + Last updated July 9, 2002. + </P> + </BODY> +</HTML> + |