1、数据包的流向
数据包在主机上有三个流向:
a、发往本机:从本机的内核空间流向用户空间(应用程序)
b、本机发出:从本机的用户空间流向内核空间,在经过网卡流出
c、转发:从本机的一个网卡进来,从另外一个网卡出去
2、数据链(内置):
iptables有5条内置链来对数据报文进行规则控制
PREROUTING:刚到达本机,在进行路由之前的报文
INPUT:进入到本机的报文
FORWARD:由本机转发的报文
OUTPUT:从本机发出的报文
POSTROUTING:进行路由之后,要离开本机的报文
3、防火墙功能表
上面提到了防火墙有5条链可以配置规则来对数据报文进行控制,那么防火墙都有哪些功能呢?
filter:报文过滤,是否允许报文通过
nat:网络地址转换,用于修改源IP或者目标IP,也可以改端口
mangle:拆解报文,做出修改并重新封装报文。
raw:关闭nat表上启用的连接追踪功能,基本上用不着。
上面4个功能实际上是4个表。以下是各个表包含的链
-
mangle表包含以下链
-
PREROUTING
-
INPUT
-
OUTPUT
-
POSTROUTING
-
-
总之该表不常用,几乎不用。
-
nat表主要用于来源地与目的地的ip或port转换,与linux本机无关主要于内网计算机有关。包含以下链
-
PREROUTING:在进行路由之前进行规则(DNAT/REDIRECT)
-
POSTROUTING:在进行路由判断后执行规则(SNAT/MASQUERADE)
-
OUTPUT:与发送出去的数据包有关
-
-
关于POSTROUTING,固定ip的时候选择SNAT,非固定IP比如拨号上网的时候选择MASQUERADE链,修改目的ip地址的DNAT操作PREROUTING链
-
filter表主要跟linux本机有关,是默认的table,也是最重要的表。包含以下链
-
INPUT:主要与数据包想要进入Linux主机有关
-
OUTPUT:主要于Linux本机所要送出的数据包有关
-
FORWARD:与Linux本机没有关系,他可以将数据包转发到后段的计算机中,于nat这个table相关性很高
-
防火墙功能和链的对应关系:
注意下图中的这些功能有优先级的关系。上面的优先级别下面高,例如在PREROUTING链上,
raw > mangle > nat
数据包传输过程中经过的链和表
4、报文流向和链的对应关系
流入本机:PREROUTING ==> INPUT
由本机流出:OUTPUT ==> POSTROUTING
转发:PREROUTING ==> FORWARD ==> POSTROUTING
练习:如果要求拒绝192.168.1.100这台主机访问本机的web服务,该在哪条链上设置什么功能?
首先拒绝访问本机的web服务用到的是filter功能,而只有INPUT、FORWARD、OUTPUT链能做过滤功能,由于是访问本机的web服务,所以应该是在INPUT链上设置防火墙规则。
5、iptables命令使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#man iptables
iptables [-t table] {-A|-C|-D} chain rule-specification
iptables [-t table] -I chain [rulenum] rule-specification
iptables [-t table] -R chain rulenum rule-specification
iptables [-t table] -D chain rulenum
iptables [-t table] -S [chain [rulenum]]
iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]
iptables [-t table] -N chain
iptables [-t table] -X [chain]
iptables [-t table] -P chain target
iptables [-t table] -E old-chain-name new-chain-name
rule-specification = [matches...] [target]
match = -m matchname [per-match-options]
target = -j targetname [per-target-options]
|
iptables规则格式:
1
|
iptables [-t table] COMMAND chain [-m matchname [per-match-options]]-j targetname [per-target-options]
|
-t table:指定表名,包括raw、mangle、nat、filter。默认为filter表
COMMAND:
实现链管理:
-N:new,自定义一条新的规则链
例如:
1
|
iptables -N mychain
|
创建一个自定义的,名为mychain的链
-X:delete,删除自定义的规则链,如果指定名称,则删除指定的,不指定名称,删除所有自 定义的链
例如:
1
|
iptables -X
|
删除所有自定义的链,删除删除指定的自定义链,后面加链的名称,如:
1
|
iptables -X mychain
|
-P:Policy,设置默认策略,对filter表中的链而言,其默认策略有:
ACCEPT: 接受
DROP: 丢弃
REJECT: 拒绝
-E: 重命名自定义链;引用计数不为0的自定义链不能够被重命名,也不能被删除
规则管理:增、删、查
-A :append,追加一条规则,放在链的尾部
-I: insert, 插入一条规则,后面通常加数字,表示插入到第几条后面,省略是表示插入到第一条
-D:delete,删除:
(1):指明规则序号;如:iptables -t nat -D INPUT 2
(2):指明规则本身
-R:replace,替换指定链上的指定规则;
-F:flush,清空指定的规则链 如:iptables -F INPUT
-Z:zero,置零;
iptables的每条规则都有两个计数器:
(1)匹配到的报文的个数
(2)匹配到的所有的报文的大小之和;
查看规则:
-L:list,列出指定链上的所有规则
-n:numberric, 以数字格式显示地址和端口号
-vv,-vvv:显示详细信息
-x:exactly,显示计数器结果的精确值
--line-numbers:显示规则的序号
chain:指定链名称,包括PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING
匹配条件:
基本匹配条件:无需加载任何模块,由 iptables/netfilter自定提供
[!] -s,--source address[/mask] :检查报文中的源IP地址是否符合此处指定的地址或者范围,!表 示取反
[!] -d,--destination address[/mask] : 检查报文中的目标IP地址是否符合此处指定的地址或范围
[!] -p,--protocol protocol
protocol:tcp、udp、udplite、Icmp、 Icmpv6.esp、ah、sctp、mh or 'all'
{tcp| upd | icmp}
[!] -i,--in-interface name:数据报文流入的接口;只能应用于数据报文流入的环节,如 PREROUTING 、INPUT、和FORWARD链
[!] -o,--out-interface name: 数据报文流出的接口,只能应用于数据报文流出的环节,如
POSTROUTING、OUTPUT和FORWARD链
扩展匹配条件:需要加载扩展模块,方可生效
隐式扩展:不需要手动加载扩展模块,因为它们是对协议的扩展,所以但凡使用了-p指明了协议,就表示已经指明了要扩展的模块
tcp:
[!] --source-port, --sport port[:port] : 匹配报文的源端口,可以是端口范围
[!]--destination-port,--dport port [:port] 匹配报文的目标端口
[!]--tcp-flags mask comp:
[!]--syn:用于匹配第一次握手,相当于"--tcp-flags SYN,ACK,FIN,RST SYN"
udp:
[!] --source-port, --sport port[:port] : 匹配报文的源端口,可以是端口范围
[!]--destination-port,--dport port [:port] 匹配报文的目标端口
icmp:
[!]--icmp-type {type[/code]|typename}
echo-request: 8
echo-reply: 0
显示扩展:必须要手动加载扩展模块。[-m matchname [per-match-options]]
#rpm -ql iptables | grep .so
所有小写字母结尾的都是规则扩展模块,大写字母结尾的都是目标扩展模块
1、multiport扩展:以离散的方式,定义多端口匹配机制,最多支持15个端口
[!] --source-ports,--sports port[,port|port:port]...:指定多个源端口
[!] --destination-ports,--dports port[,port|port:port]...:指定多个目标端口
[!] --ports port[,port|port:port]...:指明多个端口,包含源端口和目标端口
例如:开放本机(ip: 172.16.206.130)的80和22端口
1
|
iptables -A INPUT -d 172.16.206.130 -p tcp -m multiport --dports 22,80 -j ACCEPT
|
2、iprange扩展:指明连续的(但一般不能扩展为整个网络的)IP地址范围
[!] --src-range from[-to]: 源IP地址
[!] --dst-range from[-to]:目标IP地址
例如:拒绝172.16.206.10--172.16.206.15的主机访问本机的web服务的80端口
1
|
iptables -A INPUT -d 172.16.206.30 -p tcp --dport 80 -m iprange --src-range 172.16.206.10-172.16.206.15 -j DROP
|
3、string扩展: 对报文中的应用数据做字符串模式匹配检测;
--algo{bm | kmp}:字符串匹配检测算法,这两种算法性能差不多,随便用哪一个
bm: Boyer*Moore
kmp: Knuth-Pratt-Morris
[!] --string parttern:要检测的字符串模式
[!]--hex-string
4、time扩展:根据将报文到达的时间与指定的时间范围进行匹配
--datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]] :指定起始时间,包括年月日,时分秒
--datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
--timestart hh:mm[:ss] :每天的起始时间
--timestop hh:mm[:ss]:每一天的结束时间
--weekday:指明星期几,值为 Mon, Tue, Wed, Thu, Fri, Sat, Sun, 或者1-7
--kerneltz:centOS7上才有的参数,表示使用内核上的时区,而非默认的UTC
例如:每周末的下午14:30到17:30,不允许172.16.100.0/24网段的用户访问本机Web服务
1
|
iptables -A INPUT -s 172.16.100.0
/24
-d 172.16.206.30 -p tcp --dport 80 -m -
times
--timestart 14:30 --timestop 18:30 --weekdays Sat,Sun -j DROP
|
5、connlimit扩展:根据每客户端IP做并发连接数数量匹配:
--connlimit-upto n:连接的数量小于等于n时匹配
--connlimit-above n:连接的数量大于n时匹配
例如: 限制客户端连接本地FTP服务器的连接数最大为2 (连接超过2次就拒绝)
1
|
iptables -A INPUT -D 172.16.206.130 -P tcp --dport 21 -m connlimit --connlimit-above 2 -j REJECT
|
6、limit扩展:基于收发报文的速率做匹配
令牌桶过滤器
处理动作:
-j targetname [per-target-options]
ACCEPT
DROP
REJECT
RETURN:返回调用链
REDIRECT : 端口重定向
LOG: 记录日志
DNAT: 目标地址转换
SNAT: 原地址转换
MASQUERADE: 地址伪装
......
自定义链:
防火墙服务:
CentOS6:
service iptables {start | sop| restart | status}
start: 读取事先保存的规则,并应用到netfilter上
stop:清空netfilter上的规则,以及还原默认策略等
status:显示生效的规则
restart:清空netfilter上的规则,再读取事先保存的规则,并应用到netfilter上:
默认的规则文件:/etc/sysconfig/iptables
CentOS7:systemctl start | stop | restart | status firewalld.service
iptables命令使用练习:
查看所有链:
1
2
3
4
5
6
7
|
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt
source
destination
Chain FORWARD (policy ACCEPT)
target prot opt
source
destination
Chain OUTPUT (policy ACCEPT)
target prot opt
source
destination
|
新建一条自定义的链:
1
2
3
4
5
6
7
8
9
10
|
[root@localhost conf.d]
# iptables -N mychain
[root@localhost conf.d]
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt
source
destination
Chain FORWARD (policy ACCEPT)
target prot opt
source
destination
Chain OUTPUT (policy ACCEPT)
target prot opt
source
destination
Chain mychain (0 references)
target prot opt
source
destination
|
删除所有自定义的链:
1
2
3
4
5
6
7
8
|
[root@localhost conf.d]
# iptables -X
[root@localhost conf.d]
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt
source
destination
Chain FORWARD (policy ACCEPT)
target prot opt
source
destination
Chain OUTPUT (policy ACCEPT)
target prot opt
source
destination
|
删除指定的自定义链
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
[root@localhost conf.d]
# iptables -N test
[root@localhost conf.d]
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt
source
destination
Chain FORWARD (policy ACCEPT)
target prot opt
source
destination
Chain OUTPUT (policy ACCEPT)
target prot opt
source
destination
Chain
test
(0 references)
target prot opt
source
destination
[root@localhost conf.d]
# iptables -X test
[root@localhost conf.d]
# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt
source
destination
Chain FORWARD (policy ACCEPT)
target prot opt
source
destination
Chain OUTPUT (policy ACCEPT)
target prot opt
source
destination
|
禁止主机172.16.100.216 ping本机(IP 10.10.10.202)
1
2
3
4
5
6
7
8
|
iptables -I INPUT -p icmp -s 172.16.100.216 -d 10.10.10.202 -j REJECT
iptables -t filter -L -n --line-numbers -
v
Chain INPUT (policy ACCEPT 329 packets, 24775 bytes)
num pkts bytes target prot opt
in
out
source
destination
1 0 0 REJECT icmp -- * * 172.16.100.216 10.10.10.202 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt
in
out
source
destination
|
上面的需求还可以这样写
1
|
iptables -I INPUT -d 172.16.206.130 -p icmp --icmp-
type
8 -j DROP
|
这里使用了icmp的扩展协议“--icmp-type”
放行所有已建立的连接和相关连的连接
1
|
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
生产环境,阿里云主机的防火墙配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# Generated by iptables-save v1.4.7 on Tue Nov 17 20:14:09 2015
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth0 -j ACCEPT
-A INPUT -s x.x.x.x
/32
-j ACCEPT
//
允许公司的公网IP的请求进来
-A INPUT -s x.x.x.x
/32
-p tcp -m state --state NEW -m multiport --dports 80 -j ACCEPT
//zabbix
的公网IP,用于监控
-A INPUT -p tcp -m state --state NEW -m multiport --dports 10051 -j ACCEPT
//
开放zabbix server的服务端口
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
# Completed on Tue Nov 17 20:14:09 2015
|
iptables之源地址转换
源地址转换:SNAT
常用案例:企业内部客户端访问外网,这里把iptables server当路由使用
1
|
iptables -t nat -A POSTROUTING -s 192.168.0.0
/24
-o eth0 -j SNAT --to-
source
120.56.35.132
|
1
|
iptables -t nat -A POSTROUTING -s 192.168.10.0
/24
-o eth0 -j SNAT --to-
source
120.56.35.132
|
如果企业用的是ADSL拨号上网,则可以这样写
1
|
iptables -t nat -A POSTROUTING -s 192.168.100.0
/24
-o eth0 -j MASQUERADE
|
MASQUERADE也是SNAT的一种,它能自动找到合适的地址,一般外网地址不是静态IP的情况下用它。
目标地址转换:DNAT
目标地址转换用于让互联网上的主机访问本地内网上的某服务器上的服务,仅作用于nat表上PREROUTING和OUTPUT,同时也有端口转换作用
例如:内网主机172.16.1.100的httpd服务监听在8080端口,互联网上访问防火墙服务器1.2.3.4(代表公网IP)的80时转换到主机172.16.1.100的8080上,
1
|
iptables -t nat -A PREROUTING -d 1.2.3.4 -p tcp --dport 80 -j DNAT --to-destination 172.16.1.100:8080
|