Linux Netfilter Code Trace Part1: Iptable 周世中 嚴長青 Outline • • • • Hook IP Table Ipt_match Ipt_target Outline • • • • Hook IP Table Ipt_match Ipt_target Hooks • Default hooks: – PRE_ROUTING – POST_ROUTING – FORWARD – LOCAL_IN – LOCAL_OUT Hooks PREROUTE FORWARD LOCAL_IN POSTROUTE LOCAL_OUT Hooks • NF_HOOK(pf, hook, skb, indev, outdev, okfn) – pf: protocol family (PF_INET) – hook:the location of the hooks – skb: sk_buff(packet information) – indev: which device the packet come from – outdev: which device the packet go to – okfn: call the function if the packet is accepted Hook – PRE_ROUTING • NF_IP_PRE_ROUTING • ip_input.c:441(ip_rcv) – NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL, ip_rcv_finish) Hook – POST_ROUTING • NF_IP_POST_ROUTING • ip_output.c:190(ip_finish_output) – NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev, ip_finish_output2) • Ip_output.c:232(ip_mc_output) – NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL, newskb->dev, ip_dev_loopback_xmit) Hook – POST_ROUTING • ip_output.c:248(ip_mc_output) – NF_HOOK(PF_INET, NF_IP_POST_ROUTING, newskb, NULL, newskb->dev, ip_dev_loopback_xmit); Hook – FORWARD • NF_IP_FORWARD • ip_forward.c:145(ip_forward) – NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, dev2, ip_forward_finish) Hook – LOCAL_IN • NF_IP_LOCAL_IN • ip_input.c:305(ip_local_deliver) – NF_HOOK(PF_INET, NF_IP_LOCAL_IN, skb, skb->dev, NULL, ip_local_deliver_finish) Hook – LOCAL_OUT • NF_IP_LOCAL_OUT • igmp.c:252 (igmp_send_report) – NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, output_maybe_reroute) • ip_output.c:155 (ip_build_and_send_pkt) – NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, output_maybe_reroute) Hook – Write a new hook • Default a new hook value and modify NF_IP_NUMHOOKS in /include/linux/netfilter_ipv4.h • Insert NF_HOOK into the appropriate place to call the hook Outline • • • • Hook IP Table Ipt_match Ipt_target IP table • • • • Hitches on hooks Separates into data and operations Contains all rules for each hooks Removing or adding a rule will rebuild the rule base • Process the tables in priority on hooks IP table packet packet Hook op op op op IP Table …… ipt_entry op op op IP Table op op op op IP Table …… IP table(ipt_table) • struct ipt_table – char name[] – struct ipt_replace *table; • Seed table, used to product ipt_table_info – unsigned int valid_hooks; – rwlock_t lock; – struct ipt_table_info *private; • The place to record rules IP table(ipt_table) • struct ipt_replace – – – – – – – – – char name[]; unsigned int valid_hooks; unsigned int num_entries; Rules entrance for each HOOK unsigned int size; Default rules for each HOOK unsigned int hook_entry[NF_IP_NUMHOOKS]; unsigned int underflow[NF_IP_NUMHOOKS]; unsigned int num_counters; struct ipt_counters *counters; struct ipt_entry entries[0]; IP table(ipt_table_info) • struct ipt_table_info – unsigned int size – unsigned int number • Number of entries – unsigned int initial_entries • Initial number of entries – unsigned int hook_entry[NF_IP_NUMHOOKS] – unsigned int underflow[NF_IP_NUMHOOKS] – char entries[0] IP table(nf_hook_ops) • struct nf_hook_ops – nf_hookfn *hook • How to process the table on the hook – int pf • Protocol family(e.g. PF_INET) – int hooknum; • Hitches on which hook – int priority; • Priority to process the table in the hook IP table • Default IP Tables: – Filter – Mangle – NAT Write a new table • Define a table – iptable_filter.c: 84 • static struct ipt_table packet_filter = { { NULL, NULL }, "filter", &initial_table.repl, FILTER_VALID_HOOKS, RW_LOCK_UNLOCKED, NULL, THIS_MODULE }; • Define default ipt_replace – iptable_filter.c: 30 Write a new table • Initialize – iptable_filter.c: 128 – Register table, its operations to the hook • Finish – iptable_filter.c: 170 – Unregister table, operations, and clean datas Outline • • • • Hook IP Table Ipt_match Ipt_target Match • A part of a rule • Process a packet and determine whether it fulfill the condition of the rule • Return 1 for true and 0 for false • Match information: specification of the match in a IPT Entry ipt_entry ipt_entry_target ipt_match *match ipt_match ipt_match return unsigned int ipt_entry_match ipt_match The match function ipt_match Ipt_match • struct ipt_match – const char name[]; – int (*match) (); • Match function to match a packet – int (*checkentry)(); • Check whether the parameter to the match is vaild – void (*destroy)(); • Destroy the match information if necessary Build-in match • TCP match – source port, destination port, TCP flag • UDP match – source port, destination port • ICMP match – ICMP code Match extensions • • • • • • • ipt_ah.c: match for AH parameters ipt_esp.c: match for ESP parameters ipt_length.c: match for packet length ipt_limit.c: control the rate ipt_mac.c: match MAC address ipt_mark.c: match NFMASK ipt_multiport.c: match list of ports in TCP/UDP Match extensions • ipt_owner.c: match the owner of the socket • ipt_state.c: match connection tracking information • ipt_tcpmss.c: match TCP MSS(Maximum Segment Size) values • ipt_tos.c: match TOS field • ipt_ttl.c: match TTL field • ipt_unclean.c: check a packet is valid strictly Match example • ipt_tos.c • Define the ipt_match structure – struct ipt_match tos_match = { { NULL, NULL }, "tos", &match, &checkentry, NULL, THIS_MODULE }; • Initialize: register match into iptable • Finish: unregister the match Match example • Match – return (iph->tos == info->tos) ^ info->invert • Checkentry – return matchsize == IPT_ALIGN(sizeof(struct ipt_tos_info)) Write a new match • • • • • Define ipt_match Initialize: register match into iptable Finish: unregister the match Write match and checkentry function Write destroy function if necessary Outline • • • • Hook IP Table Ipt_match Ipt_target Target • A part of a rule • Process a packet and determine the packet verdict • Return verdict or IPT_CONTINUE to continue the iptable • Target information: specification of the match in a IPT Entry ipt_entry ipt_entry_target ipt_target *target ipt_target ipt_target ipt_target return 0 or a packet verdict The target function ipt_entry_match ipt_taeget Ipt_target • struct ipt_target – const char name[]; – int (*target) (); • Target function to determine the verdict of a packet • “Target=NULL” means the ipt_target is a standard target – int (*checkentry)(); • Check whether the parameter to the target is vaild – void (*destroy)(); • Destroy the target information if necessary Standard target • Target in structure ipt_target is NULL • Following a verdict, e.g. NF_ACCEPT, NF_DROP Target extensions • • • • • ipt_LOG.c: logging packets ipt_MARK.c: set NFMARK in sk_buff ipt_MASQUERADE.c: masquerade ipt_MIRROR.c: invert the src and dst IP ipt_REDIRECT.c: alert dst IP to a local IP • ipt_REJECT.c: reject packets(sending ICMP unreachable or TCP reset) Target extensions • ipt_MSS.c: set the TCP MSS field • ipt_TOS.c: set the IP TOS field • ipt_ULOG.c: send to user space daemon to log packets Target example • ipt_TOS.c • Define the ipt_target structure – static struct ipt_target ipt_tos_reg = { { NULL, NULL }, "TOS", target, checkentry, NULL, THIS_MODULE }; • Initialize: register target into iptable • Finish: unregister the target Target example • Target – Change TOS to predefined value in target info – Recompute the IP checksum – Continue filtering • Checkentry – Check size, table, and predefined value to TOS Write a new target • • • • • Define ipt_target Initialize: register target into iptable Finish: unregister the target Write target and checkentry function Write destroy function if necessary Reference • http://www.netfilter.org – IPTables-tutorial