iptables 基本配置详解
什么是防火墙
隔离本地网络与外界网络之间的一道防御系统,通俗的说,防火墙就是防火的墙,主要目的就是隔离火并建立安全区域,所以防火墙对于互联网或计算机而言可能是工作在主机或网络的边缘(计算机的边缘可能是一块网卡,而网络边缘可能是路由),对于进出数据的报文事先定义好的规则中的标准进行检查、监控,一旦符合标准的话,我们就采取由这个规则定义的处理动作,我们称为主机防火墙或网络防火墙。
Linux的网络防火墙:
有两组框架,实现防火功能的主要是netfilter,
Netfilter:是内核中的过滤框架,是网络过滤器
Iptables:是一个生产防火规则的并且能够将其附加在netfilter上,真正实现数据报文过滤的工具,当然这只是其中的一种功能,NAT、mangle等规则生成的工具。而它本身并不能防火,真正起到防火墙功能的是规则,规则只有放到netfilter上才能生效。规则包括处理标准和处理办法防火墙可以是硬件也可以是软件,无论硬件还是软件需要定义规则之后,让其生效,才能真正工作起来工作域
netfilter工作在内核空间(可以放规则的位置),iptables工作在用户空间,可以写规则,通过系统调用将规则放置在与它对应的位置上,只有生效以后这个应用程序就没有用处了
1. 链到表的演化
ipfw-->ipchains-->iptables
每一个链看做每一列的演化
iptables/netfilter:网络过滤器
netfiler:kernel中启用的时才具有作用
hookfunction(钩子函数):或称为链
以理解为把某一个目标端口进程勾选出来,进行过滤规则的匹配
wKioL1ce-3qysfRNAACDSFO5xZw518.jpg
wKiom1ce-uOjVVwnAAcgYH62j1I503.png
[扩展]:使用参考,使用man,对于iptables来讲,是一个多模块的命令,可以使用maniptables;man iptables-extensions
iptables
防火墙功能的实现主要根据其中的一些规则,而这些规则的实现就是由iptables这个工具来写入的
报文流向
(1) 从外部到主机内部->流入
(2) 本机内部的报文到外面的->流出
(3) 报文的转发
只要有报文经过,它必须要从其中的一个位置经过,而路由表中的目标IP可以判定它应该走哪条路这叫路由决策,路由决策发生在一个报文被本机的网卡接收进来以后,送到TCP/IP协议栈上的那一刻就要做出路由决策。上面三种流向是工作在TCP/IP协议栈上的三个钩子函数,任何一个报文经过其中的任何一个流向时都会被检查一遍如果被其中的某条规则匹配到,就会执行其中的处理方法
hook:钩子函数,自上而下逐个检查。五个规则:
prerouting:路由之前
input:本地进来
output:本地出去
forward:转发
postrouting:路由之后
而这每个规则组合起来就是一个链,叫规则链,每一个钩子对应的函数都应该有一个链
五个规则链:
PREROUTING
INPUT
FORWARD
OUTPUT
POSTROUTING
wKiom1ce-3CydLNNAAFPBoC38FU548.jpg
iptables结构:
wKiom1ce-7iicyKiAABrr3KcSVA460.jpg
Iptables内置链与自定义链
内置链:(大写):对应于一个钩子函数
PREROUTING,INPUT,FORWARD,OUTPUT, POSTROUTING
自定义链:
可以使用自定义的链,但只能在被调用时才能发挥作用,而且如果没有被自定义链中的任何规则匹配,还应该有返回机制;用户可以删除自定义的空链,默认链无法删除。每一条规则 都有两个内置的计数器,一个记录被匹配的报文个数,另一个记录被匹配的报文大小之和 ;
Iptables规则的运作模式
wKiom1ce--KgC8JxAADDIH1CWGQ393.jpg
路由功能发生的时刻
报文进入本机后:
判断目标主机是否为本机?
是:input
否:forward
wKioL1ce_NmQOQ1cAABvjZOtC4E327.jpg
报文离开本机之前:
判断经由哪一个接口送往下一跳?
Iptables的规则:
组成部分:根据规则的匹配条件尝试匹配报文,对匹配成功的报文根据规则定义的处理动作做出处理
匹配条件:
基本匹配:
扩展匹配:
处理动作:
基本处理动作
扩展处理动作
自定义处理动作
iptables添加规则时的考量点:
1、 要实现何种功能:判断添加规则至哪个表上
2、 报文流经的位置:判断添加规则至那个链上
IP首部
wKiom1ce_D3SetbRAADxM52lB10026.jpg
Iptables规则实现命令
防火墙开机处理模式
不同版本系统上的开机自启方式
Centos7
~]# Systemctl stop firewalld.service
~]# Systemctl disabled fireealld.service
Centos6
~]# Service iptables stop
~]# Chkconfig iptables off
Iptables规则命令语法
命令格式:iptables [-ttable] SUBCOMMAND chain(链) [matches…] [-j target]
参数:
-t table:表示要操作的表
四个:Raw,mangle,nat,filter
SUBCOMMAND:操作的命令
Chain:要操作的链
Match:匹配的条件,可以是多个
-j:指定匹配到以后的执行动作
链管理:
-N:new 新增一条自定义链
Iptables -N testchain(添加一个空链(引用计数为0))
Iptables -nL查看
[root@bogon ~]# iptables -Ntestchain
[root@bogon ~]# iptables -nL
ChainINPUT (policy ACCEPT)
target prot opt source destination
ChainFORWARD (policy ACCEPT)
target prot opt source destination
ChainOUTPUT (policy ACCEPT)
target prot opt source destination
Chaintestchain (0 references)
target prot opt source destination
-X:delete,删除自定义的空链
[root@bogon ~]# iptables -Xtestchain
[root@bogon ~]# iptables -nL
ChainINPUT (policy ACCEPT)
target prot opt source destination
ChainFORWARD (policy ACCEPT)
target prot opt source destination
ChainOUTPUT (policy ACCEPT)
target prot opt source destination
-P:policy,<链名><动作>设置某个链的默认规则
默认的策略有以下几种:
ACCEPT:接受
Drop:丢弃
Reject:拒绝
[root@localhost ~]# iptables-t filter -P FORWARD DROP
设置filter表的默认规则是DROP
注意:当数据包没有被规则列表里的任何规则匹配到时,按此默认规则的处理,动作前面不能加-j,这也是唯一一种匹配动作前面不加-j的情况
[扩展]如果把Input为drop的话远程连接不上,解决方案:写一个@定时(周期)计划,清除规则
现象:全部改为drop远程以及ping都连接不上但是22号ssh端口仍然在监听
-E:rename 重命名自定义的未被引用(引用计数为0)的链
[root@bogon ~]# iptables -Ntestchain
[root@bogon ~]# iptables -Etestchain mychain
[root@bogon ~]# iptables -nL
ChainINPUT (policy ACCEPT)
target prot opt source destination
ChainFORWARD (policy ACCEPT)
target prot opt source destination
ChainOUTPUT (policy ACCEPT)
target prot opt source destination
Chainmychain (0 references)
target prot opt source destination
[root@bogon ~]#
规则管理:
-A :append 追加一条规则,(默认是放在最后)
[root@localhost ~]# iptables-t filter -A INPUT -j DROP
在filter表的input链里追加一条规则,(作为最后一条规则,匹配所有访问本机ip的数据包,匹配到的丢弃)比如ssh登录的伪终端也被终止
-I :insert <链名> [规则号码] 插入一条规则
[root@localhost ~]# iptables -IINPUT -j DROP
在filter表的INPUT链里插入一条规则(插入成第一条)
[root@localhost ~]# iptables -IINPUT 3 -j DROP
在 filter 表的 INPUT 链里插入一条规则(插入成第 3 条)
注意: 1、-t filter 可不写,不写则自动默认是 filter 表
2、-I 链名 [规则号码],如果不写规则号码,则默认是 1
3、确保规则号码 ≤(已有规则数 + 1),否则报错
-D <链名> <规则号码|具体的规则内容>
Delete 删除一条规则
[root@localhost ~]# iptables-D INPUT 3
(按照号码匹配)删除filter表INPUT链中第三条规则
注意:删除3号后,原来的四号此时变成3号
[root@localhost~]#iptables-D INPUT -s 192.168.1.1 -jDROP
(按照内容匹配)删除filter表INPUT链中内容为"-s 192.168.1.1 -j DROP"的规则(不管其位置在哪里)
注意:.
1、若规则列表中有多条相同的规则时,按内容匹配只删除序号最小的一条
2、按号码匹配删除时,确保规则号码≤已有规则数,否则报错
3、按内容匹配删除时,确保规则存在,否则报错
-R :<链名><规则号码><具体规则内容>
Replace 替换一条规则
[root@localhost ~]# iptables -RINPUT 3 -j ACCEPT
将原来编号为3的规则内容替换为"-j ACCEPT"
注意:确保规则号码<=已有规则数,否则报错
-F :[链名]
Flush 清空规则
[root@localhost ~]# iptables -FINPUT
清空filter 表INPUT 链中的所有规则
[root@localhost ~]# iptables -tNET -F FORWARD
清空nat 表PREROUTING 链中的所有规则
-Z :zero 置零
Iptables的每条规则都有两个计数器:
有本规则匹配到的所有的packets
由本规则匹配到的所有的bytes
-S显示指定链上的所有的规则
[root@localhost ~]# iptables-t filter -S INPUT
-P INPUT ACCEPT
显示的是命令的格式
查看:(不能改变顺序)
-L:[链名]
List 列出规则
-n:numeric表示只显示IP地址和端口号码,不显示域名和服务名[不反解]
[root@localhost ~]# iptables-L INPUT
Chain INPUT (policyACCEPT)
target prot opt source destination
-v:verbose,详细信息(v越多,显示的越详细)
[root@localhost ~]# iptables -vLINPUT
Chain INPUT (policyACCEPT 454 packets, 44317 bytes)
pkts bytes target prot opt in out source destination
[root@localhost ~]# iptables -vvvLINPUT
Chain INPUT (policyACCEPT 478 packets, 46257 bytes)
pkts bytes target prot opt in out source destination
libiptcvlibxtables.so.10. 632 bytes.
Table `filter'
Hooks:pre/in/fwd/out/post = ffffffff/0/98/130/ffffffff
Underflows:pre/in/fwd/out/post = ffffffff/0/98/130/ffffffff
Entry0 (0):
SRCIP: 0.0.0.0/0.0.0.0
DSTIP: 0.0.0.0/0.0.0.0
Interface:`'/................to `'/................
Protocol: 0
Flags: 00
Invflags: 00
Counters: 478packets, 46257 bytes
Cache: 00000000
Target name: `' [40]
verdict=NF_ACCEPT
Entry 1 (152):
SRC IP: 0.0.0.0/0.0.0.0
DST IP: 0.0.0.0/0.0.0.0
Interface: `'/................to`'/................
Protocol:0
Flags:00
Invflags:00
Counters:0 packets, 0 bytes
Cache:00000000
Targetname: `' [40]
verdict=NF_DROP
-x:exactly,在v的基础上,禁止自动的单位换算
[root@localhost~]# iptables -vxL INPUT
ChainINPUT (policy ACCEPT 559 packets, 53847 bytes)
pkts bytes target prot opt in out source destination
--line-numbers:显示链上的规则的编号;
Iptables -nL(n:表示以数字格式显示地址和端口)
组合:-nvL
[root@localhost~]# iptables -L INPUT --line-numbers
ChainINPUT (policy ACCEPT)
num target prot opt source destination
列出filter表中所有的链及所有的规则
Iptables -t NAT-vnL:
用详细方式列出nat 表所有链的所有规则,只显示IP 地址和端口号
Iptables -t NAT -vnL PREROUTING:用详细方式列出nat 表PREROUTING 链的所有规则以及详细数字,不反解
匹配条件: [!]表示可以取反
基本匹配:netfilter自带的匹配机制
[!] -s, <匹配源地址>
可以是ip,NET,DOMAIN,也可以是空(空表示任何地址)
[root@localhost~]# iptables -t filter -A INPUT -s 192.168.0.0/16 -j ACCEPT
[root@localhost~]# iptables -t filter -vnL
ChainINPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
6 428 ACCEPT all -- * * 192.168.0.0/16 0.0.0.0/0
ChainFORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
ChainOUTPUT (policy ACCEPT 4 packets, 528 bytes)
pkts bytes target prot opt in out source destination
在filter表的INPUT链最后追加一条接受匹配来自172.18.0.0/16网络的数据包
[!] -d <匹配目的地址>
可以是ip,NET,DOMAIN,也可以是空(空表示任何地址)
[root@localhost~]# iptables -A OUTPUT -d 192.168.1.1/16 -j ACCEPT
[root@localhost~]# iptables -t filter -vnL
ChainINPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
133 10048 ACCEPT all -- * * 192.168.0.0/16 0.0.0.0/0
ChainFORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
ChainOUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
4 576 ACCEPT all -- * * 0.0.0.0/0 192.168.0.0/16
在filter表的OUPUT链最后追加一条匹配接受去往172.18.0.0/16网络的数据包
Iptables -A OUTPUT -d www.linuxedu.top匹配去往www.linuxedu.top的数据包
[!] -i, --in-interface name 限制报文流入的接口,只能用于prorouting,input及forward
[!] -o, --out-interface name限制报文流出的接口,只能用于output,forward,及postrouting
扩展匹配:经由扩展模块引入的匹配机制,-m matchname
隐式扩展:可以不用使用-m选项专门加载相应的模块,前提是要使用-P选项可匹配何种协议
[!]-p <匹配协议类型>
可以指明只开放某一种协议
协议:tcp,udp,icmp,icmpv6,esp,sh,sctp,mh or <空>
自己ping别人:出去的是8,回来的是0
别人ping自己:进来的是8,出去的是0
0:echo-replay回显应答
8:echo-request回显请求
[!] -sport<匹配源端口>
可以是个别端口,也可以是端口范围
--sport 1000 匹配源端口是1000的数据包
--sport 1000-3000匹配源端口是1000-3000的端口
--sport :3000 匹配源端口是小于3000的端口
--sport 1000: 匹配源端口是大于1000的端口
[!]--dport <匹配目的端口>
可以是个别端口,可以是端口范围
例如:
--dport 80 匹配目的端口是80 的数据包
--dport 6000:8000 匹配目的端口是6000-8000 的数据包(含6000、8000)
--dport :3000 匹配目的端口是3000 以下的数据包(含3000)
--dport 1000: 匹配目的端口是1000 以上的数据包(含1000)
注意:--sport 和--dport 必须配合-p 参数使用
匹配组合:
1、端口匹配
-p udp --dport 53
匹配网络中目的端口是53 的UDP协议数据包
2、地址匹配
-s 10.1.0.0/24 -d 172.17.0.0/16
匹配来自10.1.0.0/24 去往172.17.0.0/16 的所有数据包
3、端口和地址联合匹配
-s 192.168.0.1 -d www.abc.com -p tcp --dport80
匹配来自192.168.0.1,去往www.abc.com 的80 端口的TCP协议数据包
注意:
1、--sport、--dport 必须联合-p 使用,必须指明协议类型是什么
2、条件写的越多,匹配越细致,匹配范围越小
处理动作"
-j targetanme [per-target-iptions]
ACCEPT:通过,允许数据包通过本链而不拦截它,类似Cisco 中ACL 里面的permit
Iptables -A INPUT -j ACCEPT:允许所有访问本机IP 的数据包通过
DROP:丢弃,阻止数据包通过本链而丢弃它,类似Cisco 中ACL 里的deny
Iptables -A FORWARD -s 172.18.0.1/16 -j DROP阻止来源地址为192.168.80.39 的数据包通过本机
REJECT
RETURN|:返回调用的链
REDIRECT:端口重定向
LOG:日志
MARK:防火墙标记
DNAT:目标地址转换
-j DNAT --to IP[-IP][:端口-端口](nat 表的PREROUTING 链)
目的地址转换,DNAT 支持转换为单IP,也支持转换到IP 地址池(一组连续的IP 地址)
例如:
iptables -t nat -A PREROUTING -i ppp0 -p tcp--dport 80 -j DNAT --to 192.168.0.1
解释:把从ppp0 进来的要访问TCP/80 的数据包目的地址改为192.168.0.1
iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 81 -jDNAT --to 192.168.0.2:80
iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 80 -jDNAT --to 192.168.0.1-192.168.0.10
SNAT:源地址转换
-j SNAT --to IP[-IP][:端口-端口](nat表的POSTROUTING 链)源地址转换,SNAT 支持转换为单IP,也支持转换到IP 地址池(一组连续的IP 地址)
例如:
iptables -t nat -A POSTROUTING -s192.168.0.0/24 -j SNAT --to 1.1.1.1
将内网192.168.0.0/24 的原地址修改为1.1.1.1,用于NAT
iptables -t nat -A POSTROUTING -s 192.168.0.0/24-j SNAT --to 1.1.1.1-1.1.1.10
同上,只不过修改成一个地址池里的IP
MASQERADE:地址伪装
-j MASQUERADE
动态源地址转换(动态IP 的情况下使用)
例如:
iptables -t nat -A POSTROUTING -s192.168.0.0/24 -j MASQUERADE
将源地址是192.168.0.0/24 的数据包进行地址伪装
匹配条件:
显示扩展
Multiport:多端口匹配
以离散方式死你故意多端口匹配,最多可以指定15个端口,但是必须与-p参数一起使用
Iptables -A INPUT -p tcp -m multiport-dports 21,22,25,80,110 -j ACCEPT