Kernel: Lists of packet matching rules similar to ipchains/ipfwadm
Userspace: program `iptables' and library `libiptc' which access tables
Simple functionality (IP header matching) built in
Supports multiple tables
Currently there are three tables: filter, nat, mangle.
filter table used by packet filtering system
- hooks in at LOCAL_IN (INPUT), FORWARD, LOCAL_OUT (OUTPUT)
- iptable_filter hooks in at those points and passes all packets to the table
- default table operated on by iptables program
nat table used to control nat
- hooks in at LOCAL_OUT (OUTPUT), PREROUTING, POSTROUTING
- iptable_nat hooks in and passes packets whose connections have not seen NAT table to the table
mangle table used for special effects
- hooks in at LOCAL_OUT (OUTPUT), PREROUTING
- iptable_mangle hooks in and passes all packets to the table
- -i and -o flags
- DROP, not DENY
- Zeroing single chains while listing them works.
- Zeroing built-in chains also clears policy counters.
- Listing chains gives you the counters as an atomic snapshot.
- Chain names can be up to 31 characters.
We can write new match criteria for rules
Each rule can have 0 or more of these extensions attached.
Consists of two parts:
- Shared library to provide new cmd-line options to iptables
- Module to provide actual packet matching code
tcp, udp, icmp
limit, mac, mark, multiport, owner, state, tos, unclean
Unofficial
- pool, random, length
We can write new targets for rules
Consists of two parts:
- Shared library to provide new cmd-line options to iptables
- Module to provide actual packet action
LOG, MIRROR, REJECT
MARK, TOS
SNAT, DNAT, MASQUERADE, REDIRECT
Unofficial
- POOL, TCPMSS
Documented clearly in the netfilter-hacking HOWTO (English, German)
Really simple to do
Example here is writing a very simple REJECT extension
- Only does ICMP rejects
- Doesn't care which table it is placed in
- Doesn't have userspace component: takes no options
#include <linux/module.h> #include <linux/skbuff.h> #include <net/icmp.h> #include <net/route.h> #include "packet-filter/kernel/ip_tables.h" EXPORT_NO_SYMBOLS; static unsigned int reject(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, const struct net_device *out, const void *targinfo) { icmp_send(*pskb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); return NF_DROP; } static int check(const char *tablename, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) { return (targinfosize == 0 && !(hook_mask & ~((1 << NF_IP_LOCAL_IN) | (1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))); } static struct ipt_target ipt_reject_reg = { { NULL, NULL }, "REJECT", NETFILTER_VERSION, reject, check, THIS_MODULE }; int __init init(void) { if (ipt_register_target(&ipt_reject_reg)) return -EINVAL; return 0; } void __exit cleanup(void) { ipt_unregister_target(&ipt_reject_reg); } module_init(init); module_exit(cleanup);
Philip Blundell ported to IPv6
Userspace `ip6tables' shares almost all code, using macros.
Kernel space shares almost no code.
Only ip6table_filter supported.
Linux 2.4 has a reasonably nice, familiar, general, extensible packet selection framework.
Might even last two kernel generations!
Customisation seems to be popular.