Zhao Wei
zhaoway@public1.ptt.js.cn)
Linux / Free Software Independent Technical Consultant
November 15, 2002
This article describes the specific implementation of Linux's firewall technology NetFilter / iptables in the Linux kernel.
Netfilter and Linux firewall introduction
Linux's firewall technology has experienced a number of generations, step by step. The most beginning IPFWADM is the initial stage of the LINUX KERNEL development, transplanted from FreeBSD's kernel code. Later, IPchains was later developed by Paul Russell in the development of the Linux Kernel 2.3 series. The firewall management tool for user space is also developed into iptables. Netfilter / iptables This combination is currently quite satisfactory. After experiencing Linux Kernel 2.4 and 2.5, it can be said that Netfilter / iptables have experienced a wide range of users.
This article does not intend to introduce the use of Linux firewall in user space management program IPTables. As for how to build a reliable Internet firewall using the Netfilter / iptables mechanism, this is not a topic of this article. With regard to iptables, readers can refer to the manual of Man iptables, and you can refer to Packet Filtering How-to and Nat How-to-To written by Netfilter's core developer Paul Russell. Related links, see the reference directory listed later. Readers and friends are best to have a certain understanding of the use of iptables before reading this article.
This article describes the implementation of Netfilter in Linux Kernel. If conditions permit, we may further explain how to write your own kernel modules in subsequent articles and inlaid in the NetFilter architecture to implement your own custom firewall feature. It is worth pointing out that on the NetFilter's website, you can see a sub-project Patch-O-Matic of Netfilter, which contains a large number of custom kernel modules, which developers to readers and friends, providing it. Very much, very good example.
Netfilter interface in IPv4 code
Netfilter has a corresponding implementation in the network protocol stack in Linux Kernel. This article is limited to the space, which will only introduce the implementation of NetFilter on the IPv4 protocol stack of most readers.
We will notice in the process of compiling Linux Kernel, NetFilter is an optional component during the compilation process. That is, the user can decide whether to compile the Netfilter's kernel support in their own kernel during the compilation kernel. This brings us a prompt to implement the impact of Netfilter's code to implement the code of the IPv4 protocol stack, should be as small as possible, not so compelling. Otherwise, the code maintenance work of the IPv4 protocol stack has to stir with the maintenance of the code of Netfilter, which is headache.
This is true, IPv4 protocol stack In order to achieve support for Netfilter architecture, the IP Packet is carefully selected in the travel route on the IPv4 protocol stack, carefully selected five reference points. At these five reference points, each introduced a corresponding call to the NF_HOOK () macro function. These five reference points are named prerouting, local-in, forward, local-out, and postrouting. Regarding the meaning of these five reference points, there is an accurate narrative in the instructions of iptables, and believes that readers should know. From the following GREP output, we can see the IPv4 protocol stack real code to the NF_HOOK () macro function call: zhaoway @ qhq ~ / linux-2.4.19 / net / ipv4 $ grep -n nf_hook * .c
ARP.C: 591: NF_HOOK (NF_ARP, NF_ARP_OUT, SKB, NULL, DEV, DEV_QUEUE_XMIT);
ARP.C: 871: Return NF_HOOK (NF_ARP, NF_ARP_IN, SKB, DEV, NULL, ARP_PROCESS);
IGMP.c: 187: / * don't just hand nf_hook SKB-> DST-> Output, In Case Netfilter HOOK
IGMP.c: 252: Return NF_HOOK (PF_INET, NF_IP_LOCAL_OUT, SKB, NULL, RT-> u.dst.dev,
IP_forward.c: 145: Return NF_HOOK (PF_INET, NF_IP_FORWARD, SKB, SKB-> DEV, DEV2,
IP_GRE.C: 668: / * NEED THIS Wrapper Because NF_HOOK TAKES The Function AddRESS * /
IP_INPUT.C: 302: Return NF_HOOK (PF_INET, NF_IP_LOCAL_IN, SKB, SKB-> dev, NULL,
IP_INPUT.C: 437: Return NF_HOOK (PF_INET, NF_IP_PRE_ROUTING, SKB, DEV, NULL,
IP_output.c: 111: / * don't just hand nf_hook SKB-> DST-> Output, In Case Netfilter Hook
IP_output.c: 156: Return nf_hook (PF_INET, NF_IP_LOCAL_OUT, SKB, NULL, RT-> u.dst.dev,
IP_output.c: 191: Return NF_HOOK (PF_INET, NF_IP_POST_ROUTING, SKB, NULL, DEV,
IP_output.c: 233: NF_HOOK (PF_INET, NF_IP_POST_ROUTING, NEWSKB, NULL,
IP_output.c: 249: NF_HOOK (PF_INET, NF_IP_POST_ROUTING, NEWSKB, NULL,
IP_output.c: 400: Return NF_HOOK (PF_INET, NF_IP_LOCAL_OUT, SKB, NULL, RT-> U.DST.DEV,
IP_output.c: 603: err = nf_hook (PF_INET, NF_IP_LOCAL_OUT, SKB, NULL,
IP_output.c: 714: Err = NF_HOOK (PF_INET, NF_IP_LOCAL_OUT, SKB, NULL, RT-> U.DST.DEV,
Ipip.c: 516: / * NEED THIS Wrapper Because NF_HOOK TAKES The Function Address * / IPMR.c: 1211: NF_HOOK (PF_INET, NF_IP_FORWARD, SKB2, SKB-> DEV, DEV,
Zhaoway @ qhq ~ / linux-2.4.19 / net / ipv4 $
NF_HOOK () This macro function is defined in Linux-2.4.19 / include / linux / netfilter.h. When #ifdef config_netfilter is defined, turn to the NF_HOOK_SLOW () function; if the config_netfilter is not defined, turn back to the IPv4 protocol stack from the Netfilter module, continue to process. This gives the user an option when compiling KERNEL, can determine whether the Netfilter support code is compiled into the kernel by defining the config_netfilter or not. From the name of this function, we can also guess that the five reference points on the IPv4 protocol stack can be seen as five hooks. When the IP Packet travels from the IPv4 protocol stack, it will be visited by the Netfilter module and reviewed by the Netfilter module. According to the results of the review, the next step of the packet is determined: it is returned by the original IPv4 protocol stack, continue to travel; still after some modifications, put it back; or simply discard it?
Netfilter's core module
"Fish Hook" and "Fishing Point"
After the IP Packet fish is catching up from the IPv4 protocol stack, the ipv4 protocol stack is processed in Linux-2.4.19 / Net / Core / NetFilter.c. The main thing for this function is based on the NF_HOOKS [] array, start processing the Packet. Inscidentally, five reference points on the IPv4 protocol stack in the previous paragraph, are not "hooks of fishing", but "allowed fishing locations". In other words, five "Allow Fishing Points" is defined on the IPv4 protocol stack. In every "fishing point", Netfilter can place a "fish hook" and catch the passed packet. So where is the Netfiler's "Fish Hook"? It is placed in an NF_HOOKS [] [] array. This "fish hook" is described in Linux-2.4.19 / include / Linux / NetFilter.h to describe the following Struct:
Struct NF_HOOK_OPS
{
Struct list_head list;
NF_HOOKFN * HOOK;
INT PF;
Int hooknum;
Int priority;
}
We see that the nature of "fish hook" is an NF_HOOKFN function. This function will preliminary processing on the IP Packet that is caught. So, these "fish hooks" is placed in the nf_hooks [] [] array? The answer is, each table. Readers who are familiar with IPTables Management Tools should understand that a table is a set of similar firewall Rules. Three Table: Filter, Mangle, and Nat are defined by default. For example, it is a Kernel Module implemented in Linux-2.4.19 / net / ipv4 / netfilter / iptable_filter.c. During this Module's initialization, it will call nf_register_hook () to register a group of "fish hooks" to NetFilter's core code. This registration process is actually, that is, put "fish hook" in the process of "fishing point". The specific location of the "Fishing Point" is specifically described by the NF_HOOKS [] [] array. IPT_DO_TABLE ()
We specifically see Linux-2.4.19 / net / ipv4 / netfilter / iptable_filter.c is also the implementation code of the Filter Table, find the NF_HOOKFN function on the Filter Table, mainly in calling the IPT_DO_TABLE () function. . This is a function defined in Linux-2.4.19 / Net / IPv4 / NetFilter / IP_Tables.c. As mentioned earlier, a table is a collection of firewall Rules. Obviously, the IPT_DO_TABLE () function will do, that is, in accordance with one of the other Rules stored in the table, the IP Packet "Fishing" comes.
All firewall Rules in this table is stored in Table. But not all Rules have to take it, follow it to review this packet. In fact, this packet is caught from which "fish hook" is caught, only Rules related to the "fish hook" is used to review this packet. This mechanism is a plurality of Chains, while each chain has multiple Rules. Moreover, we will see it immediately, and a chain corresponds to a "fishing point" on the IPv4 protocol stack. Readers who are familiar with IPTables User Space Management Tools should immediately pay attention to this.
Define the storage format of the Rule in Table in Linux-2.4.19 / include / linux / netfilter_ipv4 / ip_tables.h, as follows:
/ * This structure defines Each of the firewall rules. Consists of 3
Parts Which Are 1) GENERAL IP Header Stuff 2) Match Specific
Stuff 3) The target to perform if the rule matches * /
Struct ipt_entry
{
Struct ipt_ip ip;
/ * Mark with FIELDS That We Care About. * /
Unsigned int NFCache;
/ * SIZE OF IPT_ENTRY MATCHES * /
u_INT16_T TARGET_OFFSET;
/ * SIZE OF IPT_ENTRY MATCHES TARGET * /
u_INT16_T next_offset; / * back Pointer * /
Unsigned int ComeFrom;
/ * Packet and byte counters. * /
Struct pt_counters counters;
/ * The matches (if any), THE TARGET. * /
Unsigned char elems [0];
}
An entry is a Rule. An entry is mainly composed of two parts. Part of a series of matches; another part is a Target. The problem with this several Match to answer is whether the associated packet and this rule match match. And the problem that Target to answer is that once the packet matches, what should I do with this packet? That is to determine the future fate of this matching packet. The definition of the beginning of Struct pt_ip is as follows:
Struct ipt_ip {
/ * Source and Destination IP Addr * /
Struct in_addr src, dst;
/ * Mask for src and dest ip addr * /
Struct in_addr smsk, dmsk;
Char iniface [ifnamsiz], outiface [ifnamsiz];
Unsigned char iniface_mask [ifnamsiz], outiface_mask [ifnamsiz];
/ * Protocol, 0 = any * /
U_INT16_T Proto;
/ * Flags Word * /
U_INT8_T FLAGS;
/ * Inverse Flags * /
U_INT8_T INVFLAGS;
}
We can see some features about this rule to match (Match) Packet on this rule in Struct IPT_IP.
Match and Target
The Netfilter core part provides an analysis, disposing of the Packet architecture, but the core partial code does not specifically analyze, and dispose of the Packet. This specific analysis, the disposal task is handed over to other modules. The core partial code can give the packet to the module code capable of handling the corresponding Rules based on the rules information recorded in the table. So, how can the core code know which module can process which class of Rules? This is to take the initiative to register, ipt_register_target () or ipt_register_match (). This registration process is mainly to notify the core code. This module has a target () function that can determine the fate of the packet; or this module has a match () function that can determine if a packet is compliant with Rules matching requirements.
This prompts us. If you want to write your own firewall module, inlaid in the NetFilter architecture, our main task is to register ipt_register_target () or ipt_register_match () to the NetFilter core.
Iptables management tools
Finally, it is to be explained to iptables, which is a management tool in the user space. As we saw, Netfilter completed the analysis and disposal of the Packet according to the rules in the kernel space. But the specific firewall Rules in these tables must still be written by the system administrator. Netfilter in KERNEL just provides a mechanism, it doesn't know how to use this mechanism, write the right Rules to implement a network firewall. Then, the system administrator writes Rules to enter the Table in the NetFilter maintenance in the Kernel space. This task is done by the tool of iptables. It passes both GetSockOpt () and setsockopt () to enter the Kernel space. These two calls are part of the BSD Socket interface. The problem in this is how IPv4 is receiving the OPT that is not recognized about a SOCK? Netfilter requires it to process NF_SOCKOPT () in the IP_SOCKOPT () function in the Linux-2.4.19 / net / ipv4 / ip_sockglue.c file calls NF_SOCKOPT (). In this way, the user space can communicate with the NetFilter core part, and the firewall Rules in Table can be maintained.
summary
Netfilter's modification of IPv4 is very small, one is NF_HOOK () in several places, and the other is NF_SOCKOPT () in IP_SOCKOPT (). Netfilter's core part of the code is just maintained Table, explaining Table's tasks lies in other kernel modules. Netfilter will send the Packet from the hook "fish" and the relevant content in Table to determine the fate of the packet.
Reference
1 Netfilter / iptables Main Site at http://www.netfilter.org or http://www.iptables.org On this site, you can find Linux Packet Filtering How-to-to-to-to-To, Linux Packet, written by Netfilter core developer Paul Russell. Linux Nat How-to and other technical articles on how to deploy Linux Netfilter firewall.
2 LINUX kernel source code online cross index at http://lxr.linux.no This site can help reader friends more convenient to read Linux Kernel's source program.
About author
Zhao Wei, live in Linux / Free Software independent technical adviser in Nanjing. Published many Chinese articles in IBM DeveloperWorks. About a list of technical articles on the network, you can find it at http://www.advogato.org/person/zhaoway/. He often patron Linuxunix version on the small lily bbs of Nanjing University. The website of the South Size lily is at http://bbs.nju.edu.cn Zhao Wei's ID in the South Size Lily is Iloveqhq Welcome readers and he discusses all technical issues related to Linux / Free Software