📄 packet-filtering-howto.txt
字号:
chain, just after the rule which jumped to this chain.
QUEUE is a special target, which queues the packet for userspace
processing. For this to be useful, two further components are
required:
o a "queue handler", which deals with the actual mechanics of passing
packets between the kernel and userspace; and
o a userspace application to receive, possibly manipulate, and issue
verdicts on packets.
The standard queue handler for IPv4 iptables is the ip_queue
module, which is distributed with the kernel and marked as
experimental.
The following is a quick example of how to use iptables to queue
packets for userspace processing:
# modprobe iptable_filter
# modprobe ip_queue
# iptables -A OUTPUT -p icmp -j QUEUE
With this rule, locally generated outgoing ICMP packets (as created
with, say, ping) are passed to the ip_queue module, which then
attempts to deliver the packets to a userspace application. If no
userspace application is waiting, the packets are dropped.
To write a userspace application, use the libipq API. This is
distributed with iptables. Example code may be found in the testsuite
tools (e.g. redirect.c) in CVS.
The status of ip_queue may be checked via:
/proc/net/ip_queue
The maximum length of the queue (i.e. the number packets delivered to
userspace with no verdict issued back) may be controlled via:
/proc/sys/net/ipv4/ip_queue_maxlen
The default value for the maximum queue length is 1024. Once this
limit is reached, new packets will be dropped until the length of the
queue falls below the limit again. Nice protocols such as TCP inter-
pret dropped packets as congestion, and will hopefully back off when
the queue fills up. However, it may take some experimenting to deter-
mine an ideal maximum queue length for a given situation if the
default value is too small.
[1m7.5. Operations on an Entire Chain[0m
A very useful feature of iptables is the ability to group related
rules into chains. You can call the chains whatever you want, but I
recommend using lower-case letters to avoid confusion with the built-
in chains and targets. Chain names can be up to 31 letters long.
[1m7.5.1. Creating a New Chain[0m
Let's create a new chain. Because I am such an imaginative fellow,
I'll call it test. We use the `-N' or `--new-chain' options:
# iptables -N test
#
It's that simple. Now you can put rules in it as detailed above.
[1m7.5.2. Deleting a Chain[0m
Deleting a chain is simple as well, using the `-X' or `--delete-chain'
options. Why `-X'? Well, all the good letters were taken.
# iptables -X test
#
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.
If you don't specify a chain, then [4mall[24m user-defined chains will be
deleted, if possible.
[1m7.5.3. Flushing a Chain[0m
There is a simple way of emptying all rules out of a chain, using the
`-F' (or `--flush') commands.
# iptables -F FORWARD
#
If you don't specify a chain, then [4mall[24m chains will be flushed.
[1m7.5.4. Listing a Chain[0m
You can list all the rules in a chain by using the `-L' (or `--list')
command.
The `refcnt' listed for each user-defined chain is the number of rules
which have that chain 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 iptables 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 TCP and UDP 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 comparisons, and the interfaces.
Otherwise these values are omitted.
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.
[1m7.5.5. Resetting (Zeroing) Counters[0m
It is useful to be able to reset the counters. This can be done with
the `-Z' (or `--zero') option.
Consider the following:
# iptables -L FORWARD
# iptables -Z FORWARD
#
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'
[4mtogether[24m, to reset the counters while reading them.
[1m7.5.6. Setting Policy[0m
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 earlier. In
this case, the [1mpolicy [22mof 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 either ACCEPT or DROP, for example:
# iptables -P FORWARD DROP
#
[1m8. Using ipchains and ipfwadm[0m
There are modules in the netfilter distribution called ipchains.o and
ipfwadm.o. Insert one of these in your kernel (NOTE: they are
incompatible with ip_tables.o!). Then you can use ipchains or ipfwadm
just like the good old days.
This will be supported for some time yet. I think a reasonable
formula is 2 * [notice of replacement - initial stable release],
beyond the date that a stable release of the replacement is available.
This means that support will probably be dropped in Linux 2.6 or 2.8.
[1m9. Mixing NAT and Packet Filtering[0m
It's common to want to do Network Address Translation (see the NAT
HOWTO) and packet filtering. The good news is that they mix extremely
well.
You design your packet filtering completely ignoring any NAT you are
doing. The sources and destinations seen by the packet filter will be
the `real' sources and destinations. For example, if you are doing
DNAT to send any connections to 1.2.3.4 port 80 through to 10.1.1.1
port 8080, the packet filter would see packets going to 10.1.1.1 port
8080 (the real destination), not 1.2.3.4 port 80. Similarly, you can
ignore masquerading: packets will seem to come from their real
internal IP addresses (say 10.1.1.1), and replies will seem to go back
there.
You can use the `state' match extension without making the packet
filter do any extra work, since NAT requires connection tracking
anyway. To enhance the simple masquerading example in the NAT HOWTO
to disallow any new connections from coming in the ppp0 interface, you
would do this:
# Masquerade out ppp0
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
# Disallow NEW and INVALID incoming or forwarded packets from ppp0.
iptables -A INPUT -i ppp0 -m state --state NEW,INVALID -j DROP
iptables -A FORWARD -i ppp0 -m state --state NEW,INVALID -j DROP
# Turn on IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
[1m10. Differences Between iptables and ipchains[0m
o Firstly, the names of the built-in chains have changed from lower
case to UPPER case, because the INPUT and OUTPUT chains now only
get locally-destined and locally-generated packets. They used to
see all incoming and all outgoing packets respectively.
o The `-i' flag now means the incoming interface, and only works in
the INPUT and FORWARD chains. Rules in the FORWARD or OUTPUT
chains that used `-i' should be changed to `-o'.
o TCP and UDP ports now need to be spelled out with the --source-port
or --sport (or --destination-port/--dport) options, and must be
placed after the `-p tcp' or `-p udp' options, as this loads the
TCP or UDP extensions respectively.
o The TCP -y flag is now --syn, and must be after `-p tcp'.
o The DENY target is now DROP, finally.
o Zeroing single chains while listing them works.
o Zeroing built-in chains also clears policy counters.
o Listing chains gives you the counters as an atomic snapshot.
o REJECT and LOG are now extended targets, meaning they are separate
kernel modules.
o Chain names can be up to 31 characters.
o MASQ is now MASQUERADE and uses a different syntax. REDIRECT,
while keeping the same name, has also undergone a syntax change.
See the NAT-HOWTO for more information on how to configure both of
these.
o The -o option is no longer used to direct packets to the userspace
device (see -i above). Packets are now sent to userspace via the
QUEUE target.
o Probably heaps of other things I forgot.
[1m11. Advice on Packet Filter Design[0m
Common wisdom in the computer security arena is to block everything,
then open up holes as neccessary. This is usually phrased `that which
is not explicitly allowed is prohibited'. I recommend this approach
if security is your maximal concern.
Do not run any services you do not need to, even if you think you have
blocked access to them.
If you are creating a dedicated firewall, start by running nothing,
and blocking all packets, then add services and let packets through as
required.
I recommend security in depth: combine tcp-wrappers (for connections
to the packet filter itself), proxies (for connections passing through
the packet filter), route verification and packet filtering. Route
verification is where a packet which comes from an unexpected
interface is dropped: for example, if your internal network has
addresses 10.1.1.0/24, and a packet with that source address comes in
your external interface, it will be dropped. This can be enabled for
one interface (ppp0) like so:
# echo 1 > /proc/sys/net/ipv4/conf/ppp0/rp_filter
#
Or for all existing and future interfaces like this:
# for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
# echo 1 > $f
# done
#
Debian does this by default where possible. If you have asymmetric
routing (ie. you expect packets coming in from strange directions),
you will want to disable this filtering on those interfaces.
Logging is useful when setting up a firewall if something isn't
working, but on a production firewall, always combine it with the
`limit' match, to prevent someone from flooding your logs.
I highly recommend connection tracking for secure systems: it
introduces some overhead, as all connections are tracked, but is very
useful for controlling access to your networks. You may need to load
the `ip_conntrack.o' module if your kernel does not load modules
automatically, and it's not built into the kernel. If you want to
accurately track complex protocols, you'll need to load the
appropriate helper module (eg. `ip_conntrack_ftp.o').
# iptables -N no-conns-from-ppp0
# iptables -A no-conns-from-ppp0 -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables -A no-conns-from-ppp0 -m state --state NEW -i ! ppp0 -j ACCEPT
# iptables -A no-conns-from-ppp0 -i ppp0 -m limit -j LOG --log-prefix "Bad packet from ppp0:"
# iptables -A no-conns-from-ppp0 -i ! ppp0 -m limit -j LOG --log-prefix "Bad packet not from ppp0:"
# iptables -A no-conns-from-ppp0 -j DROP
# iptables -A INPUT -j no-conns-from-ppp0
# iptables -A FORWARD -j no-conns-from-ppp0
Building a good firewall is beyond the scope of this HOWTO, but my
advice is `always be minimalist'. See the Security HOWTO for more
information on testing and probing your box.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -