ip_filter
Function introduction
Register the hook function to the netfilter framework through the kernel module, analyze the ip header information, extract the source ip and destination ip, and filter after matching to the specified ip address.
network layer
The network layer introduces the IP protocol and formulates a set of new addresses, so that we can distinguish whether the two hosts belong to the same network. This set of addresses is the network address, that is, the so-called IP address. IP protocol divides the 32-bit address into two parts. The front part represents the network address and the back part represents the address of the host in the LAN. If two IP addresses are in the same subnet, the network address must be the same. In order to judge the network address in the IP address, the IP protocol also introduces the subnet mask. The IP address and subnet mask can get the network address through bitwise sum operation.
Generally speaking, the network layer uses the ip address as the unique identifier for data forwarding, and the ip address can uniquely identify a host. Therefore, if we filter the ip address of the LAN, we can limit the Internet access of a device, and if we filter the ip address of the public network, we can limit the access of all devices to specific resources.
netfilter register hook function
Here we set hooknum to NF_INET_FORWARD
static struct nf_hook_ops ip_filter_ops[] __read_mostly = { { .hook = ip_filter_hook, .pf = PF_INET, .hooknum = NF_INET_FORWARD, .priority = NF_IP_PRI_FIRST + 1, }, }; static int __init ip_filter_init(void) { printk("ip filter...init\n"); nf_register_net_hooks(&init_net, ip_filter_ops, ARRAY_SIZE(ip_filter_ops)); return 0; }
Analysis of ip filter hook function
Source code
static u_int32_t ip_filter_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) { struct nf_conn *ct = (struct nf_conn *)skb->_nfct; struct udphdr *udph = NULL; struct iphdr *iph = NULL; int i; char *black_ip_list[] = { "192.168.66.167", "8.8.8.8", "114.114.114.114", NULL }; if (ct == NULL || !nf_ct_is_confirmed(ct)) { return NF_ACCEPT; } iph = ip_hdr(skb); if (!iph) return NF_ACCEPT; char src_ip[32] = {0}; char dst_ip[32] = {0}; sprintf(src_ip, "%pI4", &iph->saddr); sprintf(dst_ip, "%pI4", &iph->daddr); printk("src_ip = %s, dst_ip = %s\n", src_ip, dst_ip); for (i = 0; black_ip_list[i] != NULL; i++) { if (0 == strcmp(src_ip, black_ip_list[i]) || 0 == strcmp(dst_ip, black_ip_list[i])) { printk("drop ippacket %pI4--->%pI4\n", &iph->saddr, &iph->daddr); return NF_DROP; } } return NF_ACCEPT; }
analysis
The source ip and destination ip of the ip header are extracted from the source code, and the configured filter ip list is queried. If the matching is successful, NF will be returned_ Drop handles packet loss.
Compile run
Refer to the previous section
test result
root@OpenWrt:/fros# root@OpenWrt:/fros# insmod ip_filter.ko root@OpenWrt:/fros# <4>[52786.030458] ip filter...init <4>[52797.584631] src_ip = 192.168.66.167, dst_ip = 8.8.8.8 <4>[52797.589199] drop ippacket 192.168.66.167--->8.8.8.8 <4>[52798.585038] src_ip = 192.168.66.167, dst_ip = 8.8.8.8 <4>[52798.588543] drop ippacket 192.168.66.167--->8.8.8.8 <4>[52799.585729] src_ip = 192.168.66.167, dst_ip = 8.8.8.8 <4>[52799.588981] drop ippacket 192.168.66.167--->8.8.8.8 <4>[52800.586586] src_ip = 192.168.66.167, dst_ip = 8.8.8.8 <4>[52800.590504] drop ippacket 192.168.66.167--->8.8.8.8 <4>[52816.371851] src_ip = 192.168.66.167, dst_ip = 39.156.69.79 <4>[52816.376783] drop ippacket 192.168.66.167--->39.156.69.79 <4>[52817.373089] src_ip = 192.168.66.167, dst_ip = 39.156.69.79 <4>[52817.378449] drop ippacket 192.168.66.167--->39.156.69.79 <4>[52818.373501] src_ip = 192.168.66.167, dst_ip = 39.156.69.79 <4>[52818.379103] drop ippacket 192.168.66.167--->39.156.69.79 <4>[52819.374765] src_ip = 192.168.66.167, dst_ip = 39.156.69.79 <4>[52819.376784] drop ippacket 192.168.66.167--->39.156.69.79 <4>[52820.376567] src_ip = 192.168.66.167, dst_ip = 39.156.69.79 <4>[52820.380384] drop ippacket 192.168.66.167--->39.156.69.79
Introduction to the author
Author of OpenWrt application filtering plug-in (application filtering is used to control app networking, and can filter hundreds of apps such as games, videos and chat)
Engaged in embedded Linux development for nearly 10 years, mainly responsible for the research and development of router Netcom products, proficient in OpenWrt system, including luci, message mechanism, kernel module, etc. Good at modules: router Internet behavior management, intelligent flow control, Internet authentication, firewall, virtual server, multi wan load balancing, etc
Open source work address:
https://github.com/destan19/OpenAppFilter
Source code and documentation
Focus on WeChat official account for more technical documents, firmware, source code, etc.
Wechat code scanning concerns: