防火墙与 Iptables
# 介绍
我们先来看一下netfilter官网 (opens new window)对 iptables 的描述:
iptables is the userspace command line program used to configure the Linux 2.4.x and later packet filtering ruleset. It is targeted towards system administrators.
Since Network Address Translation is also configured from the packet filter ruleset, iptables is used for this, too.
The iptables package also includes ip6tables. ip6tables is used for configuring the IPv6 packet filter.
也就是说iptables
实际上只是位于用户空间的一个面向系统管理员的 Linux 防火墙的管理工具而已,而真正实现防火墙功能的是netfilter
,它是Linux内核中实现包过滤的内核模块,iptables
对应在内核中的模块应该是ip_tables
,我们查看系统内核中ip_tables
的信息的时候可以看到ip_tables.ko
这个模块是在netfilter
这个目录下的。
modinfo ip_tables
----------------------
filename: /lib/modules/3.10.0-1160.66.1.el7.x86_64/kernel/net/ipv4/netfilter/ip_tables.ko.xz
description: IPv4 packet filter
author: Netfilter Core Team <[email protected]>
license: GPL
retpoline: Y
rhelversion: 7.9
srcversion: 3B1EF8CB35F100EA0A8485D
depends:
intree: Y
vermagic: 3.10.0-1160.66.1.el7.x86_64 SMP mod_unload modversions
signer: CentOS Linux kernel signing key
sig_key: 02:3E:03:99:FA:FF:37:2C:35:21:10:B7:BC:E2:EA:6D:EA:55:16:6D
sig_hashalgo: sha256
2
3
4
5
6
7
8
9
10
11
12
13
14
15
实际上除了iptables
还有如nftables
、firewalld
等防火墙工具都是在用户空间(用户层)对相应的内核空间中对应的netfilter
相关的模块进行操作的工具。
# 一些概念
表、链、规则的概念
# 表
# 介绍
iptables
的四个表filter
,mangle
,nat
,raw
,默认表是filter
(没有指定表的时候就是filter表)。
filter 表
:用来对数据包进行过滤,具体的规则要求决定如何处理一个数据包。对应的内核模块为:
iptable_filter
,其表内包括三个链:input
、forward
、output
;nat 表
:nat 全称:network address translation 网络地址转换,主要用来修改数据包的 IP 地址、端口号信息。对应的内核模块为:
iptable_nat
,其表内包括三个链:prerouting
、postrouting
、output
;mangle 表
:主要用来修改数据包的服务类型,生存周期,为数据包设置标记,实现流量整形、策略路由等。对应的内核模块为:
iptable_mangle
,其表内包括五个链:prerouting
、postrouting
、input
、output
、forward
;raw 表
:主要用来决定是否对数据包进行状态跟踪。对应的内核模块为:
iptable_raw
,其表内包括两个链:output
、prerouting
;security表
:此表用于强制访问控制(Mandatory Access Control,MAC)网络规则。应的内核模块为:
iptable_security
,其表内包括两个链:input
、output
、forward
;
raw表只使用在
PREROUTING
链和OUTPUT
链上,因为优先级最高,从而可以对收到的数据包在系统进行ip_conntrack(连接跟踪)前进行处理。一但用户使用了raw表,在某个链上,raw表处理完后,将跳过NAT表和ip_conntrack处理,即不再做地址转换和数据包的链接跟踪处理了。RAW表可以应用在那些不需要做nat的情况下,以提高性能。
# 查看有哪些表
modinfo ip_tables
----------------------
filename: /lib/modules/3.10.0-1160.66.1.el7.x86_64/kernel/net/ipv4/netfilter/ip_tables.ko.xz
description: IPv4 packet filter
author: Netfilter Core Team <[email protected]>
license: GPL
retpoline: Y
rhelversion: 7.9
srcversion: 3B1EF8CB35F100EA0A8485D
depends:
intree: Y
vermagic: 3.10.0-1160.66.1.el7.x86_64 SMP mod_unload modversions
signer: CentOS Linux kernel signing key
sig_key: 02:3E:03:99:FA:FF:37:2C:35:21:10:B7:BC:E2:EA:6D:EA:55:16:6D
sig_hashalgo: sha256
2
3
4
5
6
7
8
9
10
11
12
13
14
15
得到 iptables 模块的位置,执行
ll /lib/modules/3.10.0-1160.66.1.el7.x86_64/kernel/net/ipv4/netfilter | grep iptable_
-----
iptable_filter.ko.xz
iptable_mangle.ko.xz
iptable_nat.ko.xz
iptable_raw.ko.xz
iptable_security.ko.xz
2
3
4
5
6
7
# 链
每个表中都有链,默认的链有以下五种
iptables
的五个链PREROUTING
,INPUT
,FORWARD
,OUTPUT
,POSTROUTING
。
input 链
:当收到访问防火墙本机地址的数据包时,将应用此链中的规则;output 链
:当防火墙本机向外发送数据包时,将应用此链中的规则;forward 链
:当收到需要通过防火中转发给其他地址的数据包时,将应用此链中的规则,注意如果需要实现forward转发需要开启Linux内核中的ip_forward功能;prerouting 链
:在对数据包做路由选择之前,将应用此链中的规则;postrouting 链
:在对数据包做路由选择之后,将应用此链中的规则;
查看表中有那些链可以通过
iptables -t [表名] -L
# 规则
每个链中都有很多条规则,规则是自己定义的。
比如通过以下指令可以查看INPUT链中的规则。
iptables -nL INPUT --line-number
-------------------
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 DROP tcp -- 192.168.31.31 0.0.0.0/0 tcp dpts:22:1024
2 ACCEPT all -- 192.168.31.32 0.0.0.0/0
3 ACCEPT all -- 192.168.31.170 0.0.0.0/0
4 ACCEPT all -- 192.168.31.21 0.0.0.0/0
5 DROP tcp -- 192.168.31.31 0.0.0.0/0 tcp dpt:22
2
3
4
5
6
7
8
9
10
- num 是行号,可以用于后续的插入,删除,替换等。
- target 是目标/跳跃
- ACCEPT,放行
- DROP,拦截、
- RETURN,本链通过。
- 等等,也可以是链名,跳转到另一个链
- source 源地址
- destination 目标地址
- dpts,就是目标端口,后面的代码端口值,22:1024 则是代表 22-1024 端口
# 状态机
你用ssh远程访问,你的主机和远程主机会进行通信。 静态的防火墙会这样处理: 检查时入机器的数据包,发现数据是来源是22端口,当允许时入,连接之后相互通信的数据也一样,检查每个数据,发现数据来源于22端口,允许通过!
如果用有状态的防火墙如何处理呢? 当你连接远程主机成功之后,你的主机会把这个连接记录下来,当有数据从远程ssh服务器再进入你的机器时 检查自己连接状态表,发现这个数据来源于一个已经建立的连接,允许这个数据包进入。
在iptables上一共有四种状态,分别被称为NEW、ESTABLISHED、INVALID、RELATED,这四种状态对于TCP、UDP、ICMP三种协议均有效。下面,我们来分别阐述四种状态的特性。
NEW:如果你的主机向远程机器发时一个连接请求,这个数据包状态是NEW.
ESTABLISHED: 当联接建立之后,远程主机和你主机通信数据状态为ESTABLISHED
RELATED: 像ftp这样的服务,用21端口传送命令,而用20端口(port模式)或其他端口(PASV模式)传送数据。在已有21端口上建立好连接后发送命令,用20传送的数据,状态是RELATED
INVALID:INVALID说明数据包不能被识别属于哪个连接或没有任何状态。有几个原因可以产生这种情况,比如,内存溢出,收到不知属于哪个连接的ICMP错误信息。一般地,我们DROP这个状态的任何东西,因为防火墙认为这是不安全的东西。
# 所有已经建立联接,或者与之相关的数据允许通过
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 设置默认全部禁止
iptables -P INPUT DROP
2
3
4
# 持久化
使用 iptables 程序建立的规则只会保存在内存中,通常我们在修改了 iptables 的规则重启 iptables 后,之前修改的规则又消失了。那么如何保存新建立的规则呢?
# 导出规则
规则导出到文件。
# 全部规则
iptables-save > rule.txt
# 指定表的规则
iptables-save -t filter > rule-filter.txt
2
3
4
5
# 导入规则
从文件还原规则
# 导入全部规则,会先 flush
iptables-restore < rule.txt
# 导入全部规则,不 flush
iptables-restore -n < rule.txt
# 导入指定表规则
iptables-restore -t filter < rule-filter.txt
2
3
4
5
6
# 永久生效
# 将规则到处到这个位置即可
iptables-save > /etc/sysconfig/iptables
# 自动保存,修改配置
vim /etc/sysconfig/iptables-config
-----
# Save current firewall rules on stop.
# Value: yes|no, default: no
# Saves all firewall rules to /etc/sysconfig/iptables if firewall gets stopped
# (e.g. on system shutdown).
IPTABLES_SAVE_ON_STOP="no"
2
3
4
5
6
7
8
9
10
11
其实自动保存也是在关机时把配置信息写入 /etc/sysconfig/iptables
# 常用方法
iptables [-t 表名] 管理选项 [链名] [匹配条件] [-j 控制类型]
表名
、链名
:指定iptables
命令所操作的表
和链
,未指定表名时将默认使用filter
表;管理选项
:表示iptables
规则的操作方式,比如:插入
、增加
、删除
、查看
等;iptables 命令的常用管理选项 -A:在指定链的末尾添加一条新的规则 -D:删除指定链中的某一条规则,可删除指定序号或具体内容 -I:在指定链中插入一条新规则,未指定序号时默认作为第一条规则 -R:修改、替换指定链中的某一条规则,可指定规则序号或具体内容 -L:列出指定链中所有的规则,未指定链名,则列出表中的所有链 -F:清空指定链中所有的规则,未指定链名,则清空表中的所有链 -P:设置指定链的默认策略 -n:使用数字形式显示输出结果 -v:查看规则列表时显示详细的信息 -h:查看命令帮助信息 --line-numbers:查看规则列表时,同时显示规则在链中的顺序号
1
2
3
4
5
6
7
8
9
10
11
12匹配条件
:指定要处理的数据包的特征,不符合指定条件的数据包不处理;-i --in-interface 网络接口名> 指定数据包从哪个网络接口进入, -o --out-interface 网络接口名> 指定数据包从哪个网络接口输出 -p ---proto 协议类型 指定数据包匹配的协议,如TCP、UDP和ICMP等 -s --source 源地址或子网> 指定数据包匹配的源地址 --sport 源端口号> 指定数据包匹配的源端口号 --dport 目的端口号> 指定数据包匹配的目的端口号 -m --match 匹配的模块 指定数据包规则所使用的过滤模块
1
2
3
4
5
6
7控制类型
:指数据包的处理方式,比如:允许accept
、拒绝drop
、丢弃drop
、日志LOG
等;
# 设置默认策略
如果链中的规则没有匹配上的,默认为全部请求禁止接入
iptables -P INPUT -j DROP
# 规则的增删改查
# 查看规则列表
iptables -L -t [表名]
iptables -L -t filter
iptables -L -t nat
iptables -L -t managle
2
3
4
# 新增规则
iptables -A INPUT -s 192.168.31.99 -j DROP
# 插入规则
iptables -I INPUT 5 -s 192.168.31.99 -j DROP
# 替换规则
$ iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 192.168.31.31 anywhere
2
3
4
替换 INPUT 链的第一条规则为 DROP,协议为 TCP
iptables -R INPUT 1 -j DROP -s 192.168.31.31 -p tcp
# 删除规则
删除 INPUT 链的第一个规则。
iptables -D INPUT 1
# 清空规则
iptables -F [链]
iptables --flush [链]
2
# 链的增删
# 增加一条链
iptables -N unclezs
iptables --new unclezs
-------
$ iptables -L unclezs
Chain unclezs (0 references)
target prot opt source destination
2
3
4
5
6
# 重命令链
iptables -E unclezs unclezs1
iptables --rename-chain unclezs unclezs1
-------
$ iptables -L unclezs1
Chain unclezs1 (0 references)
target prot opt source destination
2
3
4
5
6
# 删除链
iptables -X unclezs
iptables --delete-chain unclezs
2