第11单元 防火墙

11.1 知识讲解

11.1.1 什么是防火墙

1. 防火墙的基本概念

1) 防火墙的作用

防火墙提供了网络对网络或网络对主机的访问控制,通过地址隐藏等技术手段,保护网络资源免受非法侵害,是目前较为常见的网络安全设备之一。

2) 防火墙的实现

防火墙的实现方式不一而足,但通常都是由一组硬件设备(路由器和计算机)和特定的软件组合而成。除一般的通用型防火墙以外,还有一些专用的防火墙,只为特定类型的网络服务,如HTTP、SMTP等,提供保护。

3) 防火墙的位置

防火墙在网络中的位置如下图所示:

+---------+     +---------+
|         |     |         |
| Server  | ... | Server  |
|         |     |         |
+----+----+     +----+----+
     |               |
-----+---------------+---------------+------
                                     |
                               +-----+-----+
                               |           |
                               | Firewall  |
                               |           |
                               +-----+-----+
                                     |
                               ------+---------------+---------------+-----
                                                     |               |
                                                +----+----+     +----+----+
                                                |         |     |         |
                                                | Client  | ... | Client  |
                                                |         |     |         |
                                                +---------+     +---------+

客户端访问服务器,但并不直接和服务器通信,而是先将服务请求发送给服务器侧的防火墙。经防火墙检测被认为是安全的数据包才会转发给相应的服务器,否则直接过滤掉。

4) 防火墙的类型
A. 包过滤型防火墙

包过滤型防火墙工作于网络层(IP协议层),也被称为网络层防火墙。这种防火墙在网络层对数据包进行监控和分析,按照事先设定好的过滤规则,检查流经防火墙的每个数据包的源地址、目的地址、源端口、目的端口、协议状态等字段,并据此决定哪些数据包获准通过,哪些又应被拦截。这种防火墙的核心是过滤规则的制定。

B. 应用网关型防火墙

应用网关型防火墙基于网络代理技术构建,也被称为代理型防火墙。这种防火墙工作于网络协议栈的应用层,接收来自外部的各种服务请求,经安全检查后,转发给内部相应的网络服务。同样,从内部网络发往外部网络的数据包也会受到监控,并被处理为如同从防火墙外部发出的一样,从而达到隐藏内部网络的目的。这种防火墙对网络性能会有一定影响,且必须为每种网络服务提供专门的代理模块,实现难度较大。

2. Linux防火墙

Linux防火墙从最初设计到现在相对成熟的体系经历了若干代的更迭:

11.1.2 Netfilter

1. Netfilter在内核中的位置

Linux系统内核通过Netfilter在网络层(IP协议层)的内部实现防火墙功能。Netfilter为每种网络层协议,如IPv4、IPv6、IPX等,各定义了一套钩子函数。这些钩子函数在数据包流经协议栈的几个特定位置时被调用,并对数据包执行相应的处理,如修改、丢弃或交给用户进程等。如下图所示:

graph TB application(Application) ethernet(Ethernet) subgraph Network Protocol Stack subgraph L5: Application Layer socket(BSD Socket) end subgraph L4: Transport tcp_udp(TCP/UDP) end subgraph L3: Network Layer ip(IPv4/IPv6/IPX) subgraph Firewall netfilter(Netfilter) hook_1(Hook Function) hook_2(Hook Function) netfilter---hook_1 netfilter---hook_2 end ip---netfilter end subgraph L2: Data Link Layer neighbour_subsystem(Neighbour Subsystem) end subgraph L1: Physical Layer network_device(Network Device) end socket---tcp_udp tcp_udp---ip ip---neighbour_subsystem neighbour_subsystem---network_device end application---socket network_device---ethernet

2. Netfilter挂接点

Netfilter在网络层(IP协议层)的五个位置上设置挂接点,如下图所示:

graph TB in((In)) in_routing{Routing} local_processing(Local Processing) out_routing{Routing} out((Out)) in--NF_IP_PRE_ROUTING-->in_routing in_routing--NF_IP_LOCAL_IN-->local_processing local_processing--NF_IP_LOCAL_OUT-->out_routing out_routing--NF_IP_POST_ROUTING-->out in_routing--NF_IP_FORWARD-->out_routing

每个挂接点都有其特定的位置和意义,如下表所示:

挂接点 位置
NF_IP_PRE_ROUTING 数据包刚刚收到
NF_IP_FORWARD 数据包正从一块网卡转向另一块网卡
NF_IP_LOCAL_IN 数据包即将进入上层协议栈
NF_IP_LOCAL_OUT 数据包刚刚离开上层协议栈
NF_IP_POST_ROUTING 数据包即将发出

3. Netfilter钩子函数

Netfilter为每种网络层协议都定义了一套钩子函数。这些钩子函数的入口地址保存在一个二维数组中。每个希望嵌入Netfilter的模块都可以在协议栈的挂接点上注册钩子函数,这些钩子函数构成一条函数指针链。

数据包在协议栈中流到某个挂接点时,Netfilter就会调用事先注册的钩子函数,对数据包进行捕获和分析,并根据钩子函数返回的结果,决定下一步如何处理:

钩子函数的返回值如下表所示:

返回值 含义
NF_ACCEPT 允许通过,将数据包原封不动地放回协议栈,继续下一步处理
NF_DROP 禁止通过,将数据包直接丢弃,不再继续处理
NF_STOLEN 由钩子函数自己处理数据包,不再继续传送
NF_QUEUE 将数据包加入队列,交由用户程序处理
NF_REPEAT 再次调用该钩子函数

11.1.3 IPTables

构成Netfilter体系结构除了钩子函数以外还包括IPTables,即规则表,钩子函数通过访问表中定义的规则来决定应该向Netfilter返回什么值。系统管理员可以通过iptables命令管理和维护这些规则表。

1. 内置规则表

Linux系统内核默认内置三张规则表:

1) 报文处理(Packet Mangling)规则表

通过全部五个挂接点接入Netfilter框架,实现对报文的修改或附加带外数据。

2) 网络地址转换(NAT)规则表

通过NF_IP_PRE_ROUTING、NF_IP_POST_ROUTING、NF_IP_LOCAL_IN和NF_IP_LOCAL_OUT四个挂接点接入Netfilter框架,分别对转发报文源、目的地址和本机报文源、目的地址进行转换。

3) 报文过滤(Packet Filtering)规则表

通过NF_IP_LOCAL_IN、NF_IP_LOCAL_OUT和NF_IP_FORWARD三个挂接点接入Netfilter框架,分别对接收、发送和转发报文进行过滤。

数据包在网络层(IP协议层)内部的流动路径如下如所示:

graph TB in((In)) subgraph NF_IP_PRE_ROUTING packet_mangling_1(Packet Mangling) nat_1(NAT) packet_mangling_1-->nat_1 end in_routing{Routing} subgraph NF_IP_LOCAL_IN packet_mangling_2(Packet Mangling) nat_2(NAT) packet_filtering_1(Packet Filtering) packet_mangling_2-->nat_2 nat_2-->packet_filtering_1 end local_processing(Local Processing) subgraph NF_IP_LOCAL_OUT packet_mangling_3(Packet Mangling) nat_3(NAT) packet_filtering_2(Packet Filtering) packet_mangling_3-->nat_3 nat_3-->packet_filtering_2 end out_routing{Routing} subgraph NF_IP_POST_ROUTING packet_mangling_4(Packet Mangling) nat_4(NAT) packet_mangling_4-->nat_4 end subgraph NF_IP_FORWARD packet_mangling_5(Packet Mangling) packet_filtering_3(Packet Filtering) packet_mangling_5-->packet_filtering_3 end out((Out)) in-->packet_mangling_1 nat_1-->in_routing in_routing-->packet_mangling_2 packet_filtering_1-->local_processing local_processing-->packet_mangling_3 packet_filtering_2-->out_routing out_routing-->packet_mangling_4 nat_4-->out in_routing-->packet_mangling_5 packet_filtering_3-->out_routing

2. 自定义规则表

内核编程人员还可以注入模块的方式,通过Netfilter接口创建自定义的规则表。表结构如下所示:

struct ipt_table {
    struct list_head        list;                       // 表头
    char                    name[IPT_TABLE_MAXNAMELEN]; // 表名
    struct ipt_replace    * table;                      // 模板
    unsigned int            valid_hooks;                // 钩子标志位
    rwlock_t                lock;                       // 读写锁
    struct ipt_table_info * private;                    // 规则链集
    struct module         * me;                         // 模块
};

其中用于描述规则链集的private字段采用ipt_table_info结构体类型:

struct ipt_table_info {
    unsigned int size;                       // 字节数
    unsigned int number;                     // 规则数
    unsigned int initial_entries;            // 初始规则数
    unsigned int hook_entry[NF_IP_NUMHOOKS]; // 规则链起始偏移
    unsigned int underflow[NF_IP_NUMHOOKS];  // 规则链终止偏移
    char         entries[0];                 // 规则链集起始位置
};

钩子函数、规则表、规则链和规则链集的关系,以报文过滤规则表为例,如下图所示:

graph TB subgraph ipt_table list(list: Hook Functions) name(name: Packet Filtering) hooks(valid_hooks: NF_IP_LOCAL_IN/NF_IP_LOCAL_OUT/NF_IP_FORWARD) private(private) subgraph ipt_table_info entries(entries) rule1((Rule 1)) rule2((Rule 2)) rule3((Rule 3)) rule4((Rule 4)) rule5((Rule 5)) rule6((Rule 6)) rule7((Rule 7)) rule8((Rule 8)) rule9((Rule 9)) entries--NF_IP_LOCAL_IN---rule1 entries--NF_IP_LOCAL_OUT---rule4 entries--NF_IP_FORWARD---rule7 rule1---rule2 rule2---rule3 rule4---rule5 rule5---rule6 rule7---rule8 rule8---rule9 end list---name name---hooks hooks---private private-->entries end

数据包每流到一个挂接点(NF_IP_LOCAL_IN、NF_IP_LOCAL_OUT和NF_IP_FORWARD),即执行相应的钩子函数(Hook Functions),依据特定的规则链(Rule-Rule-Rule),依次检查每条规则(Rule)的匹配条件是否满足,若满足则执行相应的操作。

3. 规则

IPTables中的每一张表(ipt_table)中均包含0到N条规则链,每条规则链由若干条规则组成,每条规则包括两个部分:

对于每条规则,系统内核还要维护两个计数器:

描述每一条规则的数据结构如下所示:

struct ipt_entry {
    struct ipt_ip       ip;            // 匹配IP头部
    unsigned int        nfcache;       // 字段标志位
    u_int16_t           target_offset; // 规则目标偏移
    u_int16_t           next_offset;   // 规则链中下一条规则的相对偏移
    unsigned int        comefrom;      // 钩子标志位
    struct ipt_counters counters;      // 报文计数器和字节计数器
    unsigned char       elems[0];      // 匹配条件和规则目标
};

规则链中的每条规则如下图所示:

graph LR subgraph Rule 1 match1((Match)) match2((Match)) match3((Match)) target1{Target} packet_counter(Packet Counter) byte_counter(Byte Counter) match1---match2 match2---match3 match3---target1 packet_counter---byte_counter end
graph LR subgraph Rule 2 match4((Match)) match5((Match)) packet_counter(Packet Counter) byte_counter(Byte Counter) match4---match5 packet_counter---byte_counter end
graph LR subgraph Rule 3 target2{Target} packet_counter(Packet Counter) byte_counter(Byte Counter) packet_counter---byte_counter end

4. 匹配条件

iptables命令用于设置多种匹配条件,但某些条件需要依赖特定的内核模块。

如果不载入任何扩充内核模块,iptables命令只能默认设置针对IP包头的匹配条件,如源IP地址、目的IP地址、传输层协议等。

如果希望将除IP包头以外的其它协议(如TCP、UDP、ICMP等)包头中的字段作为匹配条件,则需要通过iptables命令的-m选项载入特定的内核模块。

5. 规则目标

规则目标决定了如何处置满足匹配条件的数据包。默认的四种规则目标如下表所示:

规则目标 处置方式
ACCEPT 接受数据包,不再继续检查规则链中后续规则的匹配条件
DROP 丢弃数据包,不再继续检查规则链中后续规则的匹配条件
QUEUE 将数据包加入队列,交由用户程序处理
RETURN 返回主规则链继续检查规则匹配条件

如果希望加入默认目标以外的其它目标,需要载入支持该目标的扩充内核模块。

11.1.4 Netfilter内核扩展

1. 可加载内核模块(Loadable Kernel Module, LKM)

操作系统的内核分为微内核和大内核两种体系结构:

为了弥补大内核系统扩展性差这一缺陷,Linux操作系统提供了可加载内核模块机制,使用户在无需重新编译整个系统内核,甚至无需重新启动操作系统的前提下,动态加载和卸载实现特定功能的内核模块,使大内核系统同样具备动态扩展的能力。

可加载内核模块是具有独立功能的程序,可被独立编译,但不能独立运行。可加载内核模块必须被动态链接,即加载到系统内核中,作为系统内核的一部分,在内核空间运行。这是其与大多数用户空间程序最显著的区别。

编写可加载内核模块必须提供以下两个函数:

int init_module(void);
void cleanup_module(void);

这两个函数在加载和卸载模块的过程中被调用,分别用于初始化和善后处理。init_module函数返回0表示模块加载成功,否则加载失败。

可加载内核模块编译输出为.ko文件,通过insmod命令可将其加载到系统内核中,如:

$ insmod filter.ko

执行lsmod命令可以列出所有可加载内核模块的名字,如:

$ lsmod

Module                      Size      Used by
vmw_vsock_vmci_transport    32768     2
vsock                       32768     3 vmw_vsock_vmci_transport
snd_ens1371                 24576     2
snd_ac97_codec              106496    1 snd_ens1371
gameport                    16384     1 snd_ens1371
ac97_bus                    16384     1 snd_ac97_codec
snd_pcm                     86016     2 snd_ac97_codec,snd_ens1371
crc32_pclmul                16384     0
...

执行rmmod命令可以卸载指定的可加载内核模块,如:

$ rmmod filter.ko

2. Netfilter内核模块

Netfilter为每种网络协议定义了一套钩子函数,这些钩子函数在数据包流经网络协议栈的特定挂接点时被调用。Linux网络协议栈通过一个全局二维数组保存这些钩子函数的指针:

struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];

其中,第一维表示协议族,第二维表示钩子类型,即挂接点。注册钩子的过程,就是根据给定的协议族和钩子类型,将钩子函数指针添加到nf_hooks数组的适当位置处。

钩子注册结构:

struct nf_hook_ops {
    nf_hookfn         * hook;     // 钩子函数指针
    struct net_device * dev;
    void              * priv;
    u_int8_t            pf;       // 协议族
    unsigned int        hooknum;  // 钩子类型
    int                 priority; // 优先级
};

注册/注销钩子函数:

int nf_register_net_hook(struct net* net, const struct nf_hook_ops* ops);
void nf_unregister_net_hook(struct net* net, const struct nf_hook_ops* ops);

钩子函数原型:

typedef unsigned int nf_hookfn(void* priv, struct sk_buff* skb,
    const struct nf_hook_state* state);

从套接字缓存skb中可以获取各种网络协议的包头字段,可以之参与规则匹配。

11.2 实训案例

11.2.1 基于Netfilter的防火墙内核扩展

应用有关Netfilter和内核模块的知识,通过三个程序实践对内核模块的扩展编程。

第一个程序实现基于协议的数据包过滤功能。

第二个程序实现基于源IP地址的数据包过滤功能。

第三个程序实现基于目的端口号的数据包过滤功能。

三个程序的主体架构基本一样,区别在于钩子函数的实现不同,程序通过钩子函数对数据包实施不同的操作,从而实现不同的过滤策略。

11.2.2 程序清单

1. 协议过滤模块

// protfilter.c
// 协议过滤模块

#include <linux/skbuff.h>
#include <net/ip.h>
#include <net/sock.h>
#include <linux/netfilter_ipv4.h>
#include <linux/kernel.h>
#include <linux/module.h>

// 注册结构
static struct nf_hook_ops ops;

// 过滤钩子
static unsigned int filter_hook(void* priv, struct sk_buff* skb,
    const struct nf_hook_state* state) {
    struct iphdr* iph = ip_hdr(skb); // IP包头

    if (iph->protocol == IPPROTO_ICMP) {
        printk("Drop ICMP packet\n");
        return NF_DROP;
    }

    return NF_ACCEPT;
}

// 加载模块
int init_module(void) {
    // sudo cat /proc/kmsg
    printk("Initializing module ...\n");

    // 注册钩子
    ops.hook     = filter_hook;
    ops.pf       = PF_INET;
    ops.hooknum  = NF_INET_PRE_ROUTING;
    ops.priority = NF_IP_PRI_FIRST;    
    if (nf_register_net_hook(&init_net, &ops) == -1) {
        printk("Unable to register hook\n");
        return -1;
    }

    return 0;
}

// 卸载模块
void cleanup_module(void) {
    // 注销钩子
    nf_unregister_net_hook(&init_net, &ops);

    printk("Exiting module OK!\n");
}

MODULE_LICENSE("GPL");

2. 地址过滤模块

// addrfilter.c
// 地址过滤模块

#include <linux/skbuff.h>
#include <net/ip.h>
#include <linux/inet.h>
#include <linux/netfilter_ipv4.h>
#include <linux/kernel.h>
#include <linux/module.h>

// 注册结构
static struct nf_hook_ops ops;

// 过滤钩子
static unsigned int filter_hook(void* priv, struct sk_buff* skb,
    const struct nf_hook_state* state) {
    struct iphdr* iph = ip_hdr(skb); // IP包头

    if (iph->saddr == in_aton("127.0.0.1")) {
        printk("Drop packet come from 127.0.0.1\n");
        return NF_DROP;
    }

    return NF_ACCEPT;
}

// 加载模块
int init_module(void) {
    // sudo cat /proc/kmsg
    printk("Initializing module ...\n");

    // 注册钩子
    ops.hook     = filter_hook;
    ops.pf       = PF_INET;
    ops.hooknum  = NF_INET_PRE_ROUTING;
    ops.priority = NF_IP_PRI_FIRST;    
    if (nf_register_net_hook(&init_net, &ops) == -1) {
        printk("Unable to register hook\n");
        return -1;
    }

    return 0;
}

// 卸载模块
void cleanup_module(void) {
    // 注销钩子
    nf_unregister_net_hook(&init_net, &ops);

    printk("Exiting module OK!\n");
}

MODULE_LICENSE("GPL");

3. 端口过滤模块

// portfilter.c
// 端口过滤模块

#include <linux/skbuff.h>
#include <net/ip.h>
#include <linux/netfilter_ipv4.h>
#include <linux/kernel.h>
#include <linux/module.h>

// 注册结构
static struct nf_hook_ops ops;

// 过滤钩子
static unsigned int filter_hook(void* priv, struct sk_buff* skb,
    const struct nf_hook_state* state) {
    struct iphdr* iph = ip_hdr(skb); // IP包头

    if (iph->protocol == IPPROTO_TCP) {
        struct tcphdr* tcph = tcp_hdr(skb); // TCP包头

        if (tcph->dest == ntohs(8000)) {
            printk("Drop packet go to 8000\n");
            return NF_DROP;
        }
    }

    return NF_ACCEPT;
}

// 加载模块
int init_module(void) {
    // sudo cat /proc/kmsg
    printk("Initializing module ...\n");

    // 注册钩子
    ops.hook     = filter_hook;
    ops.pf       = PF_INET;
    ops.hooknum  = NF_INET_PRE_ROUTING;
    ops.priority = NF_IP_PRI_FIRST;    
    if (nf_register_net_hook(&init_net, &ops) == -1) {
        printk("Unable to register hook\n");
        return -1;
    }

    return 0;
}

// 卸载模块
void cleanup_module(void) {
    // 注销钩子
    nf_unregister_net_hook(&init_net, &ops);

    printk("Exiting module OK!\n");
}

MODULE_LICENSE("GPL");

4. 过滤模块构建脚本

# Makefile
# 过滤模块构建脚本

obj-m  := protfilter.o addrfilter.o portfilter.o
KBUILD := /lib/modules/$(shell uname -r)/build
CURDIR := $(shell pwd)

default:
    make -C $(KBUILD) SUBDIRS=$(CURDIR) modules

clean:
    make -C $(KBUILD) SUBDIRS=$(CURDIR) clean

11.3 扩展提高

11.3.1 iptables命令

iptables命令允许系统管理员在用户空间对Netfilter内核模块中的规则表进行插入、删除和修改。规则表中的每条规则都有自己的目标,它告诉系统内核应如何处理满足规则匹配条件的数据包:

11.3.2 iptables参数

iptables命令语法如下所示:

iptables [-t table] command [match] [-j target/jump] options

其中:

1. 操作命令(command)

操作命令 功能 示例
-A/--append 在指定规则链的末尾追加一条规则 iptables -A INPUT --dport 80 -j ACCEPT
-I/--insert 在指定规则链的指定位置插入一条规则 iptables -I INPUT 1 --dport 80 -j ACCEPT
-D/--delete 从指定规则链中删除一条规则 iptables -D INPUT 1
iptables -D INPUT --dport 80 -j ACCEPT
-F/--flush 清空指定或所有规则链 iptables -F INPUT
-R/--replace 替换指定规则链中指定位置的规则 iptables -R INPUT 1 --dport 80 -j DROP
-P/--policy 为指定规则链设置默认策略 iptables -P INPUT DROP
-L/--list 列表显示指定或所有规则链中的所有规则 iptables -L INPUT
-Z/--zero 将指定规则链的计数器清零 iptables -Z INPUT
-N/--new-chain 新建自定义规则链 iptables -N allowed
-E/--rename-chain 更名自定义规则链 iptables -E allowed disallowed
-X/--delete-chain 删除自定义规则链 iptables -X disallowed

2. 匹配条件(match)

匹配条件 含义 示例
-p/--protocol 通信协议 iptables -A INPUT -p tcp -j DROP
-s/--src/--source 源IP地址 iptables -A INPUT -s 192.168.1.1 -j DROP
-d/--dst/--destination 目的IP地址 iptables -A INPUT -d 192.168.1.2 -j DROP
--sport/--source-port 源端口 iptables -A INPUT -p tcp --sport 22 -j DROP
--dport/--destination-port 目的端口 iptables -A INPUT -p tcp --dport 80 -j DROP
-i/--in-interface 输入网卡 iptables -A INPUT -i eth0 -j DROP
-o/--out-interface 输出网卡 iptables -A INPUT -o eth1 -j DROP
--tcp-flags TCP标志 iptables -A INPUT -p tcp --tcp-flags SYN,FIN -j DROP
-syn TCP连接 iptables -A INPUT -p tcp -syn -j DROP
-m multiport 多端口 iptables -A INPUT -p tcp -m multiport --sport 22,53 -j DROP
iptables -A INPUT -p tcp -m multiport --dport 80,96 -j DROP
iptables -A INPUT -p tcp -m multiport --port 23,80 -j DROP
--icmp-type ICMP类型 iptables -A INPUT -p icmp --icmp-type 8 -j DROP
-m limit --limit 流量上限 iptables -A INPUT -m limit --limit 3/second -j DROP
-m limit --limit -burst 浪涌上限 iptables -A INPUT -m limit --limit -burst 5 -j DROP
-m mac --mac-source 源MAC地址 iptables -A INPUT -m mac --mac-source a3:3d:ee:6a:4c:01 -j DROP
-m owner --uid-owner 产生用户 iptables -A INPUT -m owner --uid-owner 100 -j DROP
-m owner --gid-owner 产生组 iptables -A INPUT -m owner --gid-owner 200 -j DROP
-m owner --pid-owner 产生进程 iptables -A INPUT -m owner --pid-owner 300 -j DROP
-m owner --sid-owner 产生会话 iptables -A INPUT -m owner --sid-owner 400 -j DROP
-m state --state 会话状态 iptables -A INPUT -m state --state NEW,RELATED -j DROP

3. 规则目标(target)

规则目标 处理动作
ACCEPT 接受,不继续匹配后续规则
DROP 丢弃,不继续匹配后续规则
REJECT 拒绝,回传通知,不继续匹配后续规则
REDIRECT 重定向到另一个端口
MASQUERADE 将源IP地址伪装成防火墙网卡的IP地址,指定对应端口,不继续匹配后续规则
LOG 记录日志文件/var/log
SNAT 修改源IP地址,指定对应端口,不继续匹配后续规则
DNAT 修改目的IP地址,指定对应端口,不继续匹配后续规则
MIRROR 对调源和目的IP地址,不继续匹配后续规则
QUEUE 放入队列,交由用户程序处理,不继续匹配后续规则
RETURN 返回主规则链继续匹配规则
MARK 附加标记

4. 选项(options)

选项 功能
-v/--verbose 输出详细信息
-x/--exact 显示精确数值
-n/--numeric 显示数值形式
--line-numbers 显示规则序号

11.3.3 iptables应用

通过iptables命令设置Netfilter防火墙,实现如下目标:

1. 清除规则

1) 清除filter规则表中的所有内置规则链
$ sudo iptables -t filter -F
2) 清除filter规则表中的所有自定义规则链
$ sudo iptables -t filter -X
3) 将filter规则表中所有规则链的计数器清零
$ sudo iptables -t filter -Z

2. 默认策略

$ sudo iptables -t filter -P INPUT ACCEPT
$ sudo iptables -t filter -P OUTPUT ACCEPT
$ sudo iptables -t filter -P FORWARD ACCEPT

3. 添加规则

1) 接受来自192.168.1.0~192.168.1.254网段的数据包
$ sudo iptables -t filter -A INPUT -i eth0 -s 192.168.1.0/24 -j ACCEPT
2) 接受来自202.113.25.174地址的数据包
$ sudo iptables -t filter -A INPUT -i eth0 -s 202.113.25.174 -j ACCEPT
3) 丢弃来自202.113.25.0~202.113.25.254网段的数据包
$ sudo iptables -t filter -A INPUT -i eth0 -s 202.113.25.0/24 -j DROP
4) 接受来自202.113.16.0~202.113.16.254网段的数据包
$ sudo iptables -t filter -A INPUT -i eth0 -s 202.113.16.0/24 -j ACCEPT
5) 丢弃目的端口为22和23的TCP数据包
$ sudo iptables -t filter -A INPUT -i eth0 -p TCP -m multiport --dport 22,23 -j DROP
6) 接受目的端口为20和21的TCP数据包
$ sudo iptables -t filter -A INPUT -i eth0 -p TCP -m multiport --dport 20,21 -j ACCEPT
7) 列表显示所有规则链的所有规则
$ sudo iptables -L

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  192.168.1.0/24       anywhere
ACCEPT     all  --  202.113.25.174       anywhere
DROP       all  --  202.113.25.0/24      anywhere
ACCEPT     all  --  202.113.16.0/24      anywhere
DROP       tcp  --  anywhere             anywhere             tcp dpt:ssh
DROP       tcp  --  anywhere             anywhere             tcp dpt:telnet
ACCEPT     tcp  --  anywhere             anywhere             multiport dports ftp-data,ftp

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

达内集团◇C++教研部◇闵卫