3438 lines
111 KiB
Plaintext
3438 lines
111 KiB
Plaintext
|
Linux IPCHAINS-HOWTO
|
|||
|
Rusty Russell
|
|||
|
v1.0.8, Tue Jul 4 14:20:53 EST 2000
|
|||
|
|
|||
|
This document aims to describe how to obtain, install and configure
|
|||
|
the enhanced IP firewalling chains software for Linux, and some ideas
|
|||
|
on how you might use them.
|
|||
|
______________________________________________________________________
|
|||
|
|
|||
|
Table of Contents
|
|||
|
|
|||
|
|
|||
|
|
|||
|
1. Introduction
|
|||
|
|
|||
|
1.1 What?
|
|||
|
1.2 Why?
|
|||
|
1.3 How?
|
|||
|
1.4 Where?
|
|||
|
|
|||
|
2. Packet Filtering Basics
|
|||
|
|
|||
|
2.1 What?
|
|||
|
2.2 Why?
|
|||
|
2.3 How?
|
|||
|
2.3.1 A Kernel With Packet Filtering
|
|||
|
2.3.2 ipchains
|
|||
|
2.3.3 Making Rules Permanent
|
|||
|
|
|||
|
3. I'm confused! Routing, masquerading, portforwarding, ipautofw...
|
|||
|
|
|||
|
3.1 Rusty's Three-Line Guide To Masquerading
|
|||
|
3.2 Gratuitous Promotion: WatchGuard Rules
|
|||
|
3.3 Common Firewall-like Setups
|
|||
|
3.3.1 Private Network: Traditional Proxies
|
|||
|
3.3.2 Private Network: Transparent Proxies
|
|||
|
3.3.3 Private Network: Masquerading
|
|||
|
3.3.4 Public Network
|
|||
|
3.3.5 Limited Internal Services
|
|||
|
3.4 More Information on Masquerading
|
|||
|
|
|||
|
4. IP Firewalling Chains
|
|||
|
|
|||
|
4.1 How Packets Traverse The Filters
|
|||
|
4.1.1 Using ipchains
|
|||
|
4.1.2 What You'll See When Your Computer Starts Up
|
|||
|
4.1.3 Operations on a Single Rule
|
|||
|
4.1.4 Filtering Specifications
|
|||
|
4.1.4.1 Specifying Source and Destination IP Addresses
|
|||
|
4.1.4.2 Specifying Inversion
|
|||
|
4.1.4.3 Specifying Protocol
|
|||
|
4.1.4.3.1 Specifying UDP and TCP Ports
|
|||
|
4.1.4.3.2 Specifying ICMP Type and Code
|
|||
|
4.1.4.4 Specifying an Interface
|
|||
|
4.1.4.5 Specifying TCP SYN Packets Only
|
|||
|
4.1.4.6 Handling Fragments
|
|||
|
4.1.5 Filtering Side Effects
|
|||
|
4.1.5.1 Specifying a Target
|
|||
|
4.1.5.2 Logging Packets
|
|||
|
4.1.5.3 Manipulating the Type Of Service
|
|||
|
4.1.5.4 Marking a Packet
|
|||
|
4.1.5.5 Operations on an Entire Chain
|
|||
|
4.1.5.6 Creating a New Chain
|
|||
|
4.1.5.7 Deleting a Chain
|
|||
|
4.1.5.8 Flushing a Chain
|
|||
|
4.1.5.9 Listing a Chain
|
|||
|
4.1.5.10 Resetting (Zeroing) Counters
|
|||
|
4.1.5.11 Setting Policy
|
|||
|
4.1.6 Operations on Masquerading
|
|||
|
4.1.7 Checking a Packet
|
|||
|
4.1.8 Multiple Rules at Once and Watching What Happens
|
|||
|
4.2 Useful Examples
|
|||
|
4.2.1 Using ipchains-save
|
|||
|
4.2.2 Using ipchains-restore
|
|||
|
|
|||
|
5. Miscellaneous.
|
|||
|
|
|||
|
5.1 How to Organize Your Firewall Rules
|
|||
|
5.2 What Not To Filter Out
|
|||
|
5.2.1 ICMP packets
|
|||
|
5.2.2 TCP Connections to DNS (nameservers)
|
|||
|
5.2.3 FTP Nightmares
|
|||
|
5.3 Filtering out Ping of Death
|
|||
|
5.4 Filtering out Teardrop and Bonk
|
|||
|
5.5 Filtering out Fragment Bombs
|
|||
|
5.6 Changing Firewall Rules
|
|||
|
5.7 How Do I Set Up IP Spoof Protection?
|
|||
|
5.8 Advanced Projects
|
|||
|
5.8.1 SPF: Stateful Packet Filtering
|
|||
|
5.8.2 Michael Hasenstein's ftp-data hack
|
|||
|
5.9 Future Enhancements
|
|||
|
|
|||
|
6. Common Problems
|
|||
|
|
|||
|
6.1 ipchains -L Freezes!
|
|||
|
6.2 Inverse doesn't work!
|
|||
|
6.3 Masquerading/Forwarding Doesn't Work!
|
|||
|
6.4 -j REDIR doesn't work!
|
|||
|
6.5 Wildcard Interfaces Don't Work!
|
|||
|
6.6 TOS Doesn't Work!
|
|||
|
6.7 ipautofw and ipportfw Don't Work!
|
|||
|
6.8 xosview is Broken!
|
|||
|
6.9 Segmentation Fault With `-j REDIRECT'!
|
|||
|
6.10 I Can't Set Masquerading Timeouts!
|
|||
|
6.11 I Want to Firewall IPX!
|
|||
|
|
|||
|
7. A Serious Example.
|
|||
|
|
|||
|
7.1 The Arrangement
|
|||
|
7.2 Goals
|
|||
|
7.3 Before Packet Filtering
|
|||
|
7.4 Packet Filtering for Through Packets
|
|||
|
7.4.1 Set Up Jumps From forward Chain
|
|||
|
7.4.2 Define the icmp-acc Chain
|
|||
|
7.4.3 Good (Internal) to DMZ (Servers)
|
|||
|
7.4.4 Bad (external) to DMZ (servers).
|
|||
|
7.4.5 Good (internal) to Bad (external).
|
|||
|
7.4.6 DMZ to Good (internal).
|
|||
|
7.4.7 DMZ to bad (external).
|
|||
|
7.4.8 Bad (external) to Good (internal).
|
|||
|
7.4.9 Packet Filtering for the Linux Box Itself
|
|||
|
7.4.9.1 Bad (external) interface.
|
|||
|
7.4.9.2 DMZ interface.
|
|||
|
7.4.9.3 Good (internal) interface.
|
|||
|
7.5 Finally
|
|||
|
|
|||
|
8. Appendix: Differences between ipchains and ipfwadm.
|
|||
|
|
|||
|
8.1 Quick-Reference table.
|
|||
|
8.2 Examples of translated ipfwadm commands
|
|||
|
|
|||
|
9. Appendix: Using the ipfwadm-wrapper script.
|
|||
|
|
|||
|
10. Appendix: Thanks.
|
|||
|
|
|||
|
10.1 Translations
|
|||
|
|
|||
|
|
|||
|
______________________________________________________________________
|
|||
|
|
|||
|
1. Introduction
|
|||
|
|
|||
|
This is the Linux IPCHAINS-HOWTO; see ``Where?'' for the master site,
|
|||
|
which contains the latest copy. You should read the Linux NET-3-HOWTO
|
|||
|
as well. The IP-Masquerading HOWTO, the PPP-HOWTO, the Ethernet-HOWTO
|
|||
|
and the Firewall HOWTO might make interesting reading. (Then again,
|
|||
|
so might the alt.fan.bigfoot FAQ).
|
|||
|
|
|||
|
|
|||
|
If packet filtering is passe to you, read Section ``Why?'', Section
|
|||
|
``How?'', and scan through the titles in Section ``IP Firewalling
|
|||
|
Chains''.
|
|||
|
|
|||
|
|
|||
|
If you are converting from ipfwadm, read Section ``Introduction'',
|
|||
|
Section ``How?'', and Appendices in section ``Differences between
|
|||
|
ipchains and ipfwadm'' and section ``Using the `ipfwadm-wrapper'
|
|||
|
script''.
|
|||
|
|
|||
|
|
|||
|
1.1. What?
|
|||
|
|
|||
|
Linux ipchains is a rewrite of the Linux IPv4 firewalling code (which
|
|||
|
was mainly stolen from BSD) and a rewrite of ipfwadm, which was a
|
|||
|
rewrite of BSD's ipfw, I believe. It is required to administer the IP
|
|||
|
packet filters in Linux kernel versions 2.1.102 and above.
|
|||
|
|
|||
|
|
|||
|
1.2. Why?
|
|||
|
|
|||
|
The older Linux firewalling code doesn't deal with fragments, has
|
|||
|
32-bit counters (on Intel at least), doesn't allow specification of
|
|||
|
protocols other than TCP, UDP or ICMP, can't make large changes
|
|||
|
atomically, can't specify inverse rules, has some quirks, and can be
|
|||
|
tough to manage (making it prone to user error).
|
|||
|
|
|||
|
|
|||
|
1.3. How?
|
|||
|
|
|||
|
Currently the code is in the mainstream kernel from 2.1.102. For the
|
|||
|
2.0 kernel series, you will need to download a kernel patch from the
|
|||
|
web page. If your 2.0 kernel is more recent than the supplied patch,
|
|||
|
the older patch should be OK; this part of the 2.0 kernels is fairly
|
|||
|
stable (eg. the 2.0.34 kernel patch works just fine on the 2.0.35
|
|||
|
kernel). Since the 2.0 patch is incompatible with the ipportfw and
|
|||
|
ipautofw patches, I don't recommend applying it unless you really need
|
|||
|
some functionality that ipchains offers.
|
|||
|
|
|||
|
|
|||
|
1.4. Where?
|
|||
|
|
|||
|
The official page is in three places: Thanks to Penguin Computing
|
|||
|
<http://netfilter.filewatcher.org/ipchains> Thanks to the SAMBA Team
|
|||
|
<http://www.samba.org/netfilter/ipchains> Thanks to Jim Pick
|
|||
|
<http://netfilter.kernelnotes.org/ipchains>
|
|||
|
|
|||
|
|
|||
|
There is a mailing list for bug reports, discussion, development and
|
|||
|
usage. Join the mailing list by sending a message containing the word
|
|||
|
``subscribe ipchains-list'' to subscribe at east.balius.com. To mail
|
|||
|
to everyone on the list use ipchains-list at east.balius.com.
|
|||
|
|
|||
|
|
|||
|
2. Packet Filtering Basics
|
|||
|
|
|||
|
2.1. What?
|
|||
|
|
|||
|
All traffic through a network is sent in the form of packets. For
|
|||
|
example, downloading this package (say it's 50k long) might cause you
|
|||
|
to receive 36 or so packets of 1460 bytes each, (to pull numbers at
|
|||
|
random).
|
|||
|
The start of each packet says where it's going, where it came from,
|
|||
|
the type of the packet, and other administrative details. This start
|
|||
|
of the packet is called the header. The rest of the packet,
|
|||
|
containing the actual data being transmitted, is usually called the
|
|||
|
body.
|
|||
|
|
|||
|
|
|||
|
Some protocols, such TCP, which is used for web traffic, mail, and
|
|||
|
remote logins, use the concept of a `connection' -- before any packets
|
|||
|
with actual data are sent, various setup packets (with special
|
|||
|
headers) are exchanged saying `I want to connect', `OK' and `Thanks'.
|
|||
|
Then normal packets are exchanged.
|
|||
|
|
|||
|
|
|||
|
A packet filter is a piece of software which looks at the header of
|
|||
|
packets as they pass through, and decides the fate of the entire
|
|||
|
packet. It might decide to deny the packet (ie. discard the packet as
|
|||
|
if it had never received it), accept the packet (ie. let the packet go
|
|||
|
through), or reject the packet (like deny, but tell the source of the
|
|||
|
packet that it has done so).
|
|||
|
|
|||
|
|
|||
|
Under Linux, packet filtering is built into the kernel, and there are
|
|||
|
a few trickier things we can do with packets, but the general
|
|||
|
principle of looking at the headers and deciding the fate of the
|
|||
|
packet is still there.
|
|||
|
|
|||
|
|
|||
|
2.2. Why?
|
|||
|
|
|||
|
Control. Security. Watchfulness.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Control:
|
|||
|
when you are using a Linux box to connect your internal network
|
|||
|
to another network (say, the Internet) you have an opportunity
|
|||
|
to allow certain types of traffic, and disallow others. For
|
|||
|
example, the header of a packet contains the destination address
|
|||
|
of the packet, so you can prevent packets going to a certain
|
|||
|
part of the outside network. As another example, I use Netscape
|
|||
|
to access the Dilbert archives. There are advertisements from
|
|||
|
doubleclick.net on the page, and Netscape wastes my time by
|
|||
|
cheerfully downloading them. Telling the packet filter not to
|
|||
|
allow any packets to or from the addresses owned by
|
|||
|
doubleclick.net solves that problem (there are better ways of
|
|||
|
doing this though).
|
|||
|
|
|||
|
|
|||
|
Security:
|
|||
|
when your Linux box is the only thing between the chaos of the
|
|||
|
Internet and your nice, orderly network, it's nice to know you
|
|||
|
can restrict what comes tromping in your door. For example, you
|
|||
|
might allow anything to go out from your network, but you might
|
|||
|
be worried about the well-known `Ping of Death' coming in from
|
|||
|
malicious outsiders. As another example, you might not want
|
|||
|
outsiders telnetting to your Linux box, even though all your
|
|||
|
accounts have passwords; maybe you want (like most people) to be
|
|||
|
an observer on the Internet, and not a server (willing or
|
|||
|
otherwise) -- simply don't let anyone connect in, by having the
|
|||
|
packet filter reject incoming packets used to set up
|
|||
|
connections.
|
|||
|
|
|||
|
|
|||
|
Watchfulness:
|
|||
|
sometimes a badly configured machine on the local network will
|
|||
|
decide to spew packets to the outside world. It's nice to tell
|
|||
|
the packet filter to let you know if anything abnormal occurs;
|
|||
|
maybe you can do something about it, or maybe you're just
|
|||
|
curious by nature.
|
|||
|
|
|||
|
|
|||
|
2.3. How?
|
|||
|
|
|||
|
2.3.1. A Kernel With Packet Filtering
|
|||
|
|
|||
|
You need a kernel which has the new IP firewall chains in it. You can
|
|||
|
tell if the kernel you are running right now has this installed by
|
|||
|
looking for the file `/proc/net/ip_fwchains'. If it exists, you're
|
|||
|
in.
|
|||
|
|
|||
|
|
|||
|
If not, you need to make a kernel that has IP firewall chains. First,
|
|||
|
download the source to the kernel you want. If you have a kernel
|
|||
|
numbered 2.1.102 or higher, you won't need to patch it (it's in the
|
|||
|
mainstream kernel now). Otherwise, apply the patch from the web page
|
|||
|
listed above, and set the configuration as detailed below. If you
|
|||
|
don't know how to do this, don't panic -- read the Kernel-HOWTO.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
The configuration options you will need to set for the 2.0-series
|
|||
|
kernel are:
|
|||
|
|
|||
|
|
|||
|
______________________________________________________________________
|
|||
|
CONFIG_EXPERIMENTAL=y
|
|||
|
CONFIG_FIREWALL=y
|
|||
|
CONFIG_IP_FIREWALL=y
|
|||
|
CONFIG_IP_FIREWALL_CHAINS=y
|
|||
|
______________________________________________________________________
|
|||
|
|
|||
|
|
|||
|
|
|||
|
For the 2.1 or 2.2 series kernels:
|
|||
|
|
|||
|
______________________________________________________________________
|
|||
|
CONFIG_FIREWALL=y
|
|||
|
CONFIG_IP_FIREWALL=y
|
|||
|
______________________________________________________________________
|
|||
|
|
|||
|
|
|||
|
|
|||
|
The tool ipchains talks to the kernel and tells it what packets to
|
|||
|
filter. Unless you are a programmer, or overly curious, this is how
|
|||
|
you will control the packet filtering.
|
|||
|
|
|||
|
|
|||
|
2.3.2. ipchains
|
|||
|
|
|||
|
The ipchains tool inserts and deletes rules from the kernel's packet
|
|||
|
filtering section. This means that whatever you set up, it will be
|
|||
|
lost upon reboot; see ``Making Rules Permanent'' for how to make sure
|
|||
|
they are restored the next time Linux is booted.
|
|||
|
|
|||
|
|
|||
|
ipchains replaces ipfwadm, which was used for the old IP Firewall
|
|||
|
code. There is a set of useful scripts available from the ipchains
|
|||
|
ftp site:
|
|||
|
|
|||
|
|
|||
|
http://netfilter.filewatcher.org/ipchains/ipchains-
|
|||
|
scripts-1.1.2.tar.gz
|
|||
|
<http://netfilter.filewatcher.org/ipchains/ipchains-
|
|||
|
scripts-1.1.2.tar.gz>
|
|||
|
|
|||
|
|
|||
|
This contains a shell script called ipfwadm-wrapper which allows you
|
|||
|
to do packet filtering as it was done before. You probably shouldn't
|
|||
|
use this script unless you want a quick way of upgrading a system
|
|||
|
which uses ipfwadm (it's slower, and doesn't check arguments, etc).
|
|||
|
In that case, you don't need this HOWTO much either.
|
|||
|
|
|||
|
See Appendix ``Differences between ipchains and ipfwadm'' and Appendix
|
|||
|
``Using the `ipfwadm-wrapper' script'' for more details on ipfwadm
|
|||
|
issues.
|
|||
|
|
|||
|
|
|||
|
2.3.3. Making Rules Permanent
|
|||
|
|
|||
|
Your current firewall setup is stored in the kernel, and thus will be
|
|||
|
lost on reboot. I recommend using the `ipchains-save' and `ipchains-
|
|||
|
restore' scripts to make your rules permanent. To do this, set up
|
|||
|
your rules, then run (as root):
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains-save > /etc/ipchains.rules
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Create a script like the following:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#! /bin/sh
|
|||
|
# Script to control packet filtering.
|
|||
|
|
|||
|
# If no rules, do nothing.
|
|||
|
[ -f /etc/ipchains.rules ] || exit 0
|
|||
|
|
|||
|
case "$1" in
|
|||
|
start)
|
|||
|
echo -n "Turning on packet filtering:"
|
|||
|
/sbin/ipchains-restore < /etc/ipchains.rules || exit 1
|
|||
|
echo 1 > /proc/sys/net/ipv4/ip_forward
|
|||
|
echo "."
|
|||
|
;;
|
|||
|
stop)
|
|||
|
echo -n "Turning off packet filtering:"
|
|||
|
echo 0 > /proc/sys/net/ipv4/ip_forward
|
|||
|
/sbin/ipchains -F
|
|||
|
/sbin/ipchains -X
|
|||
|
/sbin/ipchains -P input ACCEPT
|
|||
|
/sbin/ipchains -P output ACCEPT
|
|||
|
/sbin/ipchains -P forward ACCEPT
|
|||
|
echo "."
|
|||
|
;;
|
|||
|
*)
|
|||
|
echo "Usage: /etc/init.d/packetfilter {start|stop}"
|
|||
|
exit 1
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
exit 0
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Make sure this is run early in the bootup procedure. In my case
|
|||
|
(Debian 2.1), I make a symbolic link called `S39packetfilter' in the
|
|||
|
`/etc/rcS.d' directory (this will be run before S40network).
|
|||
|
|
|||
|
|
|||
|
3. I'm confused! Routing, masquerading, portforwarding, ipautofw...
|
|||
|
|
|||
|
This HOWTO is about packet filtering. This means deciding whether a
|
|||
|
packet should be allowed to pass or not. However, Linux being the
|
|||
|
hacker's playground that it is, you probably want to do more than
|
|||
|
that.
|
|||
|
|
|||
|
|
|||
|
One problem is that the same tool (``ipchains'') is used to control
|
|||
|
both masquerading and transparent proxying, although these are
|
|||
|
notionally separate from packet filtering (the current Linux
|
|||
|
implementation blurs these together unnaturally, leaving the
|
|||
|
impression that they are closely related).
|
|||
|
|
|||
|
|
|||
|
Masquerading and proxying are covered by separate HOWTOs, and the auto
|
|||
|
forwarding and port forwarding features are controlled by separate
|
|||
|
tools, but since so many people keep asking me about it, I'll include
|
|||
|
a set of common scenarios and indicate when each one should be
|
|||
|
applied. The security merits of each setup will not be discussed
|
|||
|
here.
|
|||
|
|
|||
|
|
|||
|
3.1. Rusty's Three-Line Guide To Masquerading
|
|||
|
|
|||
|
This assumes that your external interface is called `ppp0'. Use
|
|||
|
ifconfig to find out, and adjust to taste.
|
|||
|
# ipchains -P forward DENY
|
|||
|
# ipchains -A forward -i ppp0 -j MASQ
|
|||
|
# echo 1 > /proc/sys/net/ipv4/ip_forward
|
|||
|
|
|||
|
|
|||
|
|
|||
|
3.2. Gratuitous Promotion: WatchGuard Rules
|
|||
|
|
|||
|
You can buy off-the-shelf firewalls. An excellent one is WatchGuard's
|
|||
|
FireBox. It's excellent because I like it, it's secure, it's Linux-
|
|||
|
based, and because they funded the maintenance of ipchains as well as
|
|||
|
the new firewalling code (for 2.4). In short, WatchGuard were paying
|
|||
|
for me to eat while I work for you. So please consider their stuff.
|
|||
|
|
|||
|
http://www.watchguard.com <http://www.watchguard.com>
|
|||
|
|
|||
|
|
|||
|
3.3. Common Firewall-like Setups
|
|||
|
|
|||
|
You run littlecorp.com. You have an internal network, and a single
|
|||
|
dialup (PPP) connection to the Internet (firewall.littlecorp.com which
|
|||
|
is 1.2.3.4). You run Ethernet on your local network, and your
|
|||
|
personal machine is called "myhost".
|
|||
|
|
|||
|
|
|||
|
This section will illustrate the different arrangement which are
|
|||
|
common. Read carefully, because they are each subtly different.
|
|||
|
|
|||
|
|
|||
|
3.3.1. Private Network: Traditional Proxies
|
|||
|
|
|||
|
In this scenario, packets from the private network never traverse the
|
|||
|
Internet, and vice versa. The IP addresses of the private network
|
|||
|
should be assigned from the RFC1918 Address Allocation for Private
|
|||
|
Internets (ie. 10.*.*.*, 172.16.*.*-172.31.*.* or 192.168.*.*).
|
|||
|
|
|||
|
|
|||
|
The only way things ever connect to the Internet is by connecting to
|
|||
|
the firewall, which is the only machine on both networks which
|
|||
|
connects onwards. You run a program (on the firewall) called a proxy
|
|||
|
to do this (there are proxies for FTP, web access, telnet, RealAudio,
|
|||
|
Usenet News and other services). See the Firewall HOWTO.
|
|||
|
|
|||
|
|
|||
|
Any services you wish the Internet to access must be on the firewall.
|
|||
|
(But see ``Limited Internal Services'' below).
|
|||
|
|
|||
|
|
|||
|
Example: Allowing web access from private network to the Internet.
|
|||
|
|
|||
|
1. The private network is assigned 192.168.1.* addresses, with myhost
|
|||
|
being 192.168.1.100, and the firewall's Ethernet interface being
|
|||
|
assigned 192.168.1.1.
|
|||
|
|
|||
|
2. A web proxy (eg. "squid") is installed and configured on the
|
|||
|
firewall, say running on port 8080.
|
|||
|
|
|||
|
3. Netscape on the private network is configured to use the firewall
|
|||
|
port 8080 as a proxy.
|
|||
|
|
|||
|
4. DNS does not need to be configured on the private network.
|
|||
|
|
|||
|
5. DNS does need to be configured on the firewall.
|
|||
|
|
|||
|
6. No default route (aka gateway) needs to be configured on the
|
|||
|
private network.
|
|||
|
|
|||
|
|
|||
|
Netscape on myhost reads http://slashdot.org.
|
|||
|
|
|||
|
1. Netscape connects to the firewall port 8080, using port 1050 on
|
|||
|
myhost. It asks for the web page of "http://slashdot.org".
|
|||
|
|
|||
|
2. The proxy looks up the name "slashdot.org", and gets
|
|||
|
207.218.152.131. It then opens a connection to that IP address
|
|||
|
(using port 1025 on the firewall's external interface), and asks
|
|||
|
the web server (port 80) for the web page.
|
|||
|
|
|||
|
3. As it receives the web page from its connection to the web server,
|
|||
|
it copies the data to the connection from Netscape.
|
|||
|
|
|||
|
4. Netscape renders the page.
|
|||
|
|
|||
|
ie. From slashdot.org's point of view, the connection is made from
|
|||
|
1.2.3.4 (firewall's PPP interface) port 1025 to 207.218.152.131
|
|||
|
(slashdot.org) port 80. From myhost's point of view, the connection
|
|||
|
is made from 192.168.1.100 (myhost) port 1050, to 192.168.1.1
|
|||
|
(firewall's Ethernet interface) port 8080.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
3.3.2. Private Network: Transparent Proxies
|
|||
|
|
|||
|
In this scenario, packets from the private network never traverse the
|
|||
|
Internet, and vice versa. The IP addresses of the private network
|
|||
|
should be assigned from the RFC1918 Address Allocation for Private
|
|||
|
Internets (ie. 10.*.*.*, 172.16.*.*-172.31.*.* or 192.168.*.*).
|
|||
|
|
|||
|
|
|||
|
The only way things ever connect to the Internet is by connecting to
|
|||
|
the firewall, which is the only machine on both networks, which
|
|||
|
connects onwards. You run a program (on the firewall) called a
|
|||
|
transparent proxy to do this; the kernel sends outgoing packets to the
|
|||
|
transparent proxy instead of sending them onwards (ie. it bastardizes
|
|||
|
routing).
|
|||
|
|
|||
|
|
|||
|
Transparent proxying means that the clients don't need to know there
|
|||
|
is a proxy involved.
|
|||
|
|
|||
|
|
|||
|
Any services you wish the Internet to access must be on the firewall.
|
|||
|
(But see ``Limited Internal Services'' below).
|
|||
|
|
|||
|
|
|||
|
Example: Allowing web access from private network to the Internet.
|
|||
|
|
|||
|
1. The private network is assigned 192.168.1.* addresses, with myhost
|
|||
|
being 192.168.1.100, and the firewall's Ethernet interface being
|
|||
|
assigned 192.168.1.1.
|
|||
|
|
|||
|
2. A transparent web proxy (I believe there are patches for squid to
|
|||
|
allow it to operate in this manner, or try "transproxy") is
|
|||
|
installed and configured on the firewall, say running on port 8080.
|
|||
|
|
|||
|
3. The kernel is told to redirect connections to port 80 to the proxy,
|
|||
|
using ipchains.
|
|||
|
|
|||
|
4. Netscape on the private network is configured to connect directly.
|
|||
|
|
|||
|
5. DNS needs to be configured on the private network (ie. you need to
|
|||
|
run a DNS server as a proxy on the firewall).
|
|||
|
|
|||
|
6. The default route (aka gateway) needs to be configured on the
|
|||
|
private network, to send packets to the firewall.
|
|||
|
|
|||
|
|
|||
|
Netscape on myhost reads http://slashdot.org.
|
|||
|
|
|||
|
1. Netscape looks up the name "slashdot.org", and gets
|
|||
|
207.218.152.131. It then opens a connection to that IP address,
|
|||
|
using local port 1050, and asks the web server (port 80) for the
|
|||
|
web page.
|
|||
|
|
|||
|
2. As the packets from myhost (port 1050) to slashdot.org (port 80)
|
|||
|
pass through the firewall, they are redirected to the waiting
|
|||
|
transparent proxy on port 8080. The transparent proxy opens a
|
|||
|
connection (using local port 1025) to 207.218.152.131 port 80
|
|||
|
(which is where the original packets were going).
|
|||
|
|
|||
|
3. As the proxy receives the web page from its connection to the web
|
|||
|
server, it copies the data to the connection from Netscape.
|
|||
|
|
|||
|
4. Netscape renders the page.
|
|||
|
|
|||
|
ie. From slashdot.org's point of view, the connection is made from
|
|||
|
1.2.3.4 (firewall's PPP interface) port 1025 to 207.218.152.131
|
|||
|
(slashdot.org) port 80. From myhost's point of view, the connection
|
|||
|
is made from 192.168.1.100 (myhost) port 1050, to 207.218.152.131
|
|||
|
(slashdot.org) port 80, but it's actually talking to the transparent
|
|||
|
proxy.
|
|||
|
|
|||
|
|
|||
|
3.3.3. Private Network: Masquerading
|
|||
|
|
|||
|
In this scenario, packets from the private network never traverse the
|
|||
|
Internet without special treatment, and vice versa. The IP addresses
|
|||
|
of the private network should be assigned from the RFC1918 Address
|
|||
|
Allocation for Private Internets (ie. 10.*.*.*, 172.16.*.*-172.31.*.*
|
|||
|
or 192.168.*.*).
|
|||
|
|
|||
|
|
|||
|
Instead of using a proxy, we use a special kernel facility called
|
|||
|
"masquerading". Masquerading rewrites packets as they pass through
|
|||
|
the firewall, so that they always seem to come from the firewall
|
|||
|
itself. It then rewrites the responses so that they look like they
|
|||
|
are going to the original recipient.
|
|||
|
|
|||
|
|
|||
|
Masquerading has separate modules to handle "tricky" protocols, such
|
|||
|
as FTP, RealAudio, Quake, etc. For really hard-to-handle protocols,
|
|||
|
the "auto forwarding" facility can handle some of them by
|
|||
|
automatically setting up port forwarding for related sets of ports:
|
|||
|
look for ``ipportfw'' (2.0 kernels) or ``ipmasqadm'' (2.1 kernels).
|
|||
|
|
|||
|
|
|||
|
Any services you wish the Internet to access must be on the firewall.
|
|||
|
(But see ``Limited Internal Services'' below).
|
|||
|
|
|||
|
|
|||
|
Example: Allowing web access from private network to the Internet.
|
|||
|
|
|||
|
1. The private network is assigned 192.168.1.* addresses, with myhost
|
|||
|
being 192.168.1.100, and the firewall's Ethernet interface being
|
|||
|
assigned 192.168.1.1.
|
|||
|
|
|||
|
2. The firewall is set up to masquerade any packets coming from the
|
|||
|
private network and going to port 80 on an Internet host.
|
|||
|
|
|||
|
3. Netscape is configured to connect directly.
|
|||
|
|
|||
|
4. DNS must be configured correctly on the private network.
|
|||
|
|
|||
|
5. The firewall should be the default route (aka gateway) for the
|
|||
|
private network.
|
|||
|
|
|||
|
Netscape on myhost reads http://slashdot.org.
|
|||
|
|
|||
|
1. Netscape looks up the name "slashdot.org", and gets
|
|||
|
207.218.152.131. It then opens a connection to that IP address,
|
|||
|
using local port 1050, and asks the web server (port 80) for the
|
|||
|
web page.
|
|||
|
|
|||
|
2. As the packets from myhost (port 1050) to slashdot.org (port 80)
|
|||
|
pass through the firewall, they are rewritten to come from the PPP
|
|||
|
interface of the firewall, port 65000. The firewall has a valid
|
|||
|
Internet address (1.2.3.4) so reply packets from slashdot.org get
|
|||
|
routed back OK.
|
|||
|
|
|||
|
3. As packets from slashdot.org (port 80) to firewall.littlecorp.com
|
|||
|
(port 65000) come in, they are rewritten to go to myhost, port
|
|||
|
1050. This is the real magic of masquerading: it remembers when it
|
|||
|
rewrites outgoing packets to it can write them back as replies come
|
|||
|
in.
|
|||
|
|
|||
|
4. Netscape renders the page.
|
|||
|
|
|||
|
ie. From the slashdot.org's point of view, the connection is made
|
|||
|
from 1.2.3.4 (firewall's PPP interface) port 65000 to 207.218.152.131
|
|||
|
(slashdot.org) port 80. From the myhost's point of view, the
|
|||
|
connection is made from 192.168.1.100 (myhost) port 1050, to
|
|||
|
207.218.152.131 (slashdot.org) port 80.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
3.3.4. Public Network
|
|||
|
|
|||
|
In this scenario, your personal network is a part of the Internet:
|
|||
|
packets can flow without change across both networks. The IP
|
|||
|
addresses of the internal network must be assigned by applying for a
|
|||
|
block of IP addresses, so the rest of the network will know how to get
|
|||
|
packets to you. This implies a permanent connection.
|
|||
|
|
|||
|
|
|||
|
In this role, packet filtering is used to restrict which packets can
|
|||
|
be forwarded between your network and the rest of the Internet, eg. to
|
|||
|
restrict the rest of the Internet to only accessing your internal web
|
|||
|
servers.
|
|||
|
|
|||
|
|
|||
|
Example: Allowing web access from private network to the Internet.
|
|||
|
|
|||
|
1. Your internal network is assigned according to the IP address block
|
|||
|
you have registered, (say 1.2.3.*).
|
|||
|
|
|||
|
2. The firewall is set up to allow all traffic.
|
|||
|
|
|||
|
3. Netscape is configured to connect directly.
|
|||
|
|
|||
|
4. DNS must be configured correctly on your network.
|
|||
|
|
|||
|
|
|||
|
5. The firewall should be the default route (aka gateway) for the
|
|||
|
private network.
|
|||
|
|
|||
|
Netscape on myhost reads http://slashdot.org.
|
|||
|
|
|||
|
1. Netscape looks up the name "slashdot.org", and gets
|
|||
|
207.218.152.131. It then opens a connection to that IP address,
|
|||
|
using local port 1050, and asks the web server (port 80) for the
|
|||
|
web page.
|
|||
|
|
|||
|
2. Packets pass through your firewall, just as they pass through
|
|||
|
several other routers between you and slashdot.org.
|
|||
|
|
|||
|
3. Netscape renders the page.
|
|||
|
|
|||
|
ie. There is only one connection: from 1.2.3.100 (myhost) port 1050,
|
|||
|
to 207.218.152.131 (slashdot.org) port 80.
|
|||
|
|
|||
|
|
|||
|
3.3.5. Limited Internal Services
|
|||
|
|
|||
|
There are a few tricks you can pull to allow the Internet to access
|
|||
|
your internal services, rather than running the services on the
|
|||
|
firewall. These will work with either a proxy or masquerading based
|
|||
|
approach for external connections.
|
|||
|
|
|||
|
|
|||
|
The simplest approach is to run a "redirector", which is a poor-man's
|
|||
|
proxy which waits for a connection on a given port, and then open a
|
|||
|
connection a fixed internal host and port, and copies data between the
|
|||
|
two connections. An example of this is the "redir" program. From the
|
|||
|
Internet point of view, the connection is made to your firewall. From
|
|||
|
your internal server's point of view, the connection is made from the
|
|||
|
internal interface of the firewall to the server.
|
|||
|
|
|||
|
|
|||
|
Another approach (which requires a 2.0 kernel patched for ipportfw, or
|
|||
|
a 2.1 or later kernel) is to use port forwarding in the kernel. This
|
|||
|
does the same job as "redir" in a different way: the kernel rewrites
|
|||
|
packets as they pass through, changing their destination address and
|
|||
|
ports to point them at an internal host and port. From the Internet's
|
|||
|
point of view, the connection is made to your firewall. From your
|
|||
|
internal server's point of view, a direct connection is made from the
|
|||
|
Internet host to the server.
|
|||
|
|
|||
|
|
|||
|
3.4. More Information on Masquerading
|
|||
|
|
|||
|
David Ranch has written an excellent new HOWTO on Masquerading, which
|
|||
|
has a large amount of overlap with this HOWTO. You can currently find
|
|||
|
that HOWTO at
|
|||
|
|
|||
|
http://www.linuxdoc.org/HOWTO/IP-Masquerade-HOWTO.html
|
|||
|
|
|||
|
|
|||
|
The official Masquerading home page is at
|
|||
|
|
|||
|
http://ipmasq.cjb.net <http://ipmasq.cjb.net>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
4. IP Firewalling Chains
|
|||
|
|
|||
|
This section describes all you really need to know to build a packet
|
|||
|
filter that meets your needs.
|
|||
|
|
|||
|
4.1. How Packets Traverse The Filters
|
|||
|
|
|||
|
The kernel starts with three lists of rules; these lists are called
|
|||
|
firewall chains or just chains. The three chains are called input,
|
|||
|
output and forward. When a packet comes in (say, through the Ethernet
|
|||
|
card) the kernel uses the input chain to decide its fate. If it
|
|||
|
survives that step, then the kernel decides where to send the packet
|
|||
|
next (this is called routing). If it is destined for another machine,
|
|||
|
it consults the forward chain. Finally, just before a packet is to go
|
|||
|
out, the kernel consults the output chain.
|
|||
|
|
|||
|
|
|||
|
A chain is a checklist of rules. Each rule says `if the packet header
|
|||
|
looks like this, then here's what to do with the packet'. If the rule
|
|||
|
doesn't match the packet, then the next rule in the chain is
|
|||
|
consulted. Finally, if there are no more rules to consult, then the
|
|||
|
kernel looks at the chain policy to decide what to do. In a security-
|
|||
|
conscious system, this policy usually tells the kernel to reject or
|
|||
|
deny the packet.
|
|||
|
|
|||
|
|
|||
|
For ASCII-art fans, this shown the complete path of a packet coming
|
|||
|
into a machine.
|
|||
|
|
|||
|
|
|||
|
----------------------------------------------------------------
|
|||
|
| ACCEPT/ lo interface |
|
|||
|
v REDIRECT _______ |
|
|||
|
--> C --> S --> ______ --> D --> ~~~~~~~~ -->|forward|----> _______ -->
|
|||
|
h a |input | e {Routing } |Chain | |output |ACCEPT
|
|||
|
e n |Chain | m {Decision} |_______| --->|Chain |
|
|||
|
c i |______| a ~~~~~~~~ | | ->|_______|
|
|||
|
k t | s | | | | |
|
|||
|
s y | q | v | | |
|
|||
|
u | v e v DENY/ | | v
|
|||
|
m | DENY/ r Local Process REJECT | | DENY/
|
|||
|
| v REJECT a | | | REJECT
|
|||
|
| DENY d --------------------- |
|
|||
|
v e -----------------------------
|
|||
|
DENY
|
|||
|
|
|||
|
|
|||
|
Here is a blow-by-blow description of each stage:
|
|||
|
|
|||
|
|
|||
|
Checksum:
|
|||
|
This is a test that the packet hasn't been corrupted in some
|
|||
|
way. If it has, it is denied.
|
|||
|
|
|||
|
|
|||
|
Sanity:
|
|||
|
There is actually one of these sanity checks before each
|
|||
|
firewall chain, but the input chain's is the most important.
|
|||
|
Some malformed packets might confuse the rule-checking code, and
|
|||
|
these are denied here (a message is printed to the syslog if
|
|||
|
this happens).
|
|||
|
|
|||
|
|
|||
|
input chain:
|
|||
|
This is the first firewall chain against which the packet will
|
|||
|
be tested. If the verdict of the chain is not DENY or REJECT,
|
|||
|
the packet continues on.
|
|||
|
|
|||
|
|
|||
|
Demasquerade:
|
|||
|
If the packet is a reply to a previously masqueraded packet, it
|
|||
|
is demasqueraded, and skips straight to the output chain. If
|
|||
|
you don't use IP Masquerading, you can mentally erase this from
|
|||
|
the diagram.
|
|||
|
|
|||
|
|
|||
|
Routing decision:
|
|||
|
The destination field is examined by the routing code, to decide
|
|||
|
if this packet should go to a local process (see Local process
|
|||
|
below) or forwarded to a remote machine (see forward chain
|
|||
|
below).
|
|||
|
|
|||
|
|
|||
|
Local process:
|
|||
|
A process running on the machine can receive packets after the
|
|||
|
Routing Decision step, and can send packets (which go through
|
|||
|
the Routing Decision step, then traverse the output chain).
|
|||
|
|
|||
|
|
|||
|
lo interface:
|
|||
|
If packets from a local process are destined for a local
|
|||
|
process, they will go through the output chain with interface
|
|||
|
set to `lo', then return through the input chain with interface
|
|||
|
also `lo'. The lo interface is usually called the loopback
|
|||
|
interface.
|
|||
|
|
|||
|
|
|||
|
local:
|
|||
|
If the packet was not created by a local process, then the
|
|||
|
forward chain is checked, otherwise the packet goes to the
|
|||
|
output chain.
|
|||
|
|
|||
|
|
|||
|
forward chain:
|
|||
|
This chain is traversed for any packets which are attempting to
|
|||
|
pass through this machine to another.
|
|||
|
|
|||
|
|
|||
|
output chain:
|
|||
|
This chain is traversed for all packets just before they are
|
|||
|
sent out.
|
|||
|
|
|||
|
|
|||
|
4.1.1. Using ipchains
|
|||
|
|
|||
|
First, check that you have the version of ipchains that this document
|
|||
|
refers to:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
$ ipchains --version
|
|||
|
ipchains 1.3.9, 17-Mar-1999
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Note that I recommend 1.3.4 (which has no long options, like
|
|||
|
`--sport'), or 1.3.8 or above; these are very stable.
|
|||
|
|
|||
|
|
|||
|
ipchains has a fairly detailed manual page (man ipchains), and if you
|
|||
|
need more detail on particulars, you can check out the programming
|
|||
|
interface (man 4 ipfw), or the file net/ipv4/ip_fw.c in the 2.1.x
|
|||
|
kernel source, which is (obviously) authoritative.
|
|||
|
|
|||
|
|
|||
|
There is also an excellent quick reference card by Scott Bronson in
|
|||
|
the source package, in both A4 and US Letter PostScript(TM).
|
|||
|
|
|||
|
|
|||
|
There are several different things you can do with ipchains. First
|
|||
|
the operations to manage whole chains. You start with three built-in
|
|||
|
chains input, output and forward which you can't delete.
|
|||
|
|
|||
|
|
|||
|
1. Create a new chain (-N).
|
|||
|
|
|||
|
2. Delete an empty chain (-X).
|
|||
|
|
|||
|
3. Change the policy for a built-in chain. (-P).
|
|||
|
|
|||
|
4. List the rules in a chain (-L).
|
|||
|
|
|||
|
5. Flush the rules out of a chain (-F).
|
|||
|
|
|||
|
6. Zero the packet and byte counters on all rules in a chain (-Z).
|
|||
|
|
|||
|
There are several ways to manipulate rules inside a chain:
|
|||
|
|
|||
|
|
|||
|
1. Append a new rule to a chain (-A).
|
|||
|
|
|||
|
2. Insert a new rule at some position in a chain (-I).
|
|||
|
|
|||
|
3. Replace a rule at some position in a chain (-R).
|
|||
|
|
|||
|
4. Delete a rule at some position in a chain (-D).
|
|||
|
|
|||
|
5. Delete the first rule that matches in a chain (-D).
|
|||
|
|
|||
|
There are a few operations for masquerading, which are in ipchains for
|
|||
|
want of a good place to put them:
|
|||
|
|
|||
|
|
|||
|
1. List the currently masqueraded connections (-M -L).
|
|||
|
|
|||
|
2. Set masquerading timeout values (-M -S). (But see ``I can't set
|
|||
|
masquerading timeouts!'').
|
|||
|
|
|||
|
The final (and perhaps the most useful) function allows you to check
|
|||
|
what would happen to a given packet if it were to traverse a given
|
|||
|
chain.
|
|||
|
|
|||
|
|
|||
|
4.1.2. What You'll See When Your Computer Starts Up
|
|||
|
|
|||
|
Before any ipchains commands have been run (be careful: some
|
|||
|
distributions run ipchains in their initialization scripts), there
|
|||
|
will be no rules in any of the built-in chains (`input', `forward' and
|
|||
|
`output'), and each of the chains will have a policy of ACCEPT. This
|
|||
|
is as wide-open as you can get.
|
|||
|
|
|||
|
|
|||
|
4.1.3. Operations on a Single Rule
|
|||
|
|
|||
|
This is the bread-and-butter of ipchains; manipulating rules. Most
|
|||
|
commonly, you will probably use the append (-A) and delete (-D)
|
|||
|
commands. The others (-I for insert and -R for replace) are simple
|
|||
|
extensions of these concepts.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Each rule specifies a set of conditions the packet must meet, and what
|
|||
|
to do if it meets them (a `target'). For example, you might want to
|
|||
|
deny all ICMP packets coming from the IP address 127.0.0.1. So in
|
|||
|
this case our conditions are that the protocol must be ICMP and that
|
|||
|
the source address must be 127.0.0.1. Our target is `DENY'.
|
|||
|
|
|||
|
|
|||
|
127.0.0.1 is the `loopback' interface, which you will have even if you
|
|||
|
have no real network connection. You can use the `ping' program to
|
|||
|
generate such packets (it simply sends an ICMP type 8 (echo request)
|
|||
|
which all cooperative hosts should obligingly respond to with an ICMP
|
|||
|
type 0 (echo reply) packet). This makes it useful for testing.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ping -c 1 127.0.0.1
|
|||
|
PING 127.0.0.1 (127.0.0.1): 56 data bytes
|
|||
|
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms
|
|||
|
|
|||
|
--- 127.0.0.1 ping statistics ---
|
|||
|
1 packets transmitted, 1 packets received, 0% packet loss
|
|||
|
round-trip min/avg/max = 0.2/0.2/0.2 ms
|
|||
|
# ipchains -A input -s 127.0.0.1 -p icmp -j DENY
|
|||
|
# ping -c 1 127.0.0.1
|
|||
|
PING 127.0.0.1 (127.0.0.1): 56 data bytes
|
|||
|
|
|||
|
--- 127.0.0.1 ping statistics ---
|
|||
|
1 packets transmitted, 0 packets received, 100% packet loss
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
You can see here that the first ping succeeds (the `-c 1' tells ping
|
|||
|
to only send a single packet).
|
|||
|
|
|||
|
|
|||
|
Then we append (-A) to the `input' chain, a rule specifying that for
|
|||
|
packets from 127.0.0.1 (`-s 127.0.0.1') with protocol ICMP (`-p ICMP')
|
|||
|
we should jump to DENY (`-j DENY').
|
|||
|
|
|||
|
|
|||
|
Then we test our rule, using the second ping. There will be a pause
|
|||
|
before the program gives up waiting for a response that will never
|
|||
|
come.
|
|||
|
|
|||
|
|
|||
|
We can delete the rule in one of two ways. Firstly, since we know
|
|||
|
that it is the only rule in the input chain, we can use a numbered
|
|||
|
delete, as in:
|
|||
|
|
|||
|
|
|||
|
# ipchains -D input 1
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
To delete rule number 1 in the input chain.
|
|||
|
|
|||
|
|
|||
|
The second way is to mirror the -A command, but replacing the -A with
|
|||
|
-D. This is useful when you have a complex chain of rules and you
|
|||
|
don't want to have to count them to figure out that it's rule 37 that
|
|||
|
you want to get rid of. In this case, we would use:
|
|||
|
|
|||
|
# ipchains -D input -s 127.0.0.1 -p icmp -j DENY
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
The syntax of -D must have exactly the same options as the -A (or -I
|
|||
|
or -R) command. If there are multiple identical rules in the same
|
|||
|
chain, only the first will be deleted.
|
|||
|
|
|||
|
|
|||
|
4.1.4. Filtering Specifications
|
|||
|
|
|||
|
We have seen the use of `-p' to specify protocol, and `-s' to specify
|
|||
|
source address, but there are other options we can use to specify
|
|||
|
packet characteristics. What follows is an exhaustive compendium.
|
|||
|
|
|||
|
|
|||
|
4.1.4.1. Specifying Source and Destination IP Addresses
|
|||
|
|
|||
|
Source (-s) and destination (-d) IP addresses can be specified in four
|
|||
|
ways. The most common way is to use the full name, such as
|
|||
|
`localhost' or `www.linuxhq.com'. The second way is to specify the IP
|
|||
|
address such as `127.0.0.1'.
|
|||
|
|
|||
|
|
|||
|
The third and fourth ways allow specification of a group of IP
|
|||
|
addresses, such as `199.95.207.0/24' or `199.95.207.0/255.255.255.0'.
|
|||
|
These both specify any IP address from 199.95.207.0 to 199.95.207.255
|
|||
|
inclusive; the digits after the `/' tell which parts of the IP address
|
|||
|
are significant. `/32' or `/255.255.255.255' is the default (match
|
|||
|
all of the IP address). To specify any IP address at all `/0' can be
|
|||
|
used, like so:
|
|||
|
|
|||
|
|
|||
|
# ipchains -A input -s 0/0 -j DENY
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
This is rarely used, as the effect above is the same as not specifying
|
|||
|
the `-s' option at all.
|
|||
|
|
|||
|
|
|||
|
4.1.4.2. Specifying Inversion
|
|||
|
|
|||
|
Many flags, including the `-s' and `-d' flags can have their arguments
|
|||
|
preceded by `!' (pronounced `not') to match addresses NOT equal to the
|
|||
|
ones given. For example. `-s ! localhost' matches any packet not
|
|||
|
coming from localhost.
|
|||
|
|
|||
|
|
|||
|
Don't forget the spaces around the `!': they really are needed.
|
|||
|
|
|||
|
|
|||
|
4.1.4.3. Specifying Protocol
|
|||
|
|
|||
|
The protocol can be specified with the `-p' flag. Protocol can be a
|
|||
|
number (if you know the numeric protocol values for IP) or a name for
|
|||
|
the special cases of `TCP', `UDP' or `ICMP'. Case doesn't matter, so
|
|||
|
`tcp' works as well as `TCP'.
|
|||
|
|
|||
|
|
|||
|
The protocol name can be prefixed by a `!', to invert it, such as `-p
|
|||
|
! TCP'.
|
|||
|
4.1.4.3.1. Specifying UDP and TCP Ports
|
|||
|
|
|||
|
For the special case where a protocol of TCP or UDP is specified,
|
|||
|
there can be an extra argument indicating the TCP or UDP port, or an
|
|||
|
(inclusive) range of ports (but see ``Handling Fragments'' below). A
|
|||
|
range is represented using a `:' character, such as `6000:6010', which
|
|||
|
covers 11 port numbers, from 6000 to 6010 inclusive. If the lower
|
|||
|
bound is omitted, it defaults to 0. If the upper bound is omitted, it
|
|||
|
defaults to 65535. So to specify TCP connections coming from ports
|
|||
|
under 1024, the syntax would be as `-p TCP -s 0.0.0.0/0 :1023'. Port
|
|||
|
numbers can be specified by name, eg. `www'.
|
|||
|
|
|||
|
|
|||
|
Note that the port specification can be preceded by a `!', which
|
|||
|
inverts it. So to specify every TCP packet BUT a WWW packet, you
|
|||
|
would specify
|
|||
|
|
|||
|
-p TCP -d 0.0.0.0/0 ! www
|
|||
|
|
|||
|
|
|||
|
|
|||
|
It is important to realize that the specification
|
|||
|
|
|||
|
|
|||
|
-p TCP -d ! 192.168.1.1 www
|
|||
|
|
|||
|
|
|||
|
|
|||
|
is very different from
|
|||
|
|
|||
|
-p TCP -d 192.168.1.1 ! www
|
|||
|
|
|||
|
|
|||
|
|
|||
|
The first specifies any TCP packet to the WWW port on any machine but
|
|||
|
192.168.1.1. The second specifies any TCP connection to any port on
|
|||
|
192.168.1.1 but the WWW port.
|
|||
|
|
|||
|
|
|||
|
Finally, this case means not the WWW port and not 192.168.1.1:
|
|||
|
|
|||
|
-p TCP -d ! 192.168.1.1 ! www
|
|||
|
|
|||
|
|
|||
|
|
|||
|
4.1.4.3.2. Specifying ICMP Type and Code
|
|||
|
|
|||
|
ICMP also allows an optional argument, but as ICMP doesn't have ports,
|
|||
|
(ICMP has a type and a code) they have a different meaning.
|
|||
|
|
|||
|
|
|||
|
You can specify them as ICMP names (use ipchains -h icmp to list the
|
|||
|
names) after the `-s' option, or as a numeric ICMP type and code,
|
|||
|
where the type follows the `-s' option and the code follows the `-d'
|
|||
|
option.
|
|||
|
|
|||
|
|
|||
|
The ICMP names are fairly long: you only need use enough letters to
|
|||
|
make the name distinct from any other.
|
|||
|
|
|||
|
|
|||
|
Here is a small table of some of the most common ICMP packets:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Number Name Required by
|
|||
|
|
|||
|
0 echo-reply ping
|
|||
|
3 destination-unreachable Any TCP/UDP traffic.
|
|||
|
5 redirect routing if not running routing daemon
|
|||
|
8 echo-request ping
|
|||
|
11 time-exceeded traceroute
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Note that the ICMP names cannot be preceeded by `!' at the moment.
|
|||
|
|
|||
|
|
|||
|
DO NOT DO NOT DO NOT block all ICMP type 3 messages! (See ``ICMP
|
|||
|
Packets'' below).
|
|||
|
|
|||
|
|
|||
|
4.1.4.4. Specifying an Interface
|
|||
|
|
|||
|
The `-i' option specifies the name of an interface to match. An
|
|||
|
interface is the physical device the packet came in on, or is going
|
|||
|
out on. You can use the ifconfig command to list the interfaces which
|
|||
|
are `up' (ie. working at the moment).
|
|||
|
|
|||
|
|
|||
|
The interface for incoming packets (ie. packets traversing the input
|
|||
|
chain) is considered to be the interface they came in on. Logically,
|
|||
|
the interface for outgoing packets (packets traversing the output
|
|||
|
chain) is the interface they will go out on. The interface for
|
|||
|
packets traversing the forward chain is also the interface they will
|
|||
|
go out on; a fairly arbitrary decision it seems to me.
|
|||
|
|
|||
|
|
|||
|
It is perfectly legal to specify an interface that currently does not
|
|||
|
exist; the rule will not match anything until the interface comes up.
|
|||
|
This is extremely useful for dial-up PPP links (usually interface
|
|||
|
ppp0) and the like.
|
|||
|
|
|||
|
|
|||
|
As a special case, an interface name ending with a `+' will match all
|
|||
|
interfaces (whether they currently exist or not) which begin with that
|
|||
|
string. For example, to specify a rule which matches all PPP
|
|||
|
interfaces, the -i ppp+ option would be used.
|
|||
|
|
|||
|
|
|||
|
The interface name can be preceded by a `!' to match a packet which
|
|||
|
does NOT match the specified interface(s).
|
|||
|
|
|||
|
|
|||
|
4.1.4.5. Specifying TCP SYN Packets Only
|
|||
|
|
|||
|
It is sometimes useful to allow TCP connections in one direction, but
|
|||
|
not the other. For example, you might want to allow connections to an
|
|||
|
external WWW server, but not connections from that server.
|
|||
|
|
|||
|
|
|||
|
The naive approach would be to block TCP packets coming from the
|
|||
|
server. Unfortunately, TCP connections require packets going in both
|
|||
|
directions to work at all.
|
|||
|
|
|||
|
|
|||
|
The solution is to block only the packets used to request a
|
|||
|
connection. These packets are called SYN packets (ok, technically
|
|||
|
they're packets with the SYN flag set, and the FIN and ACK flags
|
|||
|
cleared, but we call them SYN packets). By disallowing only these
|
|||
|
packets, we can stop attempted connections in their tracks.
|
|||
|
|
|||
|
|
|||
|
The `-y' flag is used for this: it is only valid for rules which
|
|||
|
specify TCP as their protocol. For example, to specify TCP connection
|
|||
|
attempts from 192.168.1.1:
|
|||
|
|
|||
|
-p TCP -s 192.168.1.1 -y
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Once again, this flag can be inverted by preceding it with a `!',
|
|||
|
which means every packet other than the connection initiation.
|
|||
|
|
|||
|
|
|||
|
4.1.4.6. Handling Fragments
|
|||
|
|
|||
|
Sometimes a packet is too large to fit down a wire all at once. When
|
|||
|
this happens, the packet is divided into fragments, and sent as
|
|||
|
multiple packets. The other end reassembles the fragments to
|
|||
|
reconstruct the whole packet.
|
|||
|
|
|||
|
|
|||
|
The problem with fragments is that some of the specifications listed
|
|||
|
above (in particular, source port, destinations port, ICMP type, ICMP
|
|||
|
code, or TCP SYN flag) require the kernel to peek at the start of the
|
|||
|
packet, which is only contained in the first fragment.
|
|||
|
|
|||
|
|
|||
|
If your machine is the only connection to an external network, then
|
|||
|
you can tell the Linux kernel to reassemble all fragments which pass
|
|||
|
through it, by compiling the kernel with IP: always defragment set to
|
|||
|
`Y'. This sidesteps the issue neatly.
|
|||
|
|
|||
|
|
|||
|
Otherwise, it is important to understand how fragments get treated by
|
|||
|
the filtering rules. Any filtering rule that asks for information we
|
|||
|
don't have will not match. This means that the first fragment is
|
|||
|
treated like any other packet. Second and further fragments won't be.
|
|||
|
Thus a rule -p TCP -s 192.168.1.1 www (specifying a source port of
|
|||
|
`www') will never match a fragment (other than the first fragment).
|
|||
|
Neither will the opposite rule -p TCP -s 192.168.1.1 ! www.
|
|||
|
|
|||
|
|
|||
|
However, you can specify a rule specifically for second and further
|
|||
|
fragments, using the `-f' flag. Obviously, it is illegal to specify a
|
|||
|
TCP or UDP port, ICMP type, ICMP code or TCP SYN flag in such a
|
|||
|
fragment rule.
|
|||
|
|
|||
|
|
|||
|
It is also legal to specify that a rule does not apply to second and
|
|||
|
further fragments, by preceding the `-f' with `!'.
|
|||
|
|
|||
|
|
|||
|
Usually it is regarded as safe to let second and further fragments
|
|||
|
through, since filtering will effect the first fragment, and thus
|
|||
|
prevent reassembly on the target host, however, bugs have been known
|
|||
|
to allow crashing of machines simply by sending fragments. Your call.
|
|||
|
|
|||
|
|
|||
|
Note for network-heads: malformed packets (TCP, UDP and ICMP packets
|
|||
|
too short for the firewalling code to read the ports or ICMP code and
|
|||
|
type) are treated as fragments as well. Only TCP fragments starting
|
|||
|
at position 8 are explicitly dropped by the firewall code (a message
|
|||
|
should appear in the syslog if this occurs).
|
|||
|
As an example, the following rule will drop any fragments going to
|
|||
|
192.168.1.1:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -A output -f -d 192.168.1.1 -j DENY
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
4.1.5. Filtering Side Effects
|
|||
|
|
|||
|
OK, so now we know all the ways we can match a packet using a rule.
|
|||
|
If a packet matches a rule, the following things happen:
|
|||
|
|
|||
|
|
|||
|
1. The byte counter for that rule is increased by the size of the
|
|||
|
packet (header and all).
|
|||
|
|
|||
|
2. The packet counter for that rule is incremented.
|
|||
|
|
|||
|
3. If the rule requests it, the packet is logged.
|
|||
|
|
|||
|
4. If the rule requests it, the packet's Type Of Service field is
|
|||
|
changed.
|
|||
|
|
|||
|
5. If the rule requests it, the packet is marked (not in 2.0 kernel
|
|||
|
series).
|
|||
|
|
|||
|
6. The rule target is examined to decide what to do to the packet
|
|||
|
next.
|
|||
|
|
|||
|
|
|||
|
For variety, I'll address these in order of importance.
|
|||
|
|
|||
|
|
|||
|
4.1.5.1. Specifying a Target
|
|||
|
|
|||
|
A target tells the kernel what to do with a packet that matches a
|
|||
|
rule. ipchains uses `-j' (think `jump-to') for the target
|
|||
|
specification. The target name must be less than 8 letters, and case
|
|||
|
matters: "RETURN" and "return" are completely different.
|
|||
|
|
|||
|
|
|||
|
The simplest case is when there is no target specified. This type of
|
|||
|
rule (often called an `accounting' rule) is useful for simply counting
|
|||
|
a certain type of packet. Whether this rule matches or not, the
|
|||
|
kernel simply examines the next rule in the chain. For example, to
|
|||
|
count the number of packets from 192.168.1.1, we could do this:
|
|||
|
|
|||
|
|
|||
|
# ipchains -A input -s 192.168.1.1
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
(Using `ipchains -L -v' we can see the byte and packet counters
|
|||
|
associated with each rule).
|
|||
|
|
|||
|
|
|||
|
|
|||
|
There are six special targets. The first three, ACCEPT, REJECT and
|
|||
|
DENY are fairly simple. ACCEPT allows the packet through. DENY drops
|
|||
|
the packet as if it had never been received. REJECT drops the packet,
|
|||
|
but (if it's not an ICMP packet) generates an ICMP reply to the source
|
|||
|
to tell it that the destination was unreachable.
|
|||
|
|
|||
|
|
|||
|
The next one, MASQ tells the kernel to masquerade the packet. For
|
|||
|
this to work, your kernel needs to be compiled with IP Masquerading
|
|||
|
enabled. For details on this, see the Masquerading-HOWTO and the
|
|||
|
Appendix ``Differences between ipchains and ipfwadm''. This target is
|
|||
|
only valid for packets traversing the forward chain.
|
|||
|
|
|||
|
|
|||
|
The other major special target is REDIRECT which tells the kernel to
|
|||
|
send a packet to a local port instead of wherever it was heading.
|
|||
|
This can only be specified for rules specifying TCP or UDP as their
|
|||
|
protocol. Optionally, a port (name or number) can be specified
|
|||
|
following `-j REDIRECT' which will cause the packet to be redirected
|
|||
|
to that particular port, even if it was addressed to another port.
|
|||
|
This target is only valid for packets traversing the input chain.
|
|||
|
|
|||
|
|
|||
|
The final special target is RETURN which is identical to falling off
|
|||
|
the end of the chain immediately. (See ``Setting Policy'' below).
|
|||
|
|
|||
|
|
|||
|
Any other target indicates a user-defined chain (as described in
|
|||
|
``Operations on an Entire Chain'' below). The packet will begin
|
|||
|
traversing the rules in that chain. If that chain doesn't decide the
|
|||
|
fate of the packet, then once traversal on that chain has finished,
|
|||
|
traversal resumes on the next rule in the current chain.
|
|||
|
|
|||
|
|
|||
|
Time for more ASCII art. Consider two (silly) chains: input (the
|
|||
|
built-in chain) and Test (a user-defined chain).
|
|||
|
|
|||
|
|
|||
|
`input' `Test'
|
|||
|
---------------------------- ----------------------------
|
|||
|
| Rule1: -p ICMP -j REJECT | | Rule1: -s 192.168.1.1 |
|
|||
|
|--------------------------| |--------------------------|
|
|||
|
| Rule2: -p TCP -j Test | | Rule2: -d 192.168.1.1 |
|
|||
|
|--------------------------| ----------------------------
|
|||
|
| Rule3: -p UDP -j DENY |
|
|||
|
----------------------------
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Consider a TCP packet coming from 192.168.1.1, going to 1.2.3.4. It
|
|||
|
enters the input chain, and gets tested against Rule1 - no match.
|
|||
|
Rule2 matches, and its target is Test, so the next rule examined is
|
|||
|
the start of Test. Rule1 in Test matches, but doesn't specify a
|
|||
|
target, so the next rule is examined, Rule2. This doesn't match, so
|
|||
|
we have reached the end of the chain. We return to the input chain,
|
|||
|
where we had just examined Rule2, so we now examine Rule3, which
|
|||
|
doesn't match either.
|
|||
|
|
|||
|
|
|||
|
So the packet path is:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
v __________________________
|
|||
|
`input' | / `Test' v
|
|||
|
------------------------|--/ -----------------------|----
|
|||
|
| Rule1 | /| | Rule1 | |
|
|||
|
|-----------------------|/-| |----------------------|---|
|
|||
|
| Rule2 / | | Rule2 | |
|
|||
|
|--------------------------| -----------------------v----
|
|||
|
| Rule3 /--+___________________________/
|
|||
|
------------------------|---
|
|||
|
v
|
|||
|
|
|||
|
|
|||
|
|
|||
|
See the section ``How to Organise Your Firewall Rules'' for ways to
|
|||
|
use user-defined chains effectively.
|
|||
|
|
|||
|
|
|||
|
4.1.5.2. Logging Packets
|
|||
|
|
|||
|
This is a side effect that matching a rule can have; you can have the
|
|||
|
matching packet logged using the `-l' flag. You will usually not want
|
|||
|
this for routine packets, but it is a useful feature if you want to
|
|||
|
look for exceptional events.
|
|||
|
|
|||
|
|
|||
|
The kernel logs this information looking like:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Packet log: input DENY eth0 PROTO=17 192.168.2.1:53 192.168.1.1:1025
|
|||
|
L=34 S=0x00 I=18 F=0x0000 T=254
|
|||
|
|
|||
|
|
|||
|
|
|||
|
This log message is designed to be terse, and contain technical
|
|||
|
information useful only to networking gurus, but it can be useful to
|
|||
|
the rest of us. It breaks down like so:
|
|||
|
|
|||
|
|
|||
|
1. `input' is the chain which contained the rule which matched the
|
|||
|
packet, causing the log message.
|
|||
|
|
|||
|
2. `DENY' is what the rule said to do to the packet. If this is `-'
|
|||
|
then the rule didn't effect the packet at all (an accounting rule).
|
|||
|
|
|||
|
3. `eth0' is the interface name. Because this was the input chain, it
|
|||
|
means that the packet came in `eth0'.
|
|||
|
|
|||
|
4. `PROTO=17' means that the packet was protocol 17. A list of
|
|||
|
protocol numbers is given in `/etc/protocols'. The most common are
|
|||
|
1 (ICMP), 6 (TCP) and 17 (UDP).
|
|||
|
|
|||
|
5. `192.168.2.1' means that the packet's source IP address was
|
|||
|
192.168.2.1.
|
|||
|
|
|||
|
6. `:53' means that the source port was port 53. Looking in
|
|||
|
`/etc/services' shows that this is the `domain' port (ie. this is
|
|||
|
probably an DNS reply). For UDP and TCP, this number is the source
|
|||
|
port. For ICMP, it's the ICMP type. For others, it will be 65535.
|
|||
|
|
|||
|
7. `192.168.1.1' is the destination IP address.
|
|||
|
|
|||
|
8. `:1025' means that the destination port was 1025. For UDP and TCP,
|
|||
|
this number is the destination port. For ICMP, it's the ICMP code.
|
|||
|
For others, it will be 65535.
|
|||
|
|
|||
|
9. `L=34' means that packet was a total of 34 bytes long.
|
|||
|
|
|||
|
10.
|
|||
|
`S=0x00' means the Type of Service field (divide by 4 to get the
|
|||
|
Type of Service as used by ipchains).
|
|||
|
|
|||
|
11.
|
|||
|
`I=18' is the IP ID.
|
|||
|
|
|||
|
12.
|
|||
|
`F=0x0000' is the 16-bit fragment offset plus flags. A value
|
|||
|
starting with `0x4' or `0x5' means that the Don't Fragment bit is
|
|||
|
set. `0x2' or `0x3' means the `More Fragments' bit is set; expect
|
|||
|
more fragments after this. The rest of the number is the offset of
|
|||
|
this fragment, divided by 8.
|
|||
|
|
|||
|
13.
|
|||
|
`T=254' is the Time To Live of the packet. One is subtracted from
|
|||
|
this value for every hop, and it usually starts at 15 or 255.
|
|||
|
|
|||
|
14.
|
|||
|
`(#5)' there may be a final number in brackets on more recent
|
|||
|
kernels (perhaps after 2.2.9). This is the rule number which
|
|||
|
caused the packet log.
|
|||
|
|
|||
|
|
|||
|
On standard Linux systems, this kernel output is captured by klogd
|
|||
|
(the kernel logging daemon) which hands it to syslogd (the system
|
|||
|
logging daemon). The `/etc/syslog.conf' controls the behaviour of
|
|||
|
syslogd, by specifying a destination for each `facility' (in our case,
|
|||
|
the facility is "kernel") and `level' (for ipchains, the level used is
|
|||
|
"info").
|
|||
|
|
|||
|
|
|||
|
For example, my (Debian) /etc/syslog.conf contains two lines which
|
|||
|
match `kern.info':
|
|||
|
|
|||
|
|
|||
|
|
|||
|
kern.* -/var/log/kern.log
|
|||
|
*.=info;*.=notice;*.=warn;\
|
|||
|
auth,authpriv.none;\
|
|||
|
cron,daemon.none;\
|
|||
|
mail,news.none -/var/log/messages
|
|||
|
|
|||
|
|
|||
|
|
|||
|
These mean that the messags are duplicated in `/var/log/kern.log' and
|
|||
|
`/var/log/messages'. For more details, see `man syslog.conf'.
|
|||
|
|
|||
|
|
|||
|
4.1.5.3. Manipulating the Type Of Service
|
|||
|
|
|||
|
There are four seldom-used bits in the IP header, called the Type of
|
|||
|
Service (TOS) bits. They effect the way packets are treated; the four
|
|||
|
bits are "Minimum Delay", "Maximum Throughput", "Maximum Reliability"
|
|||
|
and "Minimum Cost". Only one of these bits is allowed to be set. Rob
|
|||
|
van Nieuwkerk, the author of the TOS-mangling code, puts it as
|
|||
|
follows:
|
|||
|
|
|||
|
|
|||
|
Especially the "Minimum Delay" is important for me. I
|
|||
|
switch it on for "interactive" packets in my upstream
|
|||
|
(Linux) router. I'm behind a 33k6 modem link. Linux prior<6F>
|
|||
|
itizes packets in 3 queues. This way I get acceptable
|
|||
|
interactive performance while doing bulk downloads at the
|
|||
|
same time. (It could even be better if there wasn't such a
|
|||
|
big queue in the serial driver, but latency is kept down 1.5
|
|||
|
seconds now).
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Note: obviously, you have no control over incoming packets; you can
|
|||
|
only control the priority of packets leaving your box. To negotiate
|
|||
|
priorities with the other end, a protocol like RSVP (which I know
|
|||
|
nothing about, so don't ask me) must be used.
|
|||
|
|
|||
|
|
|||
|
The most common use is to set telnet & ftp control connections to
|
|||
|
"Minimum Delay" and FTP data to "Maximum Throughput". This would be
|
|||
|
done as follows:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ipchains -A output -p tcp -d 0.0.0.0/0 telnet -t 0x01 0x10
|
|||
|
ipchains -A output -p tcp -d 0.0.0.0/0 ftp -t 0x01 0x10
|
|||
|
ipchains -A output -p tcp -s 0.0.0.0/0 ftp-data -t 0x01 0x08
|
|||
|
|
|||
|
|
|||
|
|
|||
|
The `-t' flag takes two extra parameters, both in hexadecimal. These
|
|||
|
allow complex twiddling of the TOS bits: the first mask is ANDed with
|
|||
|
the packet's current TOS, and then the second mask is XORed with it.
|
|||
|
If this is too confusing, just use the following table:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
TOS Name Value Typical Uses
|
|||
|
|
|||
|
Minimum Delay 0x01 0x10 ftp, telnet
|
|||
|
Maximum Throughput 0x01 0x08 ftp-data
|
|||
|
Maximum Reliability 0x01 0x04 snmp
|
|||
|
Minimum Cost 0x01 0x02 nntp
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Andi Kleen goes on to point out the following (mildly edited for
|
|||
|
posterity):
|
|||
|
|
|||
|
Maybe it would be useful to add an reference to the txqueue<75>
|
|||
|
len parameter of ifconfig to the discussion of TOS bits. The
|
|||
|
default device queue length is tuned for ethernet cards, on
|
|||
|
modems it is too long and makes the 3 band scheduler (which
|
|||
|
queues based on TOS) work suboptimally. It is a good idea to
|
|||
|
set it to a value between 4-10 on modem or single b channel
|
|||
|
ISDN links: on bundled devices a longer queue is needed.
|
|||
|
This is a 2.0 and 2.1 problem, but in 2.1 it is a ifconfig
|
|||
|
flag (with recent nettools), while in 2.0 it requires source
|
|||
|
patches in the device drivers to change.
|
|||
|
|
|||
|
|
|||
|
So, to see maximal benifits of TOS manipulation for modem PPP links,
|
|||
|
do `ifconfig $1 txqueuelen' in your /etc/ppp/ip-up script. The number
|
|||
|
to use depends on the modem speed and the amount of buffering in the
|
|||
|
modem; here's Andi setting me straight again:
|
|||
|
|
|||
|
The best value for a given configuration needs experiment.
|
|||
|
If the queues are too short on a router then packets will
|
|||
|
get dropped. Also of course one gets benefits even without
|
|||
|
TOS rewriting, just that TOS rewriting helps to give the
|
|||
|
benefits to non cooperating programs (but all standard linux
|
|||
|
programs are cooperating).
|
|||
|
|
|||
|
|
|||
|
|
|||
|
4.1.5.4. Marking a Packet
|
|||
|
|
|||
|
This allows complex and powerful interactions with Alexey Kuznetsov's
|
|||
|
new Quality of Service implementation, as well as the mark-based
|
|||
|
forwarding in later 2.1 series kernels. More news as it comes to
|
|||
|
hand. This option is ignored altogether in the 2.0 kernel series.
|
|||
|
|
|||
|
|
|||
|
4.1.5.5. Operations on an Entire Chain
|
|||
|
|
|||
|
A very useful feature of ipchains is the ability to group related
|
|||
|
rules into chains. You can call the chains whatever you want, as long
|
|||
|
as the names don't clash with the built-in chains (input, output and
|
|||
|
forward) or the targets (MASQ, REDIRECT, ACCEPT, DENY, REJECT or
|
|||
|
RETURN). I suggest avoiding upper-case labels entirely, since I may
|
|||
|
use these for future extensions. The chain name can be up to 8
|
|||
|
characters long.
|
|||
|
|
|||
|
|
|||
|
4.1.5.6. Creating a New Chain
|
|||
|
|
|||
|
Let's create a new chain. Because I am such an imaginative fellow,
|
|||
|
I'll call it test.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -N test
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
It's that simple. Now you can put rules in it as detailed above.
|
|||
|
|
|||
|
|
|||
|
4.1.5.7. Deleting a Chain
|
|||
|
|
|||
|
Deleting a chain is simple as well.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -X test
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Why `-X'? Well, all the good letters were taken.
|
|||
|
|
|||
|
|
|||
|
There are a couple of restrictions to deleting chains: they must be
|
|||
|
empty (see ``Flushing a Chain'' below) and they must not be the target
|
|||
|
of any rule. You can't delete any of the three built-in chains.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
4.1.5.8. Flushing a Chain
|
|||
|
|
|||
|
There is a simple way of emptying all rules out of a chain, using the
|
|||
|
`-F' command.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -F forward
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
If you don't specify a chain, then all chains will be flushed.
|
|||
|
|
|||
|
|
|||
|
4.1.5.9. Listing a Chain
|
|||
|
|
|||
|
You can list all the rules in a chain by using the `-L' command.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -L input
|
|||
|
Chain input (refcnt = 1): (policy ACCEPT)
|
|||
|
target prot opt source destination ports
|
|||
|
ACCEPT icmp ----- anywhere anywhere any
|
|||
|
# ipchains -L test
|
|||
|
Chain test (refcnt = 0):
|
|||
|
target prot opt source destination ports
|
|||
|
DENY icmp ----- localnet/24 anywhere any
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
The `refcnt' listed for test is the number of rules which have test as
|
|||
|
their target. This must be zero (and the chain be empty) before this
|
|||
|
chain can be deleted.
|
|||
|
|
|||
|
|
|||
|
If the chain name is omitted, all chains are listed, even empty ones.
|
|||
|
|
|||
|
|
|||
|
There are three options which can accompany `-L'. The `-n' (numeric)
|
|||
|
option is very useful as it prevents ipchains from trying to lookup
|
|||
|
the IP addresses, which (if you are using DNS like most people) will
|
|||
|
cause large delays if your DNS is not set up properly, or you have
|
|||
|
filtered out DNS requests. It also causes ports to be printed out as
|
|||
|
numbers rather than names.
|
|||
|
|
|||
|
|
|||
|
The `-v' options shows you all the details of the rules, such as the
|
|||
|
the packet and byte counters, the TOS masks, the interface, and the
|
|||
|
packet mark. Otherwise these values are omitted. For example:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -v -L input
|
|||
|
Chain input (refcnt = 1): (policy ACCEPT)
|
|||
|
pkts bytes target prot opt tosa tosx ifname mark source destination ports
|
|||
|
10 840 ACCEPT icmp ----- 0xFF 0x00 lo anywhere anywhere any
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Note that the packet and byte counters are printed out using the
|
|||
|
suffixes `K', `M' or `G' for 1000, 1,000,000 and 1,000,000,000
|
|||
|
respectively. Using the `-x' (expand numbers) flag as well prints the
|
|||
|
full numbers, no matter how large they are.
|
|||
|
|
|||
|
|
|||
|
4.1.5.10. Resetting (Zeroing) Counters
|
|||
|
|
|||
|
It is useful to be able to reset the counters. This can be done with
|
|||
|
the `-Z' (zero counters) option. For example:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -v -L input
|
|||
|
Chain input (refcnt = 1): (policy ACCEPT)
|
|||
|
pkts bytes target prot opt tosa tosx ifname mark source destination ports
|
|||
|
10 840 ACCEPT icmp ----- 0xFF 0x00 lo anywhere anywhere any
|
|||
|
# ipchains -Z input
|
|||
|
# ipchains -v -L input
|
|||
|
Chain input (refcnt = 1): (policy ACCEPT)
|
|||
|
pkts bytes target prot opt tosa tosx ifname mark source destination ports
|
|||
|
0 0 ACCEPT icmp ----- 0xFF 0x00 lo anywhere anywhere any
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
The problem with this approach is that sometimes you need to know the
|
|||
|
counter values immediately before they are reset. In the above
|
|||
|
example, some packets could pass through between the `-L' and `-Z'
|
|||
|
commands. For this reason, you can use the `-L' and `-Z' together, to
|
|||
|
reset the counters while reading them. Unfortunately, if you do this,
|
|||
|
you can't operate on a single chain: you have to list and zero all the
|
|||
|
chains at once.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -L -v -Z
|
|||
|
Chain input (policy ACCEPT):
|
|||
|
pkts bytes target prot opt tosa tosx ifname mark source destination ports
|
|||
|
10 840 ACCEPT icmp ----- 0xFF 0x00 lo anywhere anywhere any
|
|||
|
|
|||
|
Chain forward (refcnt = 1): (policy ACCEPT)
|
|||
|
Chain output (refcnt = 1): (policy ACCEPT)
|
|||
|
Chain test (refcnt = 0):
|
|||
|
0 0 DENY icmp ----- 0xFF 0x00 ppp0 localnet/24 anywhere any
|
|||
|
# ipchains -L -v
|
|||
|
Chain input (policy ACCEPT):
|
|||
|
pkts bytes target prot opt tosa tosx ifname mark source destination ports
|
|||
|
10 840 ACCEPT icmp ----- 0xFF 0x00 lo anywhere anywhere any
|
|||
|
|
|||
|
Chain forward (refcnt = 1): (policy ACCEPT)
|
|||
|
Chain output (refcnt = 1): (policy ACCEPT)
|
|||
|
Chain test (refcnt = 0):
|
|||
|
0 0 DENY icmp ----- 0xFF 0x00 ppp0 localnet/24 anywhere any
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
4.1.5.11. Setting Policy
|
|||
|
|
|||
|
We glossed over what happens when a packet hits the end of a built-in
|
|||
|
chain when we discussed how a packet walks through chains in
|
|||
|
``Specifying a Target'' above. In this case, the policy of the chain
|
|||
|
determines the fate of the packet. Only built-in chains (input,
|
|||
|
output and forward) have policies, because if a packet falls off the
|
|||
|
end of a user-defined chain, traversal resumes at the previous chain.
|
|||
|
|
|||
|
|
|||
|
The policy can be any of the first four special targets: ACCEPT, DENY,
|
|||
|
REJECT or MASQ. MASQ is only valid for the `forward' chain.
|
|||
|
|
|||
|
|
|||
|
It is also important to note that a RETURN target in a rule in one of
|
|||
|
the built-in chains is useful to explicitly target the chain policy
|
|||
|
when a packet matches a rule.
|
|||
|
|
|||
|
|
|||
|
4.1.6. Operations on Masquerading
|
|||
|
|
|||
|
There are several parameters you can tweak for IP Masquerading. They
|
|||
|
are bundled with ipchains because it's not worth writing a separate
|
|||
|
tool for them (although this will change).
|
|||
|
|
|||
|
|
|||
|
The IP Masquerading command is `-M', and it can be combined with `-L'
|
|||
|
to list currently masqueraded connections, or `-S' to set the
|
|||
|
masquerading parameters.
|
|||
|
|
|||
|
|
|||
|
The `-L' command can be accompanied by `-n' (show numbers instead of
|
|||
|
hostnames and port names) or `-v' (show deltas in sequence numbers for
|
|||
|
masqueraded connection, just in case you care).
|
|||
|
|
|||
|
|
|||
|
The `-S' command should be followed by three timeout values, each in
|
|||
|
seconds: for TCP sessions, for TCP sessions after a FIN packet, and
|
|||
|
for UDP packets. If you don't want to change one of these values,
|
|||
|
simply give a value of `0'.
|
|||
|
|
|||
|
|
|||
|
The default values are listed in
|
|||
|
`/usr/src/linux/include/net/ip_masq.h', currently 15 minutes, 2
|
|||
|
minutes and 5 minutes respectively.
|
|||
|
|
|||
|
|
|||
|
The most common value to change is the first one, for FTP (see ``FTP
|
|||
|
Nightmares'' below).
|
|||
|
|
|||
|
|
|||
|
Note the problems with setting timeouts listed in ``I can't set
|
|||
|
masquerading timeouts!''.
|
|||
|
|
|||
|
|
|||
|
4.1.7. Checking a Packet
|
|||
|
|
|||
|
Sometimes you want to see what happens when a certain packet enters
|
|||
|
your machine, such as for debugging your firewall chains. ipchains
|
|||
|
has the `-C' command to allow this, using the exact same routines that
|
|||
|
the kernel uses to diagnose real packets.
|
|||
|
|
|||
|
|
|||
|
You specify which chain to test the packet on by following the `-C'
|
|||
|
argument with its name. Whereas the kernel always starts traversing
|
|||
|
on the input, output or forward chains, you are allowed to begin
|
|||
|
traversing on any chain for testing purposes.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
The details of the `packet' are specified using the same syntax used
|
|||
|
to specify firewall rules. In particular, a protocol (`-p'), source
|
|||
|
address (`-s'), destination address (`-d') and interface (`-i') are
|
|||
|
compulsory. If the protocol is TCP or UDP, then a single source and a
|
|||
|
single destination port must be specified, and a ICMP type and code
|
|||
|
must be specified for the ICMP protocol (unless the `-f' flag is
|
|||
|
specified to indicate a fragment rule, in which case these options are
|
|||
|
illegal).
|
|||
|
|
|||
|
|
|||
|
If the protocol is TCP (and the `-f' flag is not specified), the `-y'
|
|||
|
flag may be specified, to indicate that the test packet should have
|
|||
|
the SYN bit set.
|
|||
|
|
|||
|
|
|||
|
Here is an example of testing a TCP SYN packet from 192.168.1.1 port
|
|||
|
60000 to 192.168.1.2 port www, coming in the eth0 interface, entering
|
|||
|
the `input' chain. (This is a classic incoming WWW connection
|
|||
|
initiation):
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -C input -p tcp -y -i eth0 -s 192.168.1.1 60000 -d 192.168.1.2 www
|
|||
|
packet accepted
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
4.1.8. Multiple Rules at Once and Watching What Happens
|
|||
|
|
|||
|
Sometimes a single command line can result in multiple rules being
|
|||
|
effected. This is done in two ways. Firstly, if you specify a
|
|||
|
hostname which resolves (using DNS) to multiple IP addresses, ipchains
|
|||
|
will act as if you had typed multiple commands with each combination
|
|||
|
of addresses.
|
|||
|
|
|||
|
|
|||
|
So if the hostname `www.foo.com' resolves to three IP addresses, and
|
|||
|
the hostname `www.bar.com' resolves to two IP addresses, then the
|
|||
|
command `ipchains -A input -j reject -s www.bar.com -d www.foo.com'
|
|||
|
would append six rules to the input chain.
|
|||
|
|
|||
|
|
|||
|
The other way to have ipchains perform multiple actions is to use the
|
|||
|
bidirectional flag (`-b'). This flag makes ipchains behave as if you
|
|||
|
had typed the command twice, the second time with the `-s' and `-d'
|
|||
|
arguments reversed. So, to avoid forwarding either to or from
|
|||
|
192.168.1.1, you could do the following:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -b -A forward -j reject -s 192.168.1.1
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Personally, I don't like the `-b' option much; if you want
|
|||
|
convenience, see ``Using ipchains-save'' below.
|
|||
|
|
|||
|
|
|||
|
The -b option can be used with the insert (`-I'), delete (`-D') (but
|
|||
|
not the variation which takes a rule number), append (`-A') and check
|
|||
|
(`-C') commands.
|
|||
|
|
|||
|
|
|||
|
Another useful flag is `-v' (verbose) which prints out exactly what
|
|||
|
ipchains is doing with your commands. This is useful if you are
|
|||
|
dealing with commands that may effect multiple rules. For example,
|
|||
|
here we check the behaviour of fragments between 192.168.1.1 and
|
|||
|
192.168.1.2.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -v -b -C input -p tcp -f -s 192.168.1.1 -d 192.168.1.2 -i lo
|
|||
|
tcp opt ---f- tos 0xFF 0x00 via lo 192.168.1.1 -> 192.168.1.2 * -> *
|
|||
|
packet accepted
|
|||
|
tcp opt ---f- tos 0xFF 0x00 via lo 192.168.1.2 -> 192.168.1.1 * -> *
|
|||
|
packet accepted
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
4.2. Useful Examples
|
|||
|
|
|||
|
I have a dialup PPP connection (-i ppp0). I grab news (-p TCP -s
|
|||
|
news.virtual.net.au nntp) and mail (-p TCP -s mail.virtual.net.au
|
|||
|
pop-3) every time I dial up. I use Debian's FTP method to update my
|
|||
|
machine regularly (-p TCP -y -s ftp.debian.org.au ftp-data). I surf
|
|||
|
the web through my ISP's proxy while this is going on (-p TCP -d
|
|||
|
proxy.virtual.net.au 8080), but hate the ads from doubleclick.net on
|
|||
|
the Dilbert Archive (-p TCP -y -d 199.95.207.0/24 and -p TCP -y -d
|
|||
|
199.95.208.0/24).
|
|||
|
|
|||
|
|
|||
|
I don't mind people trying to ftp to my machine while I'm online (-p
|
|||
|
TCP -d $LOCALIP ftp), but don't want anyone outside pretending to have
|
|||
|
an IP address of my internal network (-s 192.168.1.0/24). This is
|
|||
|
commonly called IP spoofing, and there is a better way to protect
|
|||
|
yourself from it in the 2.1.x kernels and above: see ``How do I set up
|
|||
|
IP spoof protection?''.
|
|||
|
|
|||
|
|
|||
|
This setup is fairly simple, because there are currently no other
|
|||
|
boxes on my internal network.
|
|||
|
|
|||
|
|
|||
|
I don't want any local process (ie. Netscape, lynx etc.) to connect to
|
|||
|
doubleclick.net:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -A output -d 199.95.207.0/24 -j REJECT
|
|||
|
# ipchains -A output -d 199.95.208.0/24 -j REJECT
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Now I want to set priorities on various outgoing packets (there isn't
|
|||
|
much point in doing it on incoming packets). Since I have a fair
|
|||
|
number of these rules, it makes sense to put them all in a single
|
|||
|
chain, called ppp-out.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -N ppp-out
|
|||
|
# ipchains -A output -i ppp0 -j ppp-out
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Minimum delay for web traffic & telnet.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -A ppp-out -p TCP -d proxy.virtual.net.au 8080 -t 0x01 0x10
|
|||
|
# ipchains -A ppp-out -p TCP -d 0.0.0.0/0 telnet -t 0x01 0x10
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Low cost for ftp data, nntp, pop-3:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -A ppp-out -p TCP -d 0.0.0.0/0 ftp-data -t 0x01 0x02
|
|||
|
# ipchains -A ppp-out -p TCP -d 0.0.0.0/0 nntp -t 0x01 0x02
|
|||
|
# ipchains -A ppp-out -p TCP -d 0.0.0.0/0 pop-3 -t 0x01 0x02
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
There are a few restrictions on packets coming in the ppp0 interface:
|
|||
|
let's create a chain called `ppp-in':
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -N ppp-in
|
|||
|
# ipchains -A input -i ppp0 -j ppp-in
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Now, no packets coming in ppp0 should be claiming a source address of
|
|||
|
192.168.1.*, so we log and deny them:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -A ppp-in -s 192.168.1.0/24 -l -j DENY
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
I allow UDP packets in for DNS (I run a caching nameserver which
|
|||
|
forwards all requests to 203.29.16.1, so I expect DNS replies from
|
|||
|
them only), incoming ftp, and return ftp-data only (which should only
|
|||
|
be going to a port above 1023, and not the X11 ports around 6000).
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -A ppp-in -p UDP -s 203.29.16.1 -d $LOCALIP dns -j ACCEPT
|
|||
|
# ipchains -A ppp-in -p TCP -s 0.0.0.0/0 ftp-data -d $LOCALIP 1024:5999 -j ACCEPT
|
|||
|
# ipchains -A ppp-in -p TCP -s 0.0.0.0/0 ftp-data -d $LOCALIP 6010: -j ACCEPT
|
|||
|
# ipchains -A ppp-in -p TCP -d $LOCALIP ftp -j ACCEPT
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
I allow TCP reply packets back in
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -A ppp-in -p TCP ! -y -j ACCEPT
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Finally, local-to-local packets are OK:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -A input -i lo -j ACCEPT
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Now, my default policy on the input chain is DENY, so everything else
|
|||
|
gets dropped:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -P input DENY
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
NOTE: I wouldn't set up my chains in this order, as packets might get
|
|||
|
through while I'm setting up. Safest is usually to set the policy to
|
|||
|
DENY first, then insert the rules. Of course, if your rules require
|
|||
|
DNS lookups to resolve hostnames, you could be in trouble.
|
|||
|
|
|||
|
|
|||
|
4.2.1. Using ipchains-save
|
|||
|
|
|||
|
Setting up firewall chains just the way you want them, and then trying
|
|||
|
to remember the commands you used so you can do them next time is a
|
|||
|
pain.
|
|||
|
|
|||
|
|
|||
|
So, ipchains-save is a script which reads your current chains setup
|
|||
|
and saves it to a file. For the moment I'll keep you in suspense with
|
|||
|
regards to what ipchains-restore does.
|
|||
|
|
|||
|
|
|||
|
ipchains-save can save a single chain, or all chains (if no chain name
|
|||
|
is specified). The only option currently permitted is `-v' which
|
|||
|
prints the rules (to stderr) as they are saved. The policy of the
|
|||
|
chain is also saved for input, output and forward chains.
|
|||
|
# ipchains-save > my_firewall
|
|||
|
Saving `input'.
|
|||
|
Saving `output'.
|
|||
|
Saving `forward'.
|
|||
|
Saving `ppp-in'.
|
|||
|
Saving `ppp-out'.
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
4.2.2. Using ipchains-restore
|
|||
|
|
|||
|
ipchains-restore restores chains as saved with ipchains-save. It can
|
|||
|
take two options: `-v' which describes each rule as it is added, and
|
|||
|
`-f' which forces flushing of user-defined chains if they exist, as
|
|||
|
described below.
|
|||
|
|
|||
|
|
|||
|
If a user-defined chain is found in the input, ipchains-restore checks
|
|||
|
if that chain already exists. If it does, then you will be prompted
|
|||
|
whether the chains should be flushed (cleared of all rules) or whether
|
|||
|
restoring this chain should be skipped. If you specified `-f' on the
|
|||
|
command line, you will not be prompted; the chain will be flushed.
|
|||
|
|
|||
|
|
|||
|
For example:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains-restore < my_firewall
|
|||
|
Restoring `input'.
|
|||
|
Restoring `output'.
|
|||
|
Restoring `forward'.
|
|||
|
Restoring `ppp-in'.
|
|||
|
Chain `ppp-in' already exists. Skip or flush? [S/f]? s
|
|||
|
Skipping `ppp-in'.
|
|||
|
Restoring `ppp-out'.
|
|||
|
Chain `ppp-out' already exists. Skip or flush? [S/f]? f
|
|||
|
Flushing `ppp-out'.
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
5. Miscellaneous.
|
|||
|
|
|||
|
This section contains all the information and FAQs that I couldn't fit
|
|||
|
inside the structure above.
|
|||
|
|
|||
|
|
|||
|
5.1. How to Organize Your Firewall Rules
|
|||
|
|
|||
|
This question requires some thought. You can try to organize them to
|
|||
|
optimize speed (minimize the number of rule-checks for the most common
|
|||
|
packets) or to increase manageability.
|
|||
|
|
|||
|
|
|||
|
If you have an intermittent link, say a PPP link, you might want to
|
|||
|
set the first rule in the input chain to be set to `-i ppp0 -j DENY'
|
|||
|
at boot time, then have something like this in your ip-up script:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# Re-create the `ppp-in' chain.
|
|||
|
ipchains-restore -f < ppp-in.firewall
|
|||
|
|
|||
|
# Replace DENY rule with jump to ppp-handling chain.
|
|||
|
ipchains -R input 1 -i ppp0 -j ppp-in
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Your ip-down script would look like:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ipchains -R input 1 -i ppp0 -j DENY
|
|||
|
|
|||
|
|
|||
|
|
|||
|
5.2. What Not To Filter Out
|
|||
|
|
|||
|
There are some things you should be aware of before you start
|
|||
|
filtering out everything you don't want.
|
|||
|
|
|||
|
|
|||
|
5.2.1. ICMP packets
|
|||
|
|
|||
|
ICMP packets are used (among other things) to indicate failure for
|
|||
|
other protocols (such as TCP and UDP). `destination-unreachable'
|
|||
|
packets in particular. Blocking these packets means that you will
|
|||
|
never get `Host unreachable' or `No route to host' errors; any
|
|||
|
connections will just wait for a reply that never comes. This is
|
|||
|
irritating, but rarely fatal.
|
|||
|
|
|||
|
|
|||
|
A worse problem is the role of ICMP packets in MTU discovery. All
|
|||
|
good TCP implementations (Linux included) use MTU discovery to try to
|
|||
|
figure out what the largest packet that can get to a destination
|
|||
|
without being fragmented (fragmentation slows performance, especially
|
|||
|
when occasional fragments are lost). MTU discovery works by sending
|
|||
|
packets with the "Don't Fragment" bit set, and then sending smaller
|
|||
|
packets if it gets an ICMP packet indicating "Fragmentation needed but
|
|||
|
DF set" (`fragmentation-needed'). This is a type of `destination-
|
|||
|
unreachable' packet, and if it is never received, the local host will
|
|||
|
not reduce MTU, and performance will be abysmal or non-existent.
|
|||
|
|
|||
|
|
|||
|
Note that it is common to block all ICMP redirect messages (type 5);
|
|||
|
these can be used to manipulate routing (although good IP stacks have
|
|||
|
safeguards), and so are often seen as slightly risky.
|
|||
|
|
|||
|
|
|||
|
5.2.2. TCP Connections to DNS (nameservers)
|
|||
|
|
|||
|
If you're trying to block outgoing TCP connections, remember that DNS
|
|||
|
doesn't always use UDP; if the reply from the server exceeds 512
|
|||
|
bytes, the client uses a TCP connection (still going to port number
|
|||
|
53) to get the data.
|
|||
|
|
|||
|
|
|||
|
This can be a trap because DNS will `mostly work' if you disallow such
|
|||
|
TCP transfers; you may experience strange long delays and other
|
|||
|
occasional DNS problems if you do.
|
|||
|
|
|||
|
If your DNS queries are always directed at the same external source
|
|||
|
(either directly by using the nameserver line in /etc/resolv.conf or
|
|||
|
by using a caching nameserver in forward mode), then you need only
|
|||
|
allow TCP connections to port domain on that nameserver from the local
|
|||
|
domain port (if using a caching nameserver) or from a high port (>
|
|||
|
1023) if using /etc/resolv.conf.
|
|||
|
|
|||
|
|
|||
|
5.2.3. FTP Nightmares
|
|||
|
|
|||
|
The classic packet filtering problem is FTP. FTP has two modes; the
|
|||
|
traditional one is called active mode and the more recent one is
|
|||
|
called passive mode. Web browsers usually default to passive mode,
|
|||
|
but command-line FTP programs usually default to active mode.
|
|||
|
|
|||
|
|
|||
|
In active mode, when the remote end wants to send a file (or even the
|
|||
|
results of an ls or dir command) it tries to open a TCP connection to
|
|||
|
the local machine. This means you can't filter out these TCP
|
|||
|
connections without breaking active FTP.
|
|||
|
|
|||
|
|
|||
|
If you have the option of using passive mode, then fine; passive mode
|
|||
|
makes data connections from client to server, even for incoming data.
|
|||
|
Otherwise, it is recommended that you only allow TCP connections to
|
|||
|
ports above 1024 and not between 6000 and 6010 (6000 is used for X-
|
|||
|
Windows).
|
|||
|
|
|||
|
|
|||
|
5.3. Filtering out Ping of Death
|
|||
|
|
|||
|
Linux boxes are now immune to the famous Ping of Death, which involves
|
|||
|
sending an illegally-large ICMP packet which overflows buffers in the
|
|||
|
TCP stack on the receiver and causes havoc.
|
|||
|
|
|||
|
|
|||
|
If you are protecting boxes which might be vulnerable, you could
|
|||
|
simply block ICMP fragments. Normal ICMP packets aren't large enough
|
|||
|
to require fragmentation, so you won't break anything except big
|
|||
|
pings. I have heard (unconfirmed) reports that some systems required
|
|||
|
only the last fragment of an oversize ICMP packet to corrupt them, so
|
|||
|
blocking only the first fragment is not recommended.
|
|||
|
|
|||
|
|
|||
|
While the exploit programs I have seen all use ICMP, there is no
|
|||
|
reasons that TCP or UDP fragments (or an unknown protocol) could not
|
|||
|
be used for this attack, so blocking ICMP fragments is only a
|
|||
|
temporary solution.
|
|||
|
|
|||
|
|
|||
|
5.4. Filtering out Teardrop and Bonk
|
|||
|
|
|||
|
Teardrop and Bonk are two attacks (mainly against Microsoft Windows NT
|
|||
|
machines) which rely on overlapping fragments. Having your Linux
|
|||
|
router do defragmentation, or disallowing all fragments to your
|
|||
|
vulnerable machines are the other options.
|
|||
|
|
|||
|
|
|||
|
5.5. Filtering out Fragment Bombs
|
|||
|
|
|||
|
Some less-reliable TCP stacks are said to have problems dealing with
|
|||
|
large numbers of fragments of packets when they don't receive all the
|
|||
|
fragments. Linux does not have this problem. You can filter out
|
|||
|
fragments (which might break legitimate uses) or compile your kernel
|
|||
|
with `IP: always defragment' set to `Y' (only if your Linux box is the
|
|||
|
only possible route for these packets).
|
|||
|
5.6. Changing Firewall Rules
|
|||
|
|
|||
|
There are some timing issues involved in altering firewall rules. If
|
|||
|
you are not careful, you can let packets through while you are half-
|
|||
|
way through your changes. A simplistic approach is to do the
|
|||
|
following:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -I input 1 -j DENY
|
|||
|
# ipchains -I output 1 -j DENY
|
|||
|
# ipchains -I forward 1 -j DENY
|
|||
|
|
|||
|
... make changes ...
|
|||
|
|
|||
|
# ipchains -D input 1
|
|||
|
# ipchains -D output 1
|
|||
|
# ipchains -D forward 1
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
This drops all packets for the duration of the changes.
|
|||
|
|
|||
|
|
|||
|
If your changes are restricted to a single chain, you might want to
|
|||
|
create a new chain with the new rules, and then replace (`-R') the
|
|||
|
rule that pointed to the old chain with one that points to the new
|
|||
|
chain: then you can delete the old chain. This replacement will occur
|
|||
|
atomically.
|
|||
|
|
|||
|
|
|||
|
5.7. How Do I Set Up IP Spoof Protection?
|
|||
|
|
|||
|
IP spoofing is a technique where a host sends out packets which claim
|
|||
|
to be from another host. Since packet filtering makes decisions based
|
|||
|
on this source address, IP spoofing is uses to fool packet filters.
|
|||
|
It is also used to hide the identity of attackers using SYN attacks,
|
|||
|
Teardrop, Ping of Death and the like (don't worry if you don't know
|
|||
|
what they are).
|
|||
|
|
|||
|
|
|||
|
The best way to protect from IP spoofing is called Source Address
|
|||
|
Verification, and it is done by the routing code, and not firewalling
|
|||
|
at all. Look for a file called /proc/sys/net/ipv4/conf/all/rp_filter.
|
|||
|
If this exists, then turning on Source Address Verification at every
|
|||
|
boot is the right solution for you. To do that, insert the following
|
|||
|
lines somewhere in your init scripts, before any network interfaces
|
|||
|
are initialized:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# This is the best method: turn on Source Address Verification and get
|
|||
|
# spoof protection on all current and future interfaces.
|
|||
|
if [ -e /proc/sys/net/ipv4/conf/all/rp_filter ]; then
|
|||
|
echo -n "Setting up IP spoofing protection..."
|
|||
|
for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
|
|||
|
echo 1 > $f
|
|||
|
done
|
|||
|
echo "done."
|
|||
|
else
|
|||
|
echo PROBLEMS SETTING UP IP SPOOFING PROTECTION. BE WORRIED.
|
|||
|
echo "CONTROL-D will exit from this shell and continue system startup."
|
|||
|
echo
|
|||
|
# Start a single user shell on the console
|
|||
|
/sbin/sulogin $CONSOLE
|
|||
|
fi
|
|||
|
|
|||
|
|
|||
|
|
|||
|
If you cannot do this, you can manually insert rules to protect every
|
|||
|
interface. This requires knowledge of each interface. The 2.1
|
|||
|
kernels automatically reject packets claiming to come from the 127.*
|
|||
|
addresses (reserved for the local loopback interface, lo).
|
|||
|
|
|||
|
|
|||
|
For example, say we have three interfaces, eth0, eth1 and ppp0. We
|
|||
|
can use ifconfig to tell us the address and netmask of the interfaces.
|
|||
|
Say eth0 was attached to a network 192.168.1.0 with netmask
|
|||
|
255.255.255.0, eth1 was attached to a network 10.0.0.0 with netmask
|
|||
|
255.0.0.0, and ppp0 connected to the Internet (where any address
|
|||
|
except the reserved private IP addresses are allowed), we would insert
|
|||
|
the following rules:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -A input -i eth0 -s ! 192.168.1.0/255.255.255.0 -j DENY
|
|||
|
# ipchains -A input -i ! eth0 -s 192.168.1.0/255.255.255.0 -j DENY
|
|||
|
# ipchains -A input -i eth1 -s ! 10.0.0.0/255.0.0.0 -j DENY
|
|||
|
# ipchains -A input -i ! eth1 -s 10.0.0.0/255.0.0.0 -j DENY
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
This approach is not as good as the Source Address Verification
|
|||
|
approach, because if your network changes, you have to change your
|
|||
|
firewalling rules to keep up.
|
|||
|
|
|||
|
|
|||
|
If you are running a 2.0 series kernel, you might want to protect the
|
|||
|
loopback interface as well, using a rule like this:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -A input -i ! lo -s 127.0.0.0/255.0.0.0 -j DENY
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
5.8. Advanced Projects
|
|||
|
|
|||
|
There is a userspace library I have written which is included with the
|
|||
|
source distribution called `libfw'. It uses the ability of IP Chains
|
|||
|
1.3 and above to copy a packet to userspace (using the
|
|||
|
IP_FIREWALL_NETLINK config option).
|
|||
|
|
|||
|
|
|||
|
The mark value can be used to specify the Quality of Service
|
|||
|
parameters for packets, or to specify how packets should be port-
|
|||
|
forwarded. I've never used either, but if you want to write about it,
|
|||
|
please contact me.
|
|||
|
|
|||
|
|
|||
|
Things such as stateful inspection (I prefer the term dynamic
|
|||
|
firewalling) can be implemented in userspace using this library.
|
|||
|
Other nifty ideas include controlling packets on a per-user basis by
|
|||
|
doing a lookup in a userspace daemon. This should be pretty easy.
|
|||
|
|
|||
|
|
|||
|
5.8.1. SPF: Stateful Packet Filtering
|
|||
|
|
|||
|
ftp://ftp.interlinx.bc.ca/pub/spf <ftp://ftp.interlinx.bc.ca/pub/spf>
|
|||
|
is the site of Brian Murrell's SPF project, which does connection
|
|||
|
tracking in userspace. It adds significant security for low-bandwidth
|
|||
|
sites.
|
|||
|
|
|||
|
|
|||
|
There's little documentation at present, but here's a post to the
|
|||
|
mailing list in which Brian answered some questions:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
> I believe it does exactly what I want: Installing a temporary
|
|||
|
> "backward"-rule to let packets in as a response to an
|
|||
|
> outgoing request.
|
|||
|
|
|||
|
Yup, that is exactly what it does. The more protocols it
|
|||
|
understands, the more "backward" rules it gets right. Right
|
|||
|
now it has support for (from memory, please excuse any errors
|
|||
|
or omissions) FTP (both active and passive, in and out), some
|
|||
|
RealAudio, traceroute, ICMP and basic ICQ (inbound from the ICQ
|
|||
|
servers, and direct TCP connections, but alas the secondary
|
|||
|
direct TCP connections for things like file transfer, etc. are
|
|||
|
not there yet)
|
|||
|
|
|||
|
> Is it a replacement for ipchains or a supplement?
|
|||
|
|
|||
|
It is a supplement. Think of ipchains as the engine to allow
|
|||
|
and prevent packets from travelling across a Linux box. SPF is
|
|||
|
the driver, constantly monitoring traffic and telling ipchains
|
|||
|
how to change it's policies to reflect the changes in traffic
|
|||
|
patterns.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
5.8.2. Michael Hasenstein's ftp-data hack
|
|||
|
|
|||
|
Michael Hasenstein of SuSE has written a kernel patch which adds ftp
|
|||
|
connection tracking to ipchains. It can currently be found at
|
|||
|
http://www.suse.de/~mha/patch.ftp-data-2.gz
|
|||
|
<http://www.suse.de/~mha/patch.ftp-data-2.gz>
|
|||
|
|
|||
|
5.9. Future Enhancements
|
|||
|
|
|||
|
Firewalling and NAT have being redesigned for 2.4. Plans and
|
|||
|
discussions are available on the netfilter list (see
|
|||
|
http://lists.samba.org <http://lists.samba.org>). These enhancements
|
|||
|
should clear up many outstanding usability issues (really, firewalling
|
|||
|
and masquerading shouldn't be this hard), and allow growth for far
|
|||
|
more flexible firewalling.
|
|||
|
|
|||
|
|
|||
|
6. Common Problems
|
|||
|
|
|||
|
|
|||
|
6.1. ipchains -L Freezes!
|
|||
|
|
|||
|
You're probably blocking DNS lookups; it will eventually time out.
|
|||
|
Try using the `-n' (numeric) flag to ipchains, which suppresses the
|
|||
|
lookup of names.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
6.2. Inverse doesn't work!
|
|||
|
|
|||
|
You must put the `!' option by itself, with spaces either side. A
|
|||
|
classic mistake (warned about in 1.3.10) is:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -A input -i !eth0 -j DENY
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
There will never be an interface called `!eth0', but ipchains doesn't
|
|||
|
know that.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
6.3. Masquerading/Forwarding Doesn't Work!
|
|||
|
|
|||
|
Make sure that packet forwarding is enabled (in recent kernels it is
|
|||
|
disabled by default, meaning that packets never even try to traverse
|
|||
|
the `forward' chain). You can override this (as root) by typing
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# echo 1 > /proc/sys/net/ipv4/ip_forward
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
If this works for you, you can put this somewhere in your bootup
|
|||
|
scripts so it is enabled every time; you'll want to set up your
|
|||
|
firewalling before this command runs though, otherwise there's an
|
|||
|
opportunity for packets to slip through.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
6.4. -j REDIR doesn't work!
|
|||
|
|
|||
|
You must allow forwarding packets (see above) for redirect to work;
|
|||
|
otherwise the routing code drops the packet. So if you are just using
|
|||
|
redirect, and don't have any forwarding at all, you should be aware of
|
|||
|
that.
|
|||
|
|
|||
|
|
|||
|
Note that REDIR (being in the input chain) doesn't effect connections
|
|||
|
from a local process.
|
|||
|
|
|||
|
|
|||
|
6.5. Wildcard Interfaces Don't Work!
|
|||
|
|
|||
|
There was a bug in versions 2.1.102 and 2.1.103 of the kernel (and
|
|||
|
some old patches I produced) which made ipchains commands which
|
|||
|
specified a wildcard interface (such as -i ppp+) fail.
|
|||
|
|
|||
|
|
|||
|
This is fixed in recent kernels, and in the 2.0.34 patch on the web
|
|||
|
site. You can also fix it by hand in the kernel source by changing
|
|||
|
line 63 or so in include/linux/ip_fw.h:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#define IP_FW_F_MASK 0x002F /* All possible flag bits mask */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
This should read ``0x003F''. Fix this and recompile the kernel.
|
|||
|
|
|||
|
|
|||
|
6.6. TOS Doesn't Work!
|
|||
|
|
|||
|
This was my mistake: setting the Type of Service field did not
|
|||
|
actually set the Type of Service in kernel versions 2.1.102 through
|
|||
|
2.1.111. This problem was fixed in 2.1.112.
|
|||
|
|
|||
|
|
|||
|
6.7. ipautofw and ipportfw Don't Work!
|
|||
|
|
|||
|
For 2.0.x, this is true; I haven't time to create and maintain a jumbo
|
|||
|
patch for ipchains and ipautofw/ipportfw.
|
|||
|
|
|||
|
|
|||
|
For 2.1.x, download Juan Ciarlante's ipmasqadm from
|
|||
|
|
|||
|
<url url="http://juanjox.linuxhq.com/"
|
|||
|
name="http://juanjox.linuxhq.com/">
|
|||
|
|
|||
|
|
|||
|
and use it exactly as you would have used ipautofw or ipportfw, except
|
|||
|
instead of ipportfw you type ipmasqadm portfw, and instead of ipautofw
|
|||
|
you type ipmasqadm autofw.
|
|||
|
|
|||
|
|
|||
|
6.8. xosview is Broken!
|
|||
|
|
|||
|
Upgrade to version 1.6.0 or above, which doesn't require any firewall
|
|||
|
rules at all for 2.1.x kernels. This seems to have broken again in
|
|||
|
the 1.6.1 release; please bug the author (it's not my fault!).
|
|||
|
|
|||
|
|
|||
|
6.9. Segmentation Fault With `-j REDIRECT'!
|
|||
|
|
|||
|
This was a bug in ipchains version 1.3.3. Please upgrade.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
6.10. I Can't Set Masquerading Timeouts!
|
|||
|
|
|||
|
True (for 2.1.x kernels) up to 2.1.123. In 2.1.124, trying to set the
|
|||
|
masquerading timeouts causes a kernel lockup (change return to ret =
|
|||
|
on line 1328 of net/ipv4/ip_fw.c). In 2.1.125, it works fine.
|
|||
|
|
|||
|
|
|||
|
6.11. I Want to Firewall IPX!
|
|||
|
|
|||
|
So do a number of others, it seems. My code only covers IP,
|
|||
|
unfortunately. On the good side, all the hooks are there to firewall
|
|||
|
IPX! You just need to write the code; I will happily help where
|
|||
|
possible.
|
|||
|
|
|||
|
|
|||
|
7. A Serious Example.
|
|||
|
|
|||
|
This example was extracted from Michael Neuling and my March 1999
|
|||
|
LinuxWorld Tutorial; this is not the only way to solve the given
|
|||
|
problem, but it is probably the simplest. I hope you will find it
|
|||
|
informative.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.1. The Arrangement
|
|||
|
|
|||
|
|
|||
|
<20> Masqueraded internal network (various operating systems), which we
|
|||
|
call "GOOD".
|
|||
|
|
|||
|
<20> Exposed servers in a separate network (called "DMZ" for
|
|||
|
Demilitarized Zone).
|
|||
|
|
|||
|
<20> PPP Connection to the Internet (called "BAD").
|
|||
|
|
|||
|
|
|||
|
|
|||
|
External Network (BAD)
|
|||
|
|
|
|||
|
|
|
|||
|
ppp0|
|
|||
|
---------------
|
|||
|
| 192.84.219.1| Server Network (DMZ)
|
|||
|
| |eth0
|
|||
|
| |----------------------------------------------
|
|||
|
| |192.84.219.250 | | |
|
|||
|
| | | | |
|
|||
|
|192.168.1.250| | | |
|
|||
|
--------------- -------- ------- -------
|
|||
|
| eth1 | SMTP | | DNS | | WWW |
|
|||
|
| -------- ------- -------
|
|||
|
| 192.84.219.128 192.84.219.129 192.84.218.130
|
|||
|
|
|
|||
|
Internal Network (GOOD)
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.2. Goals
|
|||
|
|
|||
|
|
|||
|
Packet Filter box:
|
|||
|
|
|||
|
|
|||
|
PING any network
|
|||
|
This is really useful to tell if a machine is down.
|
|||
|
|
|||
|
|
|||
|
TRACEROUTE any network
|
|||
|
Once again, useful for diagnosis.
|
|||
|
|
|||
|
|
|||
|
Access DNS
|
|||
|
To make ping and DNS more useful.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Within the DMZ:
|
|||
|
|
|||
|
|
|||
|
Mail server
|
|||
|
|
|||
|
<20> SMTP to external
|
|||
|
|
|||
|
<20> Accept SMTP from internal and external
|
|||
|
|
|||
|
<20> Accept POP-3 from internal
|
|||
|
|
|||
|
Name Server
|
|||
|
|
|||
|
<20> Send DNS to external
|
|||
|
|
|||
|
<20> Accept DNS from internal, external and packet filter box
|
|||
|
|
|||
|
|
|||
|
Web server
|
|||
|
|
|||
|
<20> Accept HTTP from internal and external
|
|||
|
|
|||
|
<20> Rsync access from internal
|
|||
|
|
|||
|
|
|||
|
Internal:
|
|||
|
|
|||
|
Allow WWW, ftp, traceroute, ssh to external
|
|||
|
These are fairly standard things to allow: some places start by
|
|||
|
allowing the internal machines to do just about everything, but
|
|||
|
here we're being restrictive.
|
|||
|
|
|||
|
|
|||
|
Allow SMTP to Mail server
|
|||
|
Obviously, we want them to be able to send mail out.
|
|||
|
|
|||
|
|
|||
|
Allow POP-3 to Mail server
|
|||
|
This is how they read their mail.
|
|||
|
|
|||
|
|
|||
|
Allow DNS to Name server
|
|||
|
They need to be able to look up external names for WWW, ftp,
|
|||
|
traceroute and ssh.
|
|||
|
|
|||
|
|
|||
|
Allow rsync to Web server
|
|||
|
This is how they synchronize the external web server with the
|
|||
|
internal one.
|
|||
|
|
|||
|
|
|||
|
Allow WWW to Web server
|
|||
|
Obviously, they should be able to connect to our external web
|
|||
|
server.
|
|||
|
|
|||
|
|
|||
|
Allow ping to packet filter box
|
|||
|
This is a courteous thing to allow: it means that they can test
|
|||
|
if the firewall box is down (so we don't get blamed if an
|
|||
|
external site is broken).
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.3. Before Packet Filtering
|
|||
|
|
|||
|
|
|||
|
<20> Anti-spoofing
|
|||
|
|
|||
|
|
|||
|
Since we don't have any asymmetric routing, we can simply turn on
|
|||
|
anti-spoofing for all interfaces.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f; done
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<20> Set filtering rules to DENY all:
|
|||
|
|
|||
|
|
|||
|
We still allow local loopback traffic, but deny anything else.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# ipchains -A input -i ! lo -j DENY
|
|||
|
# ipchains -A output -i ! lo -j DENY
|
|||
|
# ipchains -A forward -j DENY
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<20> Set Up Interfaces
|
|||
|
|
|||
|
|
|||
|
This is usually done in the boot scripts. Make sure the above
|
|||
|
steps are done before the interfaces are configured, to prevent
|
|||
|
packet leakage before the rules are set up.
|
|||
|
|
|||
|
|
|||
|
<20> Insert per-protocol masquerading modules.
|
|||
|
|
|||
|
We need to insert the masquerading module for FTP, so that active
|
|||
|
and passive FTP `just work' from the internal network.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
# insmod ip_masq_ftp
|
|||
|
#
|
|||
|
|
|||
|
|
|||
|
7.4. Packet Filtering for Through Packets
|
|||
|
|
|||
|
With masquerading, it's best to filter in the forward chain.
|
|||
|
|
|||
|
|
|||
|
Split forward chain into various user chains depending on source/dest
|
|||
|
interfaces; this breaks the problem down into managable chunks.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ipchains -N good-dmz
|
|||
|
ipchains -N bad-dmz
|
|||
|
ipchains -N good-bad
|
|||
|
ipchains -N dmz-good
|
|||
|
ipchains -N dmz-bad
|
|||
|
ipchains -N bad-good
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ACCEPTing standard error ICMPs is a common thing to do, so we create a
|
|||
|
chain for it.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ipchains -N icmp-acc
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.4.1. Set Up Jumps From forward Chain
|
|||
|
|
|||
|
Unfortunately, we only know (in the forward chain) the outgoing
|
|||
|
interface. Thus, to figure out what interface the packet came in on,
|
|||
|
we use the source address (the anti-spoofing prevents address faking).
|
|||
|
|
|||
|
|
|||
|
Note that we log anything which doesn't match any of these (obviously,
|
|||
|
this should never happen).
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ipchains -A forward -s 192.168.1.0/24 -i eth0 -j good-dmz
|
|||
|
ipchains -A forward -s 192.168.1.0/24 -i ppp0 -j good-bad
|
|||
|
ipchains -A forward -s 192.84.219.0/24 -i ppp0 -j dmz-bad
|
|||
|
ipchains -A forward -s 192.84.219.0/24 -i eth1 -j dmz-good
|
|||
|
ipchains -A forward -i eth0 -j bad-dmz
|
|||
|
ipchains -A forward -i eth1 -j bad-good
|
|||
|
ipchains -A forward -j DENY -l
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.4.2. Define the icmp-acc Chain
|
|||
|
|
|||
|
Packets which are one of the error ICMPs get ACCEPTed, otherwise,
|
|||
|
control will pass back to the calling chain.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ipchains -A icmp-acc -p icmp --icmp-type destination-unreachable -j ACCEPT
|
|||
|
ipchains -A icmp-acc -p icmp --icmp-type source-quench -j ACCEPT
|
|||
|
ipchains -A icmp-acc -p icmp --icmp-type time-exceeded -j ACCEPT
|
|||
|
ipchains -A icmp-acc -p icmp --icmp-type parameter-problem -j ACCEPT
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.4.3. Good (Internal) to DMZ (Servers)
|
|||
|
|
|||
|
Internal restrictions:
|
|||
|
|
|||
|
<20> Allow WWW, ftp, traceroute, ssh to external
|
|||
|
|
|||
|
<20> Allow SMTP to Mail server
|
|||
|
|
|||
|
<20> Allow POP-3 to Mail server
|
|||
|
|
|||
|
<20> Allow DNS to Name server
|
|||
|
|
|||
|
<20> Allow rsync to Web server
|
|||
|
|
|||
|
<20> Allow WWW to Web server
|
|||
|
|
|||
|
<20> Allow ping to packet filter box
|
|||
|
|
|||
|
Could do masquerading from internal network into DMZ, but here we
|
|||
|
don't. Since noone in the internal network should be trying to do
|
|||
|
evil things, we log any packets that get denied.
|
|||
|
|
|||
|
|
|||
|
Note that old versions of Debian called `pop3' `pop-3' in
|
|||
|
/etc/services, which disagrees with RFC1700.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ipchains -A good-dmz -p tcp -d 192.84.219.128 smtp -j ACCEPT
|
|||
|
ipchains -A good-dmz -p tcp -d 192.84.219.128 pop3 -j ACCEPT
|
|||
|
ipchains -A good-dmz -p udp -d 192.84.219.129 domain -j ACCEPT
|
|||
|
ipchains -A good-dmz -p tcp -d 192.84.219.129 domain -j ACCEPT
|
|||
|
ipchains -A good-dmz -p tcp -d 192.84.218.130 www -j ACCEPT
|
|||
|
ipchains -A good-dmz -p tcp -d 192.84.218.130 rsync -j ACCEPT
|
|||
|
ipchains -A good-dmz -p icmp -j icmp-acc
|
|||
|
ipchains -A good-dmz -j DENY -l
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.4.4. Bad (external) to DMZ (servers).
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<20> DMZ restrictions:
|
|||
|
|
|||
|
<20> Mail server
|
|||
|
|
|||
|
<20> SMTP to external
|
|||
|
|
|||
|
<20> Accept SMTP from internal and external
|
|||
|
|
|||
|
<20> Accept POP-3 from internal
|
|||
|
|
|||
|
|
|||
|
<20> Name server
|
|||
|
|
|||
|
<20> Send DNS to external
|
|||
|
|
|||
|
<20> Accept DNS from internal, external and packet filter box
|
|||
|
|
|||
|
|
|||
|
<20> Web server
|
|||
|
|
|||
|
<20> Accept HTTP from internal and external
|
|||
|
|
|||
|
<20> Rsync access from internal
|
|||
|
|
|||
|
|
|||
|
<20> Things we allow from external network to DMZ.
|
|||
|
|
|||
|
<20> Don't log violations, as they may happen.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ipchains -A bad-dmz -p tcp -d 192.84.219.128 smtp -j ACCEPT
|
|||
|
ipchains -A bad-dmz -p udp -d 192.84.219.129 domain -j ACCEPT
|
|||
|
ipchains -A bad-dmz -p tcp -d 192.84.219.129 domain -j ACCEPT
|
|||
|
ipchains -A bad-dmz -p tcp -d 192.84.218.130 www -j ACCEPT
|
|||
|
ipchains -A bad-dmz -p icmp -j icmp-acc
|
|||
|
ipchains -A bad-dmz -j DENY
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.4.5. Good (internal) to Bad (external).
|
|||
|
|
|||
|
|
|||
|
<20> Internal restrictions:
|
|||
|
|
|||
|
<20> Allow WWW, ftp, traceroute, ssh to external
|
|||
|
|
|||
|
<20> Allow SMTP to Mail server
|
|||
|
|
|||
|
<20> Allow POP-3 to Mail server
|
|||
|
|
|||
|
<20> Allow DNS to Name server
|
|||
|
|
|||
|
<20> Allow rsync to Web server
|
|||
|
|
|||
|
<20> Allow WWW to Web server
|
|||
|
|
|||
|
<20> Allow ping to packet filter box
|
|||
|
|
|||
|
<20> Many people allow everything from the internal to external
|
|||
|
networks, then add restrictions. We're being fascist.
|
|||
|
|
|||
|
<20> Log violations.
|
|||
|
|
|||
|
<20> Passive FTP handled by masq. module.
|
|||
|
|
|||
|
<20> UDP destination ports 33434 and up are used by traceroute.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ipchains -A good-bad -p tcp --dport www -j MASQ
|
|||
|
ipchains -A good-bad -p tcp --dport ssh -j MASQ
|
|||
|
ipchains -A good-bad -p udp --dport 33434:33500 -j MASQ
|
|||
|
ipchains -A good-bad -p tcp --dport ftp -j MASQ
|
|||
|
ipchains -A good-bad -p icmp --icmp-type ping -j MASQ
|
|||
|
ipchains -A good-bad -j REJECT -l
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.4.6. DMZ to Good (internal).
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<20> Internal restrictions:
|
|||
|
|
|||
|
<20> Allow WWW, ftp, traceroute, ssh to external
|
|||
|
|
|||
|
<20> Allow SMTP to Mail server
|
|||
|
|
|||
|
<20> Allow POP-3 to Mail server
|
|||
|
|
|||
|
<20> Allow DNS to Name server
|
|||
|
|
|||
|
<20> Allow rsync to Web server
|
|||
|
|
|||
|
<20> Allow WWW to Web server
|
|||
|
|
|||
|
<20> Allow ping to packet filter box
|
|||
|
|
|||
|
|
|||
|
<20> If we were masquerading from the internal network to the DMZ,
|
|||
|
simply refuse any packets coming the other way. As it is, only
|
|||
|
allow packets which might be part of an established connection.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ipchains -A dmz-good -p tcp ! -y -s 192.84.219.128 smtp -j ACCEPT
|
|||
|
ipchains -A dmz-good -p udp -s 192.84.219.129 domain -j ACCEPT
|
|||
|
ipchains -A dmz-good -p tcp ! -y -s 192.84.219.129 domain -j ACCEPT
|
|||
|
ipchains -A dmz-good -p tcp ! -y -s 192.84.218.130 www -j ACCEPT
|
|||
|
ipchains -A dmz-good -p tcp ! -y -s 192.84.218.130 rsync -j ACCEPT
|
|||
|
ipchains -A dmz-good -p icmp -j icmp-acc
|
|||
|
ipchains -A dmz-good -j DENY -l
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.4.7. DMZ to bad (external).
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<20> DMZ restrictions:
|
|||
|
|
|||
|
<20> Mail server
|
|||
|
|
|||
|
<20> SMTP to external
|
|||
|
|
|||
|
<20> Accept SMTP from internal and external
|
|||
|
|
|||
|
<20> Accept POP-3 from internal
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<20> Name server
|
|||
|
|
|||
|
<20> Send DNS to external
|
|||
|
|
|||
|
<20> Accept DNS from internal, external and packet filter box
|
|||
|
|
|||
|
|
|||
|
<20> Web server
|
|||
|
|
|||
|
<20> Accept HTTP from internal and external
|
|||
|
|
|||
|
<20> Rsync access from internal
|
|||
|
|
|||
|
|
|||
|
<20>
|
|||
|
|
|||
|
|
|||
|
ipchains -A dmz-bad -p tcp -s 192.84.219.128 smtp -j ACCEPT
|
|||
|
ipchains -A dmz-bad -p udp -s 192.84.219.129 domain -j ACCEPT
|
|||
|
ipchains -A dmz-bad -p tcp -s 192.84.219.129 domain -j ACCEPT
|
|||
|
ipchains -A dmz-bad -p tcp ! -y -s 192.84.218.130 www -j ACCEPT
|
|||
|
ipchains -A dmz-bad -p icmp -j icmp-acc
|
|||
|
ipchains -A dmz-bad -j DENY -l
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.4.8. Bad (external) to Good (internal).
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<20> We don't allow anything (non-masqueraded) from the external network
|
|||
|
to the internal network
|
|||
|
|
|||
|
|
|||
|
ipchains -A bad-good -j REJECT
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.4.9. Packet Filtering for the Linux Box Itself
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<20> If we want to use packet filtering on packets coming into the box
|
|||
|
itself, we need to do filtering in the input chain. We create one
|
|||
|
chain for each destination interface:
|
|||
|
|
|||
|
|
|||
|
ipchains -N bad-if
|
|||
|
ipchains -N dmz-if
|
|||
|
ipchains -N good-if
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<20> Create jumps to them:
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ipchains -A input -d 192.84.219.1 -j bad-if
|
|||
|
ipchains -A input -d 192.84.219.250 -j dmz-if
|
|||
|
ipchains -A input -d 192.168.1.250 -j good-if
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.4.9.1. Bad (external) interface.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<20> Packet Filter box:
|
|||
|
|
|||
|
<20> PING any network
|
|||
|
|
|||
|
<20> TRACEROUTE any network
|
|||
|
|
|||
|
<20> Access DNS
|
|||
|
|
|||
|
|
|||
|
<20> External interface also receives replies to masqueraded packets
|
|||
|
(masquerading uses source ports 61000 to 65095) and ICMP errors for
|
|||
|
them and PING replies.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ipchains -A bad-if -i ! ppp0 -j DENY -l
|
|||
|
ipchains -A bad-if -p TCP --dport 61000:65095 -j ACCEPT
|
|||
|
ipchains -A bad-if -p UDP --dport 61000:65095 -j ACCEPT
|
|||
|
ipchains -A bad-if -p ICMP --icmp-type pong -j ACCEPT
|
|||
|
ipchains -A bad-if -j icmp-acc
|
|||
|
ipchains -A bad-if -j DENY
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.4.9.2. DMZ interface.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<20> Packet Filter box restrictions:
|
|||
|
|
|||
|
<20> PING any network
|
|||
|
|
|||
|
<20> TRACEROUTE any network
|
|||
|
|
|||
|
<20> Access DNS
|
|||
|
|
|||
|
|
|||
|
<20> DMZ interface receives DNS replies, ping replies and ICMP errors.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ipchains -A dmz-if -i ! eth0 -j DENY
|
|||
|
ipchains -A dmz-if -p TCP ! -y -s 192.84.219.129 53 -j ACCEPT
|
|||
|
ipchains -A dmz-if -p UDP -s 192.84.219.129 53 -j ACCEPT
|
|||
|
ipchains -A dmz-if -p ICMP --icmp-type pong -j ACCEPT
|
|||
|
ipchains -A dmz-if -j icmp-acc
|
|||
|
ipchains -A dmz-if -j DENY -l
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.4.9.3. Good (internal) interface.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
<20> Packet Filter box restrictions:
|
|||
|
|
|||
|
<20> PING any network
|
|||
|
|
|||
|
<20> TRACEROUTE any network
|
|||
|
|
|||
|
<20> Access DNS
|
|||
|
|
|||
|
|
|||
|
<20> Internal restrictions:
|
|||
|
|
|||
|
<20> Allow WWW, ftp, traceroute, ssh to external
|
|||
|
|
|||
|
<20> Allow SMTP to Mail server
|
|||
|
|
|||
|
<20> Allow POP-3 to Mail server
|
|||
|
|
|||
|
<20> Allow DNS to Name server
|
|||
|
|
|||
|
<20> Allow rsync to Web server
|
|||
|
|
|||
|
<20> Allow WWW to Web server
|
|||
|
|
|||
|
<20> Allow ping to packet filter box
|
|||
|
|
|||
|
|
|||
|
<20> Internal interface receives pings, ping replies and ICMP errors.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ipchains -A good-if -i ! eth1 -j DENY
|
|||
|
ipchains -A good-if -p ICMP --icmp-type ping -j ACCEPT
|
|||
|
ipchains -A good-if -p ICMP --icmp-type pong -j ACCEPT
|
|||
|
ipchains -A good-if -j icmp-acc
|
|||
|
ipchains -A good-if -j DENY -l
|
|||
|
|
|||
|
|
|||
|
|
|||
|
7.5. Finally
|
|||
|
|
|||
|
|
|||
|
<20> Delete blocking rules:
|
|||
|
|
|||
|
|
|||
|
ipchains -D input 1
|
|||
|
ipchains -D forward 1
|
|||
|
ipchains -D output 1
|
|||
|
|
|||
|
|
|||
|
|
|||
|
8. Appendix: Differences between ipchains and ipfwadm.
|
|||
|
|
|||
|
Some of these changes are a result of kernel changes, and some a
|
|||
|
result of ipchains being different from ipfwadm.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
1. Many arguments have been remapped: capitals now indicates a
|
|||
|
command, and lower case now indicates an option.
|
|||
|
|
|||
|
2. Arbitrary chains are supported, so even built-in chains have full
|
|||
|
names instead of flags (eg. `input' instead of `-I').
|
|||
|
|
|||
|
3. The `-k' option has vanished: use `! -y'.
|
|||
|
|
|||
|
4. The `-b' option actually inserts/appends/deletes two rules, rather
|
|||
|
than a single `bidirectional' rule.
|
|||
|
|
|||
|
5. The `-b' option can be passed to `-C' to do two checks (one in each
|
|||
|
direction).
|
|||
|
|
|||
|
6. The `-x' option to `-l' has been replaced by `-v'.
|
|||
|
|
|||
|
7. Multiple source and destination ports are not supported anymore.
|
|||
|
Hopefully being able to negate the port range will somewhat make up
|
|||
|
for that.
|
|||
|
|
|||
|
8. Interfaces can only be specified by name (not address). The old
|
|||
|
semantics got silently changed in the 2.1 kernel series anyway.
|
|||
|
|
|||
|
9. Fragments are examined, not automatically allowed through.
|
|||
|
|
|||
|
10.
|
|||
|
Explicit accounting chains have been done away with.
|
|||
|
|
|||
|
11.
|
|||
|
Arbitrary protocols over IP can be tested for.
|
|||
|
|
|||
|
12.
|
|||
|
The old behavior of SYN and ACK matching (which was previously
|
|||
|
ignored for non-TCP packets) has changed; the SYN option is not
|
|||
|
valid for non-TCP-specific rules.
|
|||
|
|
|||
|
13.
|
|||
|
Counters are now 64-bit on 32-bit machines, not 32-bit.
|
|||
|
|
|||
|
14.
|
|||
|
Inverse options are now supported.
|
|||
|
|
|||
|
15.
|
|||
|
ICMP codes are now supported.
|
|||
|
|
|||
|
16.
|
|||
|
Wildcard interfaces are now supported.
|
|||
|
|
|||
|
17.
|
|||
|
TOS manipulations are now sanity-checked: the old kernel code would
|
|||
|
silently stop you from (illegally) manipulating the `Must Be Zero'
|
|||
|
TOS bit; ipchains now returns an error if you try, as well as for
|
|||
|
other illegal cases.
|
|||
|
|
|||
|
|
|||
|
8.1. Quick-Reference table.
|
|||
|
|
|||
|
[ Mainly, command arguments are UPPER CASE, and option arguments are
|
|||
|
lower case ]
|
|||
|
|
|||
|
|
|||
|
One thing to note, masquerading is specified by `-j MASQ'; it is
|
|||
|
completely different from `-j ACCEPT', and not treated as merely a
|
|||
|
side-effect, unlike ipfwadm does.
|
|||
|
|
|||
|
|
|||
|
================================================================
|
|||
|
| ipfwadm | ipchains | Notes
|
|||
|
----------------------------------------------------------------
|
|||
|
| -A [both] | -N acct | Create an `acct' chain
|
|||
|
| |& -I 1 input -j acct | and have output and input
|
|||
|
| |& -I 1 output -j acct | packets traverse it.
|
|||
|
| |& acct |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -A in | input | A rule with no target
|
|||
|
----------------------------------------------------------------
|
|||
|
| -A out | output | A rule with no target
|
|||
|
----------------------------------------------------------------
|
|||
|
| -F | forward | Use this as [chain].
|
|||
|
----------------------------------------------------------------
|
|||
|
| -I | input | Use this as [chain].
|
|||
|
----------------------------------------------------------------
|
|||
|
| -O | output | Use this as [chain].
|
|||
|
----------------------------------------------------------------
|
|||
|
| -M -l | -M -L |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -M -s | -M -S |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -a policy | -A [chain] -j POLICY | (but see -r and -m).
|
|||
|
----------------------------------------------------------------
|
|||
|
| -d policy | -D [chain] -j POLICY | (but see -r and -m).
|
|||
|
----------------------------------------------------------------
|
|||
|
| -i policy | -I 1 [chain] -j POLICY| (but see -r and -m).
|
|||
|
----------------------------------------------------------------
|
|||
|
| -l | -L |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -z | -Z |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -f | -F |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -p | -P |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -c | -C |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -P | -p |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -S | -s | Only takes one port or
|
|||
|
| | | range, not multiples.
|
|||
|
----------------------------------------------------------------
|
|||
|
| -D | -d | Only takes one port or
|
|||
|
| | | range, not multiples.
|
|||
|
----------------------------------------------------------------
|
|||
|
| -V | <none> | Use -i [name].
|
|||
|
----------------------------------------------------------------
|
|||
|
| -W | -i |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -b | -b | Now actually makes 2 rules.
|
|||
|
----------------------------------------------------------------
|
|||
|
| -e | -v |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -k | ! -y | Doesn't work unless
|
|||
|
| | | -p tcp also specified.
|
|||
|
----------------------------------------------------------------
|
|||
|
| -m | -j MASQ |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -n | -n |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -o | -l |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -r [redirpt] | -j REDIRECT [redirpt] |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -t | -t |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -v | -v |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -x | -x |
|
|||
|
----------------------------------------------------------------
|
|||
|
| -y | -y | Doesn't work unless
|
|||
|
| | | -p tcp also specified.
|
|||
|
----------------------------------------------------------------
|
|||
|
|
|||
|
|
|||
|
|
|||
|
8.2. Examples of translated ipfwadm commands
|
|||
|
|
|||
|
Old command: ipfwadm -F -p deny
|
|||
|
|
|||
|
New command: ipchains -P forward DENY
|
|||
|
|
|||
|
|
|||
|
Old command: ipfwadm -F -a m -S 192.168.0.0/24 -D 0.0.0.0/0
|
|||
|
|
|||
|
New command: ipchains -A forward -j MASQ -s 192.168.0.0/24 -d
|
|||
|
0.0.0.0/0
|
|||
|
|
|||
|
|
|||
|
Old command: ipfwadm -I -a accept -V 10.1.2.1 -S 10.0.0.0/8 -D
|
|||
|
0.0.0.0/0
|
|||
|
|
|||
|
New command: ipchains -A input -j ACCEPT -i eth0 -s 10.0.0.0/8 -d
|
|||
|
0.0.0.0/0
|
|||
|
|
|||
|
(Note that there is no equivalent for specifying interfaces by
|
|||
|
address: use the interface name. On this machine, 10.1.2.1
|
|||
|
corresponds to eth0).
|
|||
|
|
|||
|
|
|||
|
9. Appendix: Using the ipfwadm-wrapper script.
|
|||
|
|
|||
|
The ipfwadm-wrapper shell script should be a plug-in replacement of
|
|||
|
ipfwadm for backwards compatibility with ipfwadm 2.3a.
|
|||
|
|
|||
|
|
|||
|
The only feature it can't really handle is the `-V' option. When this
|
|||
|
is used, a warning is given. If the `-W' option is also used, the
|
|||
|
`-V' option is ignored. Otherwise, the script tries to find the
|
|||
|
interface name associated with that address, using ifconfig. If that
|
|||
|
fails (such as for an interface which is down) then it will exit with
|
|||
|
an error message.
|
|||
|
|
|||
|
|
|||
|
This warning can be suppressed by either changing the `-V' to a `-W',
|
|||
|
or directing the standard output of the script to /dev/null.
|
|||
|
|
|||
|
|
|||
|
If you should find any mistakes in this script, or any changes between
|
|||
|
the real ipfwadm and this script, please report a bug to me: send an
|
|||
|
EMail to rusty@linuxcare.com with "BUG-REPORT" in the subject. Please
|
|||
|
list your old version of ipfwadm (ipfwadm -h), your version of
|
|||
|
ipchains (ipchains --version), the version of the ipfwadm wrapper
|
|||
|
script (ipfwadm-wrapper --version). Also send the output of ipchains-
|
|||
|
save. Thanks in advance.
|
|||
|
|
|||
|
|
|||
|
Mix ipchains with this ipfwadm-wrapper script at your own peril.
|
|||
|
|
|||
|
|
|||
|
10. Appendix: Thanks.
|
|||
|
|
|||
|
Many thanks have to go to Michael Neuling, who wrote the first
|
|||
|
releasable cut of the IP chains code while working for me. Public
|
|||
|
apologies for nixing his result-caching idea, which Alan Cox later
|
|||
|
proposed and I have finally begun implementing, having seen the error
|
|||
|
of my ways.
|
|||
|
|
|||
|
|
|||
|
Thanks to Alan Cox for his 24-hour EMail tech support, and
|
|||
|
encouragement.
|
|||
|
|
|||
|
|
|||
|
Thanks to all the authors of the ipfw and ipfwadm code, especially Jos
|
|||
|
Vos. Standing on the shoulders of giants and all that... This
|
|||
|
applies to Linus Torvalds and all the kernel and userspace hackers as
|
|||
|
well.
|
|||
|
|
|||
|
|
|||
|
Thanks to the diligent beta testers and bughunters, especially Jordan
|
|||
|
Mendelson, Shaw Carruthers, Kevin Moule, Dr. Liviu Daia, Helmut Adams,
|
|||
|
Franck Sicard, Kevin Littlejohn, Matt Kemner, John D. Hardin, Alexey
|
|||
|
Kuznetsov, Leos Bitto, Jim Kunzman, Gerard Gerritsen, Serge Sivkov,
|
|||
|
Andrew Burgess, Steve Schmidtke, Richard Offer, Bernhard Weisshuhn,
|
|||
|
Larry Auton, Ambrose Li, Pavel Krauz, Steve Chadsey, Francesco
|
|||
|
Potorti`, Alain Knaff, Casper Boden-Cummins and Henry Hollenberg.
|
|||
|
|
|||
|
|
|||
|
10.1. Translations
|
|||
|
|
|||
|
People who do translations should put themselves at the top of the
|
|||
|
Thanks page, like so: `Special thanks to XXX, for translating
|
|||
|
everything exactly from my English.'. Then tell me about your
|
|||
|
translation so I can include it here.
|
|||
|
|
|||
|
|
|||
|
Arnaud Launay, asl@launay.org:
|
|||
|
http://www.freenix.fr/unix/linux/HOWTO/IPCHAINS-HOWTO.html
|
|||
|
<http://www.freenix.fr/unix/linux/HOWTO/IPCHAINS-HOWTO.html>
|
|||
|
|
|||
|
|
|||
|
Giovanni Bortolozzo, borto@pluto.linux.it:
|
|||
|
http://www.pluto.linux.it/ildp/HOWTO/IPCHAINS-HOWTO.html
|
|||
|
<http://www.pluto.linux.it/ildp/HOWTO/IPCHAINS-HOWTO.html>
|
|||
|
|
|||
|
|
|||
|
Herman Rodr<64>guez, herman@maristas.dhis.org:
|
|||
|
http://netfilter.kernelnotes.org/ipchains/spanish/HOWTO.html
|
|||
|
<http://netfilter.kernelnotes.org/ipchains/spanish/HOWTO.html>
|
|||
|
|
|||
|
|
|||
|
|