利用netfilter构建用户态防火墙-23页文档资料
- 格式:ppt
- 大小:1.15 MB
- 文档页数:23


Linux⽹络-基于Netfilter的防⽕墙⼀个简单的基于netfilter丢弃所有包的模块//'Hello World' kernel module, logs call to init_module// and cleanup_module to /var/log/messages// In Ubuntu 8.04 we use make and appropriate Makefile to compile kernel module#define __KERNEL__#define MODULE#include <linux/module.h>#include <linux/kernel.h>#include <linux/init.h>#include <linux/netfilter.h>#include <linux/netfilter_ipv4.h>static struct nf_hook_ops nfho; // 定义nf_hook_ops数据结构//function to be called by hookunsigned int hook_func(unsigned int hooknum,struct sk_buff **skb,const struct net_device *in,const struct net_device *out,int (*okfn)(struct sk_buff *)){printk(KERN_INFO "packet dropped\n"); //log to var/log/messagesreturn NF_DROP; //drops the packet}int init_module(void){nfho.hook = hook_func; // 定义数据结构nfho.hooknum = NF_INET_PRE_ROUTING; //called right after packet recieved, first hook in Netfilternfho.pf = PF_INET; //IPV4 packetsnfho.priority = NF_IP_PRI_FIRST; //set to highest priority over all other hook functionsnf_register_hook(&nfho); //register hookreturn0;}// 注销模块void cleanup_module(void){nf_unregister_hook(&nfho);}Makefileobj-m := hello.oKDIR := /usr/src/linux-headers-4.4.0-62-genericPWD := $(shell pwd)default:$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modulesclean:$(MAKE) -C $(KDIR) M=$(PWD) clean使⽤glibc来编写命令简单的命令⾏⼯具:参考资料:理解getopt()函数#include <stdlib.h>#include <getopt.h>#define print_value(x) (x==NULL?"-" : x)static struct mf_rule_struct {int in_out;char *src_ip;char *src_netmask;char *src_port; //default to -1char *dest_ip;char *dest_netmask;char *dest_port;char *proto;char *action;} mf_rule;static struct mf_delete_struct {char *cmd;char *row;} mf_delete;void send_rule_to_proc(){printf("TODO: send_rule_to_procn");}void send_delete_to_proc(){printf("TODO: send_delete_to_procn");}void print_rule(){printf("TODO: print_rule\n");return;}int main(int argc, char *argv[]){int c;int action = 1; //1: new rule; 2: print; 3: deletemf_rule.in_out = -1;mf_rule.src_ip = NULL;mf_rule.src_netmask = NULL;mf_rule.src_port = NULL;mf_rule.dest_ip = NULL;mf_rule.dest_netmask = NULL;mf_rule.dest_port = NULL;mf_rule.proto = NULL;mf_rule.action = NULL;while (1){static struct option long_options[] ={/*set a flag*/{"in", no_argument, &mf_rule.in_out, 1},{"out", no_argument, &mf_rule.in_out, 0},/*These options don't set a flag.We distinguish them by their indices.*/{"print", no_argument, 0, 'o'},{"delete", required_argument, 0, 'd'},{"srcip", required_argument, 0, 's'},{"srcnetmask", required_argument, 0, 'm'},{"srcport", required_argument, 0, 'p'},{"destip", required_argument, 0, 't'},{"destnetmask", required_argument, 0, 'n'},{"destport", required_argument, 0, 'q'},{"proto", required_argument, 0, 'c'},{"action", required_argument, 0, 'a'},{0, 0, 0, 0}};int option_index = 0;c = getopt_long(argc, argv, "od:s:m:p:t:n:q:c:a:", long_options, &option_index);/*Detect the end of the options. */action = 1;switch (c){case0:printf("flag option: %s, mf_rule.in_out = %dn", long_options[option_index].name, mf_rule.in_out);break;case'o':action = 2; //printbreak;case'd':action = 3; //deletemf_delete.cmd = (char *)long_options[option_index].name;mf_delete.row = optarg;break;case's':mf_rule.src_ip = optarg; //src ipbreak;case'm':mf_rule.src_netmask = optarg; //srcnetmask:break;case'p':mf_rule.src_port = optarg; //srcport:break;case't':mf_rule.dest_ip = optarg; //destip:break;case'n':mf_rule.dest_netmask = optarg; //destnetmaskbreak;case'q':mf_rule.dest_port = optarg; //destportbreak;case'c':mf_rule.proto = optarg; //protobreak;case'a':mf_rule.action = optarg;//actionbreak;case'?':/* getopt_long printed an error message. */break;default:abort();}if (c != 0)printf("%s = %sn", long_options[option_index].name, optarg);}if (action == 1) {send_rule_to_proc();} else if (action == 2) {print_rule();} else if (action == 3) {send_delete_to_proc();}if (optind < argc){printf("non-option ARGV-elements: ");while (optind < argc)printf("%s ", argv[optind++]);putchar('\n');}}命令⾏⼯具程序解析:编译程序 gcc cmd.c -o cmd运⾏程序:./cmd --in --srcip 192.168.0.10 --srcnetmask 255.255.255.0 --srcport 1000 --destip 114.114.114.114 --destnetmask 255.255.255.0 --destport 53 --proto 6 --action 0输出结果:➜ test_cmd ./cmd --in --srcip 192.168.0.10 --srcnetmask 255.255.255.0 --srcport 1000 --destip 114.114.114.114 --destnetmask255.255.255.0 --destport 53 --proto 6 --action 0flag option: in, mf_rule.in_out = 1srcip = 192.168.0.10srcnetmask = 255.255.255.0srcport = 1000destip = 114.114.114.114destnetmask = 255.255.255.0destport = 53proto = 6action = 0TODO: send_rule_to_proc运⾏程序./cmd --delete 1➜ test_cmd ./cmd --delete 2delete = 2TODO: send_delete_to_proc。
防火墙软件Netfilter之NAT技术ZDNet 网络频道频道更新时间:2008-06-10 作者:来源:路由器技术资讯网本文关键词:NAT网络地址转换什么是nat本文档主要描述怎样进行IP伪装(masquerading)、透明代理(transparent proxying)、端口转发(port forwarding)和其他形式的网络地址翻译技术。
1.什么是网络地址翻译NAT(Network Address Translation)?当一个包在网络上传输时,从它的源地址(例如你自己的主机)到达目的地址(例如),中间经过很多节点和网络。
这些节点通常不会改变你的包。
他们仅仅转发你的包。
如果一个节点执行NAT,他将会修改包的源或目的地址。
通常这个节点会记住他怎样修改了这个包,因此当相应的应答包从另一个方向到达时,他知道如何反向修改这个应答包。
2.为什么要使用NAT?l 用modem上网大多数的ISPs只给你提供一个IP地址。
你可以以任何源地址发出包,但是只有包含这个IP地址的包的应答包才会到达你的网络。
如果你想使用多台机器(比如有个自己的网络)利用这个IP地址上网。
需要NAT。
这是NAT使用得最为常见的情况,在linux的世界里称为IP伪装(masquerading)。
又称之为SNAT,因为你要改变包的源地址。
l Multiple Servers有时候你想改变到达你的网络的包的去向。
通常因为你只有一个IP地址,但是你又想用户到达这个真实IP地址之后的各个机器。
方法是修改这些包的目的地址,让他们到达不同的机器。
还有就是用于负载均衡。
这种类型的NAT在linux上叫做端口转发(port-forwarding)。
l Transparent Proxying(透明代理)透明代理是在你的网络和外部世界之间的程序,所有的进或出都要经过这个代理。
之所以叫做“透明”,因为你的网络无需考虑他的存在。
例如,squid软件能够配置为透明代理。