Netfilter: Linux Firewall implementation in the kernel

Source: Internet
Author: User
Tags ibm developerworks

Introduction to netfilter and Linux Firewall

The firewall technology of Linux has gone through several generations and has evolved step by step. At the beginning, ipfwadm was transplanted from FreeBSD's kernel code at the early stage of Linux kernel development. Later I went through ipchains and developed the netfilter architecture through Paul Russell in the Development of Linux kernel 2.3 series. The user space's firewall management tool is also developed as iptables. The combination of Netfilter and iptables is currently quite satisfactory. After the development of Linux kernel 2.4 and 2.5, it can be said that Netfilter/iptables has withstood the widespread use of a large number of users.

This document does not describe how to use Linux firewall's Management Program iptables in user space. It is not a topic of interest to use Netfilter/iptables to build a reliable Internet firewall. For the use of iptables, readers can refer to the man iptables manual or the packet filtering how-to and Nat how-to written by Paul Russell, the core developer of Netfilter. For more information, see the reference directory. Before reading this article, readers are advised to have a certain understanding of iptables.

This article describes how to implement Netfilter in Linux kernel. If conditions permit, we may further explain in subsequent articles how to write our own kernel modules and embed it in the netfilter architecture to implement our own customized firewall functions. It is worth noting that on the netfilter website, we can see a sub-project patch-o-matic of Netfilter, which contains a large number of customized kernel modules, these modules provide readers with many examples of developing their own kernel modules.

Netfilter interface in IPv4 code

Netfilter is implemented in network protocol stacks such as IPv4, IPv6, and decnet in Linux kernel. This article will only introduce the implementation of Netfilter on the IPv4 protocol stack that interests most readers.

We will note that netfilter is an optional part during the compilation of Linux kernel. That is to say, you can decide whether to compile the kernel into the Kernel support of Netfilter according to your own needs. This brings us a reminder that the impact of the Code implementing netfilter on the Code Implementing the IPv4 protocol stack should be as small as possible, not so noticeable. Otherwise, the Code maintenance of the IPv4 protocol stack will have to be involved with the maintenance of the Code implementing netfilter, which is a headache.

Indeed, in order to support the netfilter architecture, the IPv4 protocol stack carefully selects five reference points in the travel route of IP packet on the IPv4 protocol stack. Each of these five reference points introduces a corresponding call to the nf_hook () Macro function. The five reference points are named prerouting, local-in, forward, local-Out, And postrouting respectively. The meanings of these five reference points are described accurately in iptables instructions. I believe readers should understand them. From the following grep output, we can see that the IPv4 protocol stack implementation code calls the nf_hook () Macro function:

zhaoway@qhq ~/linux-2.4.19/net/ipv4 $ grep -n NF_HOOK *.carp.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 hookigmp.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 hookip_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 $ 

The Macro function nf_hook () is defined in the linux-2.4.19/include/Linux/netfilter. h. When # ifdef config_netfilter is defined, the nf_hook_slow () function is called. If config_netfilter is not defined, the netfilter module is switched back to the IPv4 protocol stack to continue processing. This gives you an option when compiling the kernel. You can decide whether to compile the netfilter support code into the kernel by defining config_netfilter or not. From the name of this function, we can also guess that we can regard the five reference points on the IPv4 protocol stack as five hooks. When the IP packet travels on the IPv4 protocol stack, the five hooks will be caught by the netfilter module, reviewed, and determined the next fate of packet according to the review results: is it because the IPv4 protocol stack is replaced by the original one, so that you can continue to travel? After some modifications, do you want to put it back? Or simply discard it?

Core modules of Netfilter

"Hooks" and "Fishing points"

After the IP packet is caught by nf_hook () from the IPv4 protocol stack, it enters the nf_hook_slow () function in linux-2.4.19/NET/CORE/netfilter. C for processing. The main task of this function is to process packet according to the nf_hooks [] array. Accurately speaking, the five reference points on the IPv4 protocol stack mentioned in the previous section are not "phishing hooks", but "locations where fishing is allowed ". In other words, the IPv4 protocol stack defines five "Fishing points allowed ". In each "fishing spot", netfilter can be placed with a "Fish Hook" to catch the passing packet. So where are the netfiler hooks? Put it in the nf_hooks [] [] array. The hooks are described using the following struct defined in linux-2.4.19/include/Linux/netfilter. h:

struct nf_hook_ops{        struct list_head list;        nf_hookfn *hook;        int pf;        int hooknum;        int priority;};

We can see that the essence of "hooks" is an nf_hookfn function. This function will initially process the caught IP packet. Who put these "hooks" in the nf_hooks [] [] array? The answer is: each table. Readers familiar with iptables management tools should understand that a table is a set of similar firewall rules. By default, iptables defines three tables: filter, mangle, and Nat. Taking filter table as an example, it is a kernel module implemented in linux-2.4.19/NET/IPv4/Netfilter/iptable_filter.c. During the initialization of this module, it will call nf_register_hook () to register a set of "hooks" with the core code of Netfilter ". In fact, this registration process refers to the process of putting "hooks" into "Fishing points. The specific position of the "fishing spot" is described by the subscript of the nf_hooks [] [] array.

Ipt_do_table ()

We see the specific linux-2.4.19/NET/IPv4/Netfilter/iptable_filter.c is the implementation code of the filter table, it is found that the filter table on the "Fish Hook" nf_hookfn function, mainly in the call ipt_do_table () function. This is a function defined in linux-2.4.19/NET/IPv4/Netfilter/ip_tables.c. As mentioned above, a table is a set of firewall rules. Obviously, what the ipt_do_table () function will do is to process the IP packet that is caught according to the rules stored in the table.

Table stores all the firewall rules in this table. But not all rules need to be taken. Review the packet according to it. In fact, only the rules associated with the "Fish Hook" is caught by this packet to review the packet. This mechanism implements multiple chains for each table, and each chain has multiple rules. Moreover, we can immediately see that a chain corresponds to a "fishing spot" on the IPv4 protocol stack. Readers who are familiar with the use of iptables user space management tools should immediately notice this point.

In linux-2.4.19/include/Linux/netfilter_ipv4/ip_tables.h, the storage format of rule in table is defined 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 ipt_counters counters;        /* The matches (if any), then the target. */        unsigned char elems[0];};

An entry is a rule. An entry consists of two parts. One part is a series of matches; the other part is a target. The answer to these matches is whether the related packet matches the rule. What should I do if packet matches this target? That is, it is up to target to determine the future fate of the matched packet. Struct ipt_ip is defined 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 immediately see that some characteristics of the packet to be matched in the struct ipt_ip are recorded.

Match and target

The core part of Netfilter provides an architecture for analyzing and processing packet, but the core part of the Code does not specifically analyze and process packet. This specific analysis and disposal task is handed over to other modules for completion. The core part of the code can be submitted to the module code that can process the corresponding rules according to the rules information recorded in the table. So, how does the core code know which module can handle the rules? This requires you to actively register with the core code, ipt_register_target () or ipt_register_match () when various corresponding modules are started (). This registration process mainly notifies the core code. This module has a target () function that determines the fate of packet. Alternatively, this module has a match () function, you can determine whether a packet meets the matching requirements of rules.

This reminds us that if we want to write our own firewall module embedded in the netfilter architecture, the main task we need to do is to register ipt_register_target () or ipt_register_match () with the netfilter core ().

Iptables management tool

Finally, it should be noted that iptables is a management tool located in the user space. As we can see above, the netfilter code in the kernel space completes the Analysis and Processing of packet based on the rules in the table. However, the specific firewall rules in these tables must be edited by the system administrator. The Netfilter in the kernel only provides a mechanism. It does not know how to use this mechanism to Write appropriate rules to implement a network firewall. Then, how does the system administrator enter the table maintained by Netfilter in the kernel space?

This task is completed by iptables. It is called by getsockopt () and setsockopt () systems to enter the kernel space. These two calls are part of the BSD socket interface. The problem here is what should IPv4 address when receiving an opt that is not recognized by a sock? Netfilter requires it to call nf_sockopt () appropriately in the ip_sockopt () function called by the getsockopt () and setsockopt () systems in the linux-2.4.19/NET/IPv4/ip_sockglue.c file (). In this way, the user space can communicate with the core part of Netfilter and maintain the firewall rules in the table.

Summary

Netfilter has very small changes to IPv4. One is to call nf_hook () in several places, and the other is to call nf_sockopt () in ip_sockopt (). The core part of Netfilter code is to maintain the table. it is explained that the task of table lies in other kernel modules. Netfilter sends the packet caught from the hook and related content in the table to the registered module, which determines the fate of packet.

References

1 Netfilter/iptables main site on the http://www.netfilter.org or http://www.iptables.org on this site, you can find netfilter core Developer Paul Russell write Linux packet filtering how-, linux Nat how-to and other technical articles on how to deploy the Linux netfilter firewall.

2 Linux kernel source code online cross index in the http://lxr.linux.no site can help readers more easily read the Linux kernel source code.

About the author

Zhao Wei, an independent technical consultant for Linux/Free Software in Nanjing. I have published many Chinese articles on IBM developerworks. A list of technical articles he posted on the internet can be found in the http://www.advogato.org/person/zhaoway. He often visits the linuxunix version on Nanjing University's little Lily BBS. The ID of Zhao Wei in http://bbs.nju.edu.cn on Lily is iloveqhq. Welcome to discuss various technical issues related to Linux/free software with him.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.