================================================== -=* Using Netfilter to Create a Masquerading Router *=- ================================================== T-Å Fransson Wed Jun 14 22:07:55 CEST 2000 TOC: 1) About this document 2) Requirements 3) Understanding iptables 4) Example network 1. About this document ====================== This document is not maintained. This is the latest version of it. If you do not understand what masquerading is, and if you never heard of Netfilter, I suggest you stop reading here. The reason I wrote this document was that I could not find a masquerading-HOWTO that was updated to use Netfilter (Linux kernel version 2.0 used a thing called ipfwadm, and v2.2 used something called ipchains). 1.1. License ------------ You are hereby granted to copy and distribute this document, in parts or as a whole, provided T-Å Fransson is recognized as the author. 2. Requirements =============== - Linux version 2.3.x or later (most likely 2.4.x) - Kernel compilation capability (You need to be able to configure and compile netlink and the iptable modules) - iptables-1.1.10 or later (ymmv) from http://netfilter.kernelnotes.org 2.1 Configuring your kernel for Netfilter ----------------------------------------- The kernel modules responsible for the actual work are: - ip_tables : provides the interface for Netfilter. - iptable_nat : provides NAT, Network Adress Translation - ipt_MASQUERADE : provides masquerading, a form of NAT - ip_conntrack : connection tracking, needed by iptable_nat and ipt_MASQUERADE. Netfilter also has a possibility to pass packets to user-space programs (not covered here), therefor you need the Kernel/User netlink socket. This is how I configured my 2.4.0-test1 kernel: under 'Networking Options' (make menuconfig)... ... [*] Kernel/User netlink socket [ ] Routing messages <*> Netlink device emulation [*] Network packet filtering (replaces ipchains) [ ] Network packet filtering debugging [ ] Socket Filtering ... ...and under 'IP: Netfilter Configuration': ... Connection tracking (required for masq/NAT) FTP protocol support < > Userspace queueing via NETLINK (EXPERIMENTAL) IP tables support (required for filtering/masq/NAT) < > limit match support MAC address match support < > netfilter MARK match support Multiple port match support < > TOS match support < > Connection state match support < > Unclean match support (EXPERIMENTAL) < > Owner match support (EXPERIMENTAL) Packet filtering REJECT target support MIRROR target support (EXPERIMENTAL) Full NAT MASQUERADE target support REDIRECT target support Packet mangling TOS target support MARK target support LOG target support ipchains (2.2-style) support ipfwadm (2.0-style) support ... obviously, i made some arbitrary choices on what to include, but it compiled ok. YMMV. 2.2 Installing iptables-1.1.10 ------------------------------ Simple, really. Just read the 'INSTALL' file in the tarball. 3. Understanding iptables ========================= What Netfilter gives you, is a number of 'tables', which contains 'chains' where you can set 'targets'. A target decides the destiny of a packet. Example of targets are: - ACCEPT : let the packet through and stop evaluating targets in this chain. - DROP : throw away the packet and stop evaluating targets in this chain. The default table is called 'filter' and contains the chains INPUT, FORWARD and OUTPUT. INPUT is typically where you want to set up DROP targets for packets coming from 'evil' hosts. Example: iptables -A INPUT -s 138.106.24.12 -j ACCEPT iptables -A INPUT -s 138.106.0.0/16 -j DROP This adds a DROP target in the chain INPUT. '-s' stands for 'source', so the above commands will make your host throw away packets coming from the network 138.106.*.*, _except_ packets from 138.106.24.12, which are let through (chains are evaluated top-down). To list the chain INPUT, use: iptables -L INPUT The FORWARD chain is used if your host is acting as router, i.e you have multiple interfaces and are forwarding traffic between them, this is used in section 4. If you want to make sure applications on your host do not contact certain other hosts, use the OUTPUT chain. Example: iptables -A OUTPUT -d 130.236.2.0/24 -p icmp -j DROP This rule stops icmp packets (ping) destined for the 130.236.2.x network, from leaving your host. When you insert the module iptable_nat, you get an extra table with three chains, PREROUTING, POSTROUTING and OUTPUT. These chains correspond to the chains in the default table, but are used for network adress translation. You also get some extra targets, most notably DNAT, SNAT and MASQUERADE. DNAT is for altering destination adress, SNAT is for altering the source adress. Example: iptables -t nat -A OUTPUT -p tcp -j DNAT --to-destination 205.188.146.23:80 iptables -t nat -A PREROUTING -p tcp \ -j DNAT --to-destination 207.46.131.137:80 Hosts, for which your host is routing, will always surf on www.microsoft.com, and users on your local host will always be directed to www.aol.com, no matter what URL they are typing >:) To delete a rule, you just replace the '-A' for add, with a '-D' for delete. To remove all rules in a chain, use '-F', so to remove the above added rules, the following is good: iptables -t nat -D OUTPUT -p tcp -j DNAT --to-destination 205.188.146.23:80 iptables -t nat -D PREROUTING -p tcp \ -j DNAT --to-destination 207.46.131.137:80 or, you can flush the chains completely with: iptables -t nat -F OUTPUT iptables -t nat -F PREROUTING The target MASQUERADE can be used in the POSTROUTING chain. This is a special form of SNAT, which makes packets beeing routed through your host look like they originate from _your_ host. This is especially useful when your LAN is sharing a dynamic ip link (typically ppp over modem). In section 4, this is covered more throughly. With Netfilter, you can do lots of other things. You can create your own chains, and have packets pass through them. User created chains are ('-j') jumped to just as other targets. Also, you can pass the packets to userspace programs and process them there (that is why you need Netlink, mentioned above). All of this is way beyond the scope of this document. Read the manual for iptables(8), and the various documents on http://netfilter.kernelnotes.org. 4. Example Network ================== Consider the following network: inet | | |212.130.17.23 *-----------------* 192.168.1.1| ppp0 |192.168.2.1 /----|eth0 eth1|------\ | | XXX | | | *-----------------* | | 192.168.1/24 eth0 | | 192.168.2/24 eth1 | | default ppp0 | | | | | | | | 192.168.1.2 | 192.168.2.2 *-----------------* *-----------------* | eth0 | | eth0 | | YYY | | ZZZ | *-----------------* *-----------------* 192.168.1/24 eth0 192.168.2/24 eth0 default 192.168.1.1 default 192.168.2.1 - The text under each box indicates the routing table - xxx.xxx.xxx.xxx/24 means netmask 255.255.255.0 (/16 means 255.255.0.0 and /22 means 255.255.252.0) This particular setup involves three computers, XXX, YYY and ZZZ, four network adapters (two in XXX, one each in YYY and ZZZ) and a modem, through which XXX connects to an ISP. Since the ISP only provides one IP address, simple forwarding won't work, should YYY and ZZZ want to open a connection to the outside world. Instead, XXX is masquerading for the other hosts. At the same time,XXX, YYY and ZZZ should be able to talk to eachother, and their true identity should be revealed, unless connections are made to the outside world. Note that YYY and ZZZ need not be Linux machines, since they are not performing any forwarding or NAT. To fulfill these needs, a rule in the POSTROUTING chain of the nat table on XXX is added: iptables -t nat -A POSTROUTING -d ! 192.168.0.0/22 -j MASQUERADE Elaborated, this means: "If the destination of a packet, beeing routed through this node, is not one of 192.168.0.*, 192.168.1.*,192.168.2.* or 192.168.3.*, give the packet a source adress of the interface, through which the package is leaving the node." 192.168.1.* and 192.168.2.* are the networks for YYY and ZZZ, so in other words, packets to YYY and ZZZ (and to XXX itself, ofcourse) are not masqueraded, while packets to other places are given the source adress of XXX's ppp0 interface (212.130.17.23). This ofcourse has the unwanted side effect that _anyone_ can use XXX as a masquerading gateway, and that is _bad_. To make sure XXX does not perform masquerading, or forwarding at all, for hosts other than those on the internal segment, add the following rules: iptables -A FORWARD -s 192.168.0.0/22 -j ACCEPT iptables -A FORWARD -d 192.168.0.0/22 -j ACCEPT iptables -A FORWARD -j DROP Packets coming from, or going to, the two (four, actually) internal segments are accepted for forwarding by XXX, all others are thrown away. The resulting chains are: (filtering table) [root@XXX /]# iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination ACCEPT all -- 192.168.0.0/22 anywhere ACCEPT all -- anywhere 192.168.0.0/22 DROP all -- anywhere anywhere Chain OUTPUT (policy ACCEPT) target prot opt source destination (nat table) [root@XXX /]# iptables -t nat -L Chain PREROUTING (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination MASQUERADE all -- anywhere !192.168.0.0/22 Chain OUTPUT (policy ACCEPT) target prot opt source destination Also, don't forget to enable ipv4 forwarding by echoing "1" to /proc/sys/net/ipv4/ip_forward Below is an example script to perform everything (call this from rc.local or equiv) --------------------------------- #!/bin/bash # insert modules insmod ip_tables insmod ip_conntrack insmod iptable_nat insmod ipt_MASQUERADE # set up masquerading for everything not destined to the localnets iptables -t nat -A POSTROUTING -d ! 192.168.0.0/22 -j MASQUERADE # only forward packages for our subnets iptables -A FORWARD -s 192.168.0.0/22 -j ACCEPT iptables -A FORWARD -d 192.168.0.0/22 -j ACCEPT iptables -A FORWARD -j DROP # enable forwarding echo "1" > /proc/sys/net/ipv4/ip_forward ---------------------------------- ================================================================ //T-Å