写了个Linux包过滤防火墙
花幾天寫(xiě)了個(gè)so easy的Linux包過(guò)濾防火墻,估計(jì)實(shí)際意義不是很大。防火墻包括用戶態(tài)執(zhí)行程序和內(nèi)核模塊,內(nèi)核模塊完全可以用iptable代替。由于在編寫(xiě)的過(guò)程一開(kāi)始寫(xiě)的是內(nèi)核模塊所以就直接用上來(lái)。
代碼結(jié)構(gòu)如下:
.
├── kernelspace
│?? ├── Makefile
│?? ├── Makefile_netlink
│?? ├── modules.order
│?? ├── Module.symvers
│?? ├── netfilter.c
│?? ├── netfilter.h
│?? ├── netfilter.ko
│?? ├── netfilter.mod.c
│?? ├── netfilter.mod.o
│?? ├── netfilter.o
│?? ├── out.temp
│?? └── tags
└── userspace
??? ├── filter
??? ├── filter_1
??? ├── filter.c
??? ├── filter.c~
??? ├── load.sh
??? └── tags
由于在開(kāi)發(fā)的過(guò)程中誤刪了filter源文件。后面再重新寫(xiě)過(guò),過(guò)程也是挺艱辛的。后來(lái)想想自己寫(xiě)過(guò)一個(gè)rm命令吧,把原來(lái)的rm命令替換掉,或者還可以這樣子,自己寫(xiě)一個(gè)命令,姑且叫delete命令吧。delete刪除數(shù)據(jù)可以恢復(fù)的,再或者,用git吧,git管理想誤刪可不是這么容易的。
ok,閑話少扯,上代碼上分析上開(kāi)發(fā)過(guò)程。
先從內(nèi)核模塊看起,也就是文件樹(shù)下的以kernelspace為根的文件。嗯~~文件挺多的,不過(guò)自己寫(xiě)的就三個(gè),Makefile,netfilter.c and netfilter.h
內(nèi)核模塊采用linux的netfilter框架。
通俗的說(shuō),netfilter的架構(gòu)就是在整個(gè)網(wǎng)絡(luò)流程的若干位置放置了一些檢測(cè)點(diǎn)(HOOK),而在每個(gè)檢測(cè)點(diǎn)上登記了一些處理函數(shù)進(jìn)行處理(如包過(guò)濾,NAT等,甚至可以是 用戶自定義的功能)。
IP層的五個(gè)HOOK點(diǎn)如下:
[1]:NF_IP_PRE_ROUTING:剛剛進(jìn)入網(wǎng)絡(luò)層的數(shù)據(jù)包通過(guò)此點(diǎn)(剛剛進(jìn)行完版本號(hào),校驗(yàn)和等檢測(cè)), 目的地址轉(zhuǎn)換在此點(diǎn)進(jìn)行; [2]:NF_IP_LOCAL_IN:經(jīng)路由查找后,送往本機(jī)的通過(guò)此檢查點(diǎn),INPUT包過(guò)濾在此點(diǎn)進(jìn)行; [3]:NF_IP_FORWARD:要轉(zhuǎn)發(fā)的包通過(guò)此檢測(cè)點(diǎn),FORWARD包過(guò)濾在此點(diǎn)進(jìn)行; [4]:NF_IP_POST_ROUTING:所有馬上便要通過(guò)網(wǎng)絡(luò)設(shè)備出去的包通過(guò)此檢測(cè)點(diǎn),內(nèi)置的源地址轉(zhuǎn)換功能(包括地址偽裝)在此點(diǎn)進(jìn)行; [5]:NF_IP_LOCAL_OUT:本機(jī)進(jìn)程發(fā)出的包通過(guò)此檢測(cè)點(diǎn),OUTPUT包過(guò)濾在此點(diǎn)進(jìn)行。(摘自百度百科)
更多關(guān)注點(diǎn)在怎樣使用netfilter上。兩個(gè)函數(shù)
nf_register_hook ========> nf_unregister_hook。顧名思義,注冊(cè)鉤子,釋放鉤子。關(guān)鍵在于參數(shù)結(jié)構(gòu)struct nf_hook_ops *reg的填充。函數(shù)和struct nf_hook_ops結(jié)構(gòu)都可以在netfilter.h頭文件中找到。作者netfilter.h目錄為/usr/src/linux-head***/include/linux下找到。
struct nf_hook_ops {
?? ?struct list_head list;
?? ?/* User fills in from here down. */
?? ?nf_hookfn *hook;
?? ?struct module *owner;
?? ?u_int8_t pf;
?? ?unsigned int hooknum;
?? ?/* Hooks are ordered in ascending priority. */
?? ?int priority;
};
關(guān)注更多的是這些成員的具體意義以及編程時(shí)候如何選擇這些成員。
nf_hookfn *hook 是你自己定義的回調(diào)函數(shù)。當(dāng)有符合條件的數(shù)據(jù)包到來(lái)時(shí)候會(huì)調(diào)用。
hooknum為前面提到的IP層的五個(gè)hook點(diǎn)的取值
prority根據(jù)uapi/linux/netfiler_ipv4.h的定義,可以取以下值
enum nf_ip_hook_priorities {
?? ?NF_IP_PRI_FIRST = INT_MIN,
?? ?NF_IP_PRI_CONNTRACK_DEFRAG = -400,
?? ?NF_IP_PRI_RAW = -300,
?? ?NF_IP_PRI_SELINUX_FIRST = -225,
?? ?NF_IP_PRI_CONNTRACK = -200,
?? ?NF_IP_PRI_MANGLE = -150,
?? ?NF_IP_PRI_NAT_DST = -100,
?? ?NF_IP_PRI_FILTER = 0,
?? ?NF_IP_PRI_SECURITY = 50,
?? ?NF_IP_PRI_NAT_SRC = 100,
?? ?NF_IP_PRI_SELINUX_LAST = 225,
?? ?NF_IP_PRI_CONNTRACK_HELPER = 300,
?? ?NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
?? ?NF_IP_PRI_LAST = INT_MAX,
};
pf根socket編寫(xiě)時(shí)候類似,在此不多寫(xiě)。
現(xiàn)在獻(xiàn)上內(nèi)核模塊的代碼
1 /************************************************************************* 2 > File Name: netfilter.c 3 > Author: ICKelin 4 > Mail: 18277973721@sina.cn 5 > Created Time: 2015年02月27日 星期五 02時(shí)39分09秒 6 ************************************************************************/ 7 8 #include "netfilter.h" 9 10 #define _USER_SPACE_ 11 12 struct nf_hook_ops hook_in; 13 struct nf_hook_ops hook_out; 14 15 static int __init fire_init() 16 { 17 hook_in.hook = fire_hook_entry; 18 hook_in.hooknum = NF_INET_LOCAL_IN; 19 hook_in.pf = PF_INET; 20 hook_in.priority = NF_IP_PRI_FIRST; 21 22 nf_register_hook(&hook_in); 23 return 0; 24 } 25 26 static void __exit fire_exit() 27 { 28 nf_unregister_hook(&hook_in); 29 } 30 31 //有數(shù)據(jù)包到來(lái)調(diào)用 32 33 unsigned int fire_hook_entry( 34 unsigned int hooknum, 35 struct sk_buff *skb, 36 const struct net_device *in, 37 const struct net_device *out, 38 int (*okfn)(struct sk_buff*) 39 ) 40 { 41 42 #ifdef _USER_SPACE_ 43 return NF_QUEUE; 44 #endif 45 46 struct iphdr *ip = ip_hdr(skb); 47 struct tcphdr *tcp = tcp_hdr(skb); 48 struct udphdr *udp = udp_hdr(skb); 49 50 if(ip->protocol == 6) 51 { 52 printk("tcp連接:::: 源ip:%3d.%3d.%3d.%3d 目的ip %3d.%3d.%3d.%3d ", NET_TO_IP((ip->saddr)),NET_TO_IP((ip->daddr))); 53 54 printk("源端口號(hào) %6d 目的端口號(hào) %6d",ntohs(tcp->source), ntohs(tcp->dest)); 55 56 if(ntohs(tcp->dest) == 80) 57 { 58 printk("狀態(tài):隊(duì)列\(zhòng)n"); 59 return NF_QUEUE; 60 } 61 else 62 printk("狀態(tài):允許通過(guò)防火墻"); 63 return NF_ACCEPT; 64 } 65 else if(ip->protocol == 17) 66 { 67 printk("udp連接::: 源ip:%3d.%3d.%3d.%3d 目的ip %3d.%3d.%3d.%3d ", NET_TO_IP(ip->saddr), NET_TO_IP(ip->daddr)); 68 printk("源端口號(hào) %d 目的端口號(hào) %d 狀態(tài):允許通過(guò)防火墻\n", ntohs(udp->source), ntohs(udp->dest)); 69 return NF_ACCEPT; 70 } 71 else if(ip->protocol ==1) 72 { 73 printk("icmp connect come\n"); 74 return NF_QUEUE; 75 } 76 else if(ip->protocol == 2) 77 { 78 printk("igmp conect come\n"); 79 return NF_ACCEPT; 80 } 81 return NF_ACCEPT; 82 83 // printk("packet come\n"); 84 return NF_ACCEPT; 85 } 86 87 module_init(fire_init); 88 module_exit(fire_exit);頭文件netfilter.h包含基本文件linux頭文件。在此也貼上,以便讀者進(jìn)行探索時(shí)候可以找到對(duì)應(yīng)的頭文件。
1 /************************************************************************* 2 > File Name: netfilter.h 3 > Author: ICKelin 4 > Mail: 18277973721@sina.cn 5 > Created Time: 2015年02月27日 星期五 02時(shí)39分24秒 6 ************************************************************************/ 7 8 #include <linux/in.h> 9 #include <linux/ip.h> 10 #include <linux/tcp.h> 11 #include <linux/udp.h> 12 #include <linux/icmp.h> 13 14 #include <linux/kernel.h> 15 #include <linux/module.h> 16 #include <linux/netdevice.h> 17 #include <linux/init.h> 18 #include <linux/skbuff.h> 19 #include <linux/types.h> 20 #include <linux/inet.h> 21 #include <linux/netfilter_ipv4.h> 22 /* 23 * 防火墻初始化函數(shù),供module_exit的參數(shù)使用 24 * 內(nèi)部調(diào)用鉤子注冊(cè)函數(shù)nf_register_hook.填充 25 * struct nf_hook_ops結(jié)構(gòu) 26 * struct nf_hook_ops 27 * { 28 * struct list_head list; 29 * nf_hookfn *hook; 30 * struct module *owner; 31 * u_int8_t pf; 32 * unsigned int hooknum; 33 * int priority; 34 * } 35 * 36 * 詳細(xì)信息參考netfilter.h頭文件 37 * nf_hookfd指定為fire_hook_entry作為回調(diào)函數(shù) 38 * 39 * */ 40 41 static int __init fire_init(); 42 43 /* 44 * 防火墻退出函數(shù),共module_init的參數(shù)使用 45 * 填充struct nf_hook_ops結(jié)構(gòu) 46 * 47 * */ 48 49 static void __exit fire_exit(); 50 51 /* 52 * 防火墻鉤子回調(diào)。供給nf_register_hook函數(shù)的參數(shù) 53 * 54 * struct nf_hook_ops結(jié)構(gòu)的 55 * hook成員使用,用與注冊(cè)回調(diào)函數(shù) 56 * 57 * */ 58 59 unsigned int fire_hook_entry 60 ( 61 unsigned int hooknum, 62 struct sk_buff *skb, 63 const struct net_device *in, 64 const struct net_device *out, 65 int (*okfn)(struct sk_buff*) 66 ); 67 /* 68 * 69 * 70 * */ 71 72 #define NET_TO_IP(addr) \ 73 ((unsigned char*)&addr)[0],\ 74 ((unsigned char*)&addr)[1],\ 75 ((unsigned char*)&addr)[2],\ 76 ((unsigned char*)&addr)[3]?
內(nèi)核模塊需要make
Makefile
obj-m := netfilter.o KERNELBUILD :=/lib/modules/$(shell uname -r)/build default: make -C $(KERNELBUILD) M=$(shell pwd) modules clean: rm -rf *.o *.ko *.mod.c .*.cmd *.markers *.order *.symvers .tmp_versions?
內(nèi)核模塊其實(shí)還是挺簡(jiǎn)單的。如果編寫(xiě)用戶層的包過(guò)濾防火墻的話沒(méi)有必要在內(nèi)核模塊上花費(fèi)太多功夫,以上內(nèi)核模塊實(shí)現(xiàn)的功能用iptable都可以實(shí)現(xiàn)。
至于協(xié)議解析部分,也不是三言兩語(yǔ)能寫(xiě)的完。但是作者寫(xiě)過(guò)利用原始套接字進(jìn)行抓包的程序,不過(guò)正在準(zhǔn)備筆試就沒(méi)有多大時(shí)間寫(xiě)博客總結(jié)。讀者能看懂包解析部分的代碼的是沒(méi)什么問(wèn)題的。
用戶空間模塊。用戶空間模塊采用的是netfilter_queue函數(shù)庫(kù)。原本找資料的時(shí)候看到ipq這個(gè)庫(kù),不過(guò)后來(lái)到netfilter官網(wǎng)上找資料,ipq函數(shù)庫(kù)被取代來(lái)。
libnetfilter_queue is a userspace library providing an API to packets that have been queued by the kernel packet filter. It is is part of a system that deprecates the old ip_queue / libipq mechanism.
libnetfilter_queue has been previously known as libnfnetlink_queue.
用戶空間動(dòng)起來(lái)也不難。關(guān)鍵是官網(wǎng)有api參考。看著官網(wǎng)的api再結(jié)合之前抓包的程序?qū)懫饋?lái)就easy了。
這部分誤刪過(guò)一次,我那個(gè)淚奔啊,rm命令害死人,原本注釋打得完美了,重寫(xiě)一次就沒(méi)有打注釋的欲望了。忘見(jiàn)諒。
/*************************************************************************??? > File Name: filter.c
??? > Author: ICKelin
??? > Mail: 18277973721@sina.cn
??? > Created Time: 2015年03月02日 星期一 01時(shí)04分38秒
?************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <asm/byteorder.h>
#include <linux/netfilter.h>
#include <libnetfilter_queue/libnetfilter_queue.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#define BUFF_SIZE?? ?1024*10
#define IP_SIZE?? ??? ?50
#define AUTHOR "ICKelin"
#define VERSION "v1.1"
#define _DEBUG_
#define error(msg) \
?? ?{fprintf(stderr, "%s error with %s\n", msg, strerror(errno));exit(-1);}
struct filter_info
{
?? ?long from_ip;
?? ?long to_ip;
?? ?char *protocol_type;
}filter;
int parse_cmd(char *protocol_type, char *from, char *to);
void fire_help();
void fire_version();
int get_port_by_service(char *service);
static int cb(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,struct nfq_data *nfa, void *data)
{
?? ?int is_block = 0;
?? ?struct nfqnl_msg_packet_hdr *msg = nfq_get_msg_packet_hdr(nfa);
?? ?if(msg == NULL)
?? ??? ?error("nfqnl_msg_packet_hdr");
?? ?char *pdata;
?? ?
?? ?int n = nfq_get_payload(nfa, (char**)&pdata);
?? ?struct iphdr *ip = (struct iphdr*)pdata;
?? ?struct tcphdr *tcp;
?? ?int block_port = get_port_by_service(filter.protocol_type);
?? ?struct in_addr add;
?? ?
?? ?add.s_addr = ip->saddr;
?? ?printf("%s\t", inet_ntoa(add));
?? ?add.s_addr = ip->daddr;
?? ?printf("%s\t", inet_ntoa(add));
?? ?switch(ip->protocol)
?? ?{
?? ??? ?//udp
?? ??? ?case 17:
?? ??? ??? ?printf("UDP\t");
?? ??? ??? ?struct udphdr *udp = (struct udphdr*)(pdata + sizeof(struct iphdr));
?? ??? ??? ?printf("%d\t%d\t", ntohs(udp->source), ntohs(udp->dest));
?? ??? ??? ?printf("通過(guò)\n");
?? ??? ??? ?break;
?? ??? ?case 6:
?? ??? ??? ?printf("TCP\t");
?? ??? ??? ?tcp = (struct tcphdr *)(pdata + sizeof(struct iphdr));
?? ??? ??? ?printf("%d\t%d\t", ntohs(tcp->source), ntohs(tcp->dest), block_port);
?? ??? ??? ?if( (ntohs(tcp->source) == block_port||ntohs(tcp->dest) == block_port) && ntohl(ip->saddr) >=filter.from_ip && ntohl(ip->saddr)<=filter.to_ip)
?? ??? ??? ?{
?? ??? ??? ??? ?//char out[1024];
?? ??? ??? ??? ?//strcpy(out,(char*)tcp + tcp->doff*4);
?? ??? ??? ??? ?//out[strlen(out)-3] = '3';
?? ??? ??? ??? ?//memcpy((char*)(tcp + tcp->doff*4), out, sizeof(out));
?? ??? ??? ??? ?//printf("%s\n", (char*)tcp + tcp->doff*4);
?? ??? ??? ??? ?printf("攔截\n");
?? ??? ??? ??? ?return nfq_set_verdict(qh,ntohl(msg->packet_id), NF_DROP,n,pdata);
?? ??? ??? ?}
?? ??? ??? ?else
?? ??? ??? ??? ?printf("通過(guò)\n");
?? ??? ??? ?break;
?? ??? ?case 1:
?? ??? ??? ?printf("ICMP\t");
?? ??? ??? ?printf("無(wú)\t無(wú)\t");
?? ??? ??? ?printf("通過(guò)\n");
?? ??? ??? ?break;
?? ??? ?default:
?? ??? ??? ?printf("un\t");
?? ??? ??? ?printf("通過(guò)\n");
?? ??? ??? ?break;
?? ?}
?? ?return nfq_set_verdict(qh,ntohl(msg->packet_id), NF_ACCEPT,n,pdata); ?
}
int main(int argc, char **argv)
{
?? ?char *protocol_type,*from, *to;
?? ?char opt;
?? ?int flag = 0;
?? ?while((opt = getopt(argc, argv, "hvf:t:p:")) != EOF)
?? ?{
?? ??? ?switch(opt)
?? ??? ?{
?? ??? ??? ?case 'h':
?? ??? ??? ??? ?fire_help();
?? ??? ??? ??? ?return 0;
?? ??? ??? ?case 'v':
?? ??? ??? ??? ?fire_version();
?? ??? ??? ??? ?return 0;
?? ??? ??? ?case 'f':
?? ??? ??? ??? ?from = optarg;
?? ??? ??? ??? ?flag=flag|1;
?? ??? ??? ??? ?break;
?? ??? ??? ?case 't':
?? ??? ??? ??? ?to = optarg;
?? ??? ??? ??? ?flag|=2;
?? ??? ??? ??? ?break;
?? ??? ??? ?case 'p':
?? ??? ??? ??? ?protocol_type = optarg;
?? ??? ??? ??? ?flag|=4;
?? ??? ??? ??? ?break;
?? ??? ??? ?default:
?? ??? ??? ??? ?fire_help();
?? ??? ??? ??? ?break;
?? ??? ?}
?? ?}
?? ?if((flag^7) != 0)
?? ?{
?? ??? ?fprintf(stderr, "command line options error\nyou should use \n\t-f begin ip you are going to block\n-t end ip you are going to block\n\t-p for the protocol or port you are going to block\n");
?? ??? ?fprintf(stderr,"\tfor example:filter -f 192.168.15.* -t 192.16.120.* -p http\n");
?? ??? ?fprintf(stderr,"more information use -h\n");
?? ??? ?exit(-1);
?? ?}
?? ?
?? ?parse_cmd(protocol_type, from, to);
?? ?printf("\nfirewall setup successfully\n\n");
?? ?printf("? you filter information:\n");
?? ?printf("\tfrom:%s???? net byte order %ld\n", from, filter.from_ip);
?? ?printf("\tto? :%s???? net byte order %ld\n", to, filter.to_ip);
?? ?printf("\tprotocol:%s\n\n", filter.protocol_type);
?? ?printf("now let's firework for firewall\n\n");
?? ?printf("源ip\t\t目的ip\t\t協(xié)議\t源端口 目的端口 狀態(tài)\n");
?? ?struct nfq_handle *h;
?? ?struct nfq_q_handle *qh;
?? ?int fd;
?? ?int rv;
?? ?char buf[4096];
?? ?h = nfq_open();
?? ?if (!h)
?? ??? ?error("nfq_open");
?? ?nfq_unbind_pf(h, AF_INET);
?? ?if (nfq_bind_pf(h, AF_INET) < 0)
?? ??? ?error("nfq_bind_pf");
?? ?qh = nfq_create_queue(h, 0, &cb, NULL);
?? ?if (!qh)
?? ??? ?error("nfq_create_queue");
?? ?if (nfq_set_mode(qh, NFQNL_COPY_PACKET, 0xffff) < 0)
?? ??? ?error("nfq_set_mode");
?? ?fd = nfq_fd(h);
?? ?while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0)
?? ??? ?nfq_handle_packet(h, buf, rv);
?? ?nfq_destroy_queue(qh);
?? ?nfq_close(h);
?? ?return 0;
}
void fire_help()
{
?? ?printf("welcome to use my network filter firework\n");
?? ?printf("how to set your own match to filter packets:\n\n");
?? ?printf("\t-p\tfilter protocol,like http,ftp...maybe you want to use port instead\n");
?? ?printf("\t-f\tfilter ip from argument\n");
?? ?printf("\t-h\tshow help information\n");
?? ?printf("\t-v\tshow sortware information and the author information\n\n");
?? ?printf("? author:%s\n", AUTHOR);
?? ?printf("? come form:CHINA\n");
?? ?printf("? email:18277973721@sina.cn\n");
?? ?printf("? version:%s\n\n",VERSION);
}
void fire_version()
{
}
int parse_cmd(char *protocol_type, char *from, char *to)
{
?? ?char temp[IP_SIZE];
?? ?int index;
?? ?
?? ?if(strcasecmp(protocol_type, "http") == 0)
?? ??? ?filter.protocol_type = "http";
?? ?else if(strcasecmp(protocol_type, "ftp") == 0)
?? ??? ?filter.protocol_type = "ftp";
?? ?else if(strcasecmp(protocol_type, "smtp") == 0)
?? ??? ?filter.protocol_type = "smtp";
?? ?else
?? ?{
?? ??? ?fprintf(stderr, "not support protocol.\nversion %s only support http,ftp or smtp protocol\nmore information see -h option\n", VERSION);
?? ??? ?exit(-1);
?? ?}
?? ?while(*from)
?? ?{
?? ??? ?if(*from != '.' && *from !='*' &&(*from<'0'||*from>'9'))
?? ??? ?{
?? ??? ??? ?fprintf(stderr, "from ip address format error! format:###.###.##.#\nexample:192.168.*.*\nmore information use -h option\n");
?? ??? ??? ?exit(-1);
?? ??? ?}
?? ??? ?if(*from == '*')
?? ??? ??? ?temp[index++] = '0';
?? ??? ?else
?? ??? ??? ?temp[index++] = *from;
?? ??? ?from++;
?? ?}
?? ?temp[index] = 0;
?? ?filter.from_ip = ntohl(inet_addr(temp));
?? ?
?? ?memset(temp, 0, sizeof(temp));
?? ?index = 0;
?? ?while(*to)
?? ?{
?? ??? ?if(*to != '.' && *to !='*' &&(*to<'0'||*to>'9'))
?? ??? ?{
?? ??? ??? ?fprintf(stderr, "to ip address format error! format:###.###.##.#\nexample:192.168.*.*\nmore information use -h option");
?? ??? ??? ?exit(-1);
?? ??? ?}
?? ??? ?if(*to == '*')
?? ??? ??? ?temp[index++] = '0';
?? ??? ?else
?? ??? ??? ?temp[index++] = *to;
?? ??? ?to++;
?? ?}
?? ?temp[index] = 0;
?? ?filter.to_ip = ntohl(inet_addr(temp));
?? ?if(filter.from_ip > filter.to_ip)
?? ?{
?? ??? ?fprintf(stderr, "hello guys, there is no ip between %s to %s\ni advice you to check your input\nmore information see -h option", from, to);
?? ??? ?exit(-1);
?? ?}
?? ?return 1;
}
int get_port_by_service(char *service)
{
?? ?if(strcasecmp(service, "HTTP") == 0)
?? ??? ?return 80;
?? ?if(strcasecmp(service, "FTP") == 0)
?? ??? ?return 21;
?? ?if(strcasecmp(service, "smtp") == 0)
?? ??? ?return 25;
?? ?return 0;
}
關(guān)于命令行選項(xiàng)和ip地址驗(yàn)證這塊不多說(shuō)。netfilter_queue庫(kù)的使用參考鏈接:libnetfilter_quue,讀者參考頭文件和官方文檔探索相信能夠很快就能編寫(xiě)自己的包過(guò)濾防火墻來(lái)。
至于其他功能,讀者可以發(fā)揮自己的想象力去搞。只要不違反法律,盡情的去玩吧。
?
轉(zhuǎn)載于:https://www.cnblogs.com/ickelin/p/4340566.html
總結(jié)
以上是生活随笔為你收集整理的写了个Linux包过滤防火墙的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: WIN7安装及配置JDK
- 下一篇: Entity Framework 实体框