iptables 详解(基于马哥讲的iptables)
看到网上很多人写的iptables详解有很多错误,还有很多不完整的地方。于是决定自己写一份。供大家参考。
一, 准备工作
本文章用到vmware workstation中2台虚拟机。和一台物理主机
2台虚拟主机为名字:
server: ipaddr:172.16.100.1/16 gateway:172.16.100.254 网卡连接类型为host only(仅主机模式)
firewall:ipaddr:192.168.0.110/24 gateway:192.168.0.1 网卡连接类型为:桥接模式 (可以连接到互联网)
ipaddr:172.16.100.254/16 网卡连接类型为host only(仅主机模式)
一台物理主机window10 (从无线路由中有线接入)ipaddr:192.168.0.111/24 gateway 192.168.0.1 可以连接到互联网(模拟外网地址)
二, 前言
1,什么是防火墙: 防火墙,其实说白了讲,就是用于实现Linux下访问控制的功能的,它分为硬件的或者软件的防火墙两种。无论是在哪个网络中,防火墙工作的地方一定是在某个网络的边缘。而我们的任务就是需要去定义到底防火墙如何工作,这就是防火墙的策略,规则,以达到让它对出入网络的IP、数据进行检测。
目前市面上比较常见的有3、4层的防火墙,叫网络层的防火墙,还有7层的防火墙,其实是代理层的网关。
对于TCP/IP的七层模型来讲,我们知道第三层是网络层,三层的防火墙会在这层对源地址和目标地址进行检测。但是对于七层的防火墙,不管你源端口或者目标端口,源地址或者目标地址是什么,都将对你所有的东西进行检查。所以,对于设计原理来讲,七层防火墙更加安全,但是这却带来了效率更低。所以市面上通常的防火墙方案,都是两者结合的。而又由于我们都需要从防火墙所控制的这个口来访问,所以防火墙的工作效率就成了用户能够访问数据多少的一个最重要的控制,配置的不好甚至有可能成为流量的瓶颈。
三:iptables 的历史以及工作原理
1.iptables的发展:
iptables的前身叫ipfirewall (内核1.x时代),这是一个作者从freeBSD上移植过来的,能够工作在内核当中的,对数据包进行检测的一款简易访问控制工具。但是ipfirewall工作功能极其有限(它需要将所有的规则都放进内核当中,这样规则才能够运行起来,而放进内核,这个做法一般是极其困难的)。当内核发展到2.x系列的时候,软件更名为ipchains,它可以定义多条规则,将他们串起来,共同发挥作用,而现在,它叫做iptables,可以将规则组成一个列表,实现绝对详细的访问控制功能。
他们都是工作在用户空间中,定义规则的工具,本身并不算是防火墙。它们定义的规则,可以让在内核空间当中的netfilter来读取,并且实现让防火墙工作。而放入内核的地方必须要是特定的位置,必须是tcp/ip的协议栈经过的地方。而这个tcp/ip协议栈必须经过的地方,可以实现读取规则的地方就叫做 netfilter.(网络过滤器)
作者一共在内核空间中选择了5个位置,
1.内核空间中:从一个网络接口进来,到另一个网络接口去的
2.数据包从内核流入用户空间的
3.数据包从用户空间流入内核空间的
4.进入/离开本机的外网接口
5.进入/离开本机的内网接口
2.iptables的工作机制
从上面的发展我们知道了作者选择了5个位置,来作为控制的地方,但是你有没有发现,其实前三个位置已经基本上能将路径彻底封锁了,但是为什么已经在进出的口设置了关卡之后还要在内部卡呢? 由于数据包尚未进行路由决策,还不知道数据要走向哪里,所以在进出口是没办法实现数据过滤的。所以要在内核空间里设置转发的关卡,进入用户空间的关卡,从用户空间出去的关卡。那么,既然他们没什么用,那我们为什么还要放置他们呢?因为我们在做NAT和DNAT的时候,目标地址转换必须在路由之前转换。所以我们必须在外网而后内网的接口处进行设置关卡。
这五个位置也被称为五个钩子函数(hook functions),也叫五个规则链。
1.PREROUTING (路由前)
2.INPUT (数据包流入口)
3.FORWARD (转发关卡)
4.OUTPUT(数据包流出口)
5.POSTROUTING(路由后)
这是NetFilter规定的五个规则链,任何一个数据包,只要经过本机,必将经过这五个链中的其中一个链。
3.防火墙的策略
防火墙策略一般分为两种,一种叫“通”策略,一种叫“堵”策略,通策略,默认门是关着的,必须要定义谁能进。堵策略则是,大门是洞开的,但是你必须有身份认证,否则不能进。所以我们要定义,让进来的进来,让出去的出去,所以通,是要全通,而堵,则是要选择。当我们定义的策略的时候,要分别定义多条功能,其中:定义数据包中允许或者不允许的策略,filter过滤的功能,而定义地址转换的功能的则是nat选项。为了让这些功能交替工作,我们制定出了“表”这个定义,来定义、区分各种不同的工作功能和处理方式。
我们现在用的比较多个功能有3个:还有一个不常用raw(本文不介绍)
1.filter 定义允许或者不允许的
2.nat 定义地址转换的
3.mangle功能:修改报文原数据
4.raw功能:把修改的报文还原回去
我们修改报文原数据就是来修改TTL的。能够实现将数据包的元数据拆开,在里面做标记/修改内容的。而防火墙标记,其实就是靠mangle来实现的。
小扩展:
对于filter来讲一般只能做在3条链上:INPUT ,FORWARD ,OUTPUT
对于nat来讲一般也只能做在3条链上:PREROUTING ,OUTPUT ,POSTROUTING
而mangle则是5条链都可以做:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
raw来讲只能2条链上做:PREROUTING,OUTPUT
注意:规则的次序非常关键,谁的规则越严格,应该放的越靠前,而检查规则的时候,是按照从上往下的方式进行检查的。
iptables/netfilter(这款软件)是工作在用户空间的,它可以让规则进行生效的,本身不是一种服务,而且规则是立即生效的。而我们iptables现在被做成了一个服务,可以进行启动,停止的。启动,则将规则直接生效,停止,则将规则撤销。
iptables还支持自己定义链。但是自己定义的链,必须是跟某种特定的链关联起来的。在一个关卡设定,指定当有数据的时候专门去找某个特定的链来处理,当那个链处理完之后,再返回。接着在特定的链中继续检查。
--以上理论来自:http://blog.chinaunix.net/uid-26495963-id-3279216.html
四:iptables 规则的写法
1, iptables 规则定义比较复杂(这里介绍简单通用的写法)
iptables [-t TABLE] COMMAND CHAIN [num] 匹配标准 -j 处理办法
[-t TABLE] :4个分别是filter,nat,mangle,raw 可以省略,默认为filter表
COMMAND :定义对规则进行管理。
CHAIN :5条链分别是PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
[num]:指定对第几条规则进行处理。
匹配标准:下面有详细介绍
-j 处理方法:对匹配到,指定如何进行处理。
匹配标准:
通用匹配
-s, --src: 指定源地址,可以是一个ip 如:192.168.0.111,也可以是一个网络 如:192.168.0.0/24
-d, --dst:指定目标地址
-p {tcp|udp|icmp}:指定协议
-i INTERFACE: 指定数据报文流入的接口
可用于定义标准的链:PREROUTING,INPUT,FORWARD
-o INTERFACE: 指定数据报文流出的接口
可用于标准定义的链:OUTPUT,POSTROUTING,FORWARD
练习1:放行192.168.0.0/24的网络对192.168.0.110(firewall主机ip)SSH的访问
iptables -A INPUT -s 192.168.0.0/24 -d 192.168.0.110 -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -s 192.168.0.110 -d 192.168.0.1/24 -p tcp --sport 22 -j ACCEPT
练习2:修改firewall iptables 中filter 表中INPUT,和OUTPUT链的默认规则为DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
练习3:放行firewall 允许自己和自己通信。
iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -i lo -j ACCEPT
iptables -A OUTPUT -s 127.0.0.1 -d 127.0.0.1 -o lo -j ACCEPT
以上的可以简写为
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
扩展匹配
隐含扩展:不用特别指明由哪个模块进行的扩展,因为此时使用-p {tcp|udp|icmp}
-p tcp
--sport PORT[-PORT]: 源端口 可以使用连续的端口 如:--sport 21-23
--dport PORT[-PORT]: 目标端口
--tcp-flags mask comp: 只检查mask指定的标志位,是逗号分隔的标志位列表;comp:此列表中出现的标记位必须为1,comp中没出现,而mask中出现的,必须为0;
--tcp-flags SYN,FIN,ACK,RST SYN = --syn
--syn 三次握手的第一次
练习4:允许192.168.0.0/24网络对firewall(192.168.0.110)的80端口进行访问
iptables -A INPUT -s 192.168.0.0/24 -d 192.168.0.110 -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -s 192.168.0.110 -d 192.168.0.1/24 -p tcp --sport 80 -j ACCEPT
练习5:拒绝来自所有主机对firewall(192.168.0.110)非法报文请求(syn=1 ack=1 fin=1)
iptables -A INPUT -d 192.168.0.110 -p tcp --tcp-flags SYN,ACK,FIN,RST SYN,ACK,FIN -j DROP
-p icmp
--icmp-type
echo-reply 应答回显 用数字0表示
echo-request 请求回显 用数字8表示
练习6:允许firewall(192.168.0.110)ping 别人的主机,不允许别人ping firewall主机。
iptables -A INPUT -d 192.168.0.110 -p icmp --icmp-type 0 -j ACCEPT
iptables -A OUTPUT -s 192.168.0.110 -p icmp --icmp-type 8 -j ACCEPT
-p udp
--sport PORT[-PORT]: 源端口 可以使用连续的端口 如:--sport 21-23
--dport PORT[-PORT]: 目标端口
显式扩展:必须指明由哪个模块进行的扩展,在iptables中使用-m选项可完成此功能
-m EXTENDSION_NAME --specific-opt
EXTENDSION_NAME:扩展模块名
--specific-opt: 扩展模块名对应的选项
-m state --state
state扩展是ip_conntrack模块实现连接追踪的,它可以对udp, tcp, icmp的状态追踪
NEW:新请求
ESTABLISHED:已建立的连接
RELATED:有关联的连接
INVALID:无效的请求如:syn=1,fin=1,ack=1 这样的非法报文
练习7:允许外面主机访问firewall 的ftp服务。
ftp是一个比较比较特殊的服务:分为:控制连接和数据连接两个阶段。控制连接工作的端口号为21 数据连接分为主动模式和被动模式(工作原理自行查找)
要想iptables对它进行控制需要加载ip_nat_ftp,和ip_contrack_ftp .修改/etc/sysconfig/iptables-config 配置脚本。修改IPTABLES_MODULES="ip_conntrack_ftp ip_nat_ftp"。重启iptables(上面最的规则要先用service iptables save 命令保存,要不重启iptables写的规则就没有了)
iptables -A INPUT -d 192.168.0.110 -p tcp --dport 21 -m state --state NEW -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-m multiport : 用离散端口
--source-ports 指定源端口,如:--source-ports 22,53,80
--destination-ports 指定目标端口 如:--destination-ports 22,53,80
--ports 通用匹配,不论是源端口,还是目标端口
练习8:允许外部主机访问firewall(192.168.0.110)的httpd ,ftpd,SSH 服务
iptables -A INPUT -d 192.168.0.110 -p tcp -m multiport --destination-ports 21,22,80 -m state --state NEW -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT (上面如果用过了,就不用写了)
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT (上面如果用过了,就不用写了)
这是我们可以删除:iptables -A INPUT -s 192.168.0.0/24 -d 192.168.0.110 -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -s 192.168.0.110 -d 192.168.0.1/24 -p tcp --sport 22 -j ACCEPT
iptables -A INPUT -s 192.168.0.0/24 -d 192.168.0.110 -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -s 192.168.0.110 -d 192.168.0.1/24 -p tcp --sport 80 -j ACCEPT
-m iprange
--src-range 源地址范围:如 --src-range 172.168.100.3-172.16.100.100
--dst-range 目标地址范围:如 --dst-range 172.168.100.3-172.16.100.100
iptables -A INPUT -p tcp -m iprange --src-range 172.16.100.3-172.16.100.100 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
-m connlimit: 连接数限制
--connlimit-above n 链接上限n表示个数
iptables -A INPUT -d 192.168.0.110 -p tcp --dport 80 -m connlimit --connlimit-above 2 -j ACCEPT
-m limit
--limit RATE 连接速率 如:3/minute
--limit-burst n 一次最大并发数 n 表示个数
-m string 字符串匹配
--algo {bm|kmp} 指定算法
--string "STRING" 要匹配的字符
以上条件都可以去反:条件取反:!,-s ! 192.168.0.110
五,命令:
管理规则
-A:附加一条规则,添加在链的尾部
-I CHAIN [num]: 插入一条规则,插入为对应CHAIN上的第num条;
-D CHAIN [num]: 删除指定链中的第num条规则;
-R CHAIN [num]: 替换指定的规则;
练习9:(-I用法)向INPUT链中插入为第二条规则
iptables -I INPUT 2 -d 192.168.0.100 -p tcp --dport 53 -j ACCEPT
(-R用法)修改INPUT链中的第二条规则
iptables -R INPUT 2 -d 192.168.0.100 -p udp --dport53 -j ACCEPT
(-D用法)删除INPUT链中的第二条规则
iptables -D INPUT 2
管理链:
-F [CHAIN]:flush,清空指定规则链,如果省略CHAIN,则可以实现删除对应表中的所有链
例如 iptables -t nat -F PREROUTING
iptables -t nat -F 清空nat表的所有链
-P CHAIN: 设定指定链的默认策略;(ACCEPT | DROP)
例如:iptables -P INPUT DROP 设定INPUT默认策略为DROP
-N:自定义一个新的空链
例如: iptables -N NEW_CHAIN 创建新空链
-X: 删除一个自定义的空链
例如: iptables -X NEW_CHAIN 删除空链(注意只能删除自己定义的空链,iptables默认的5条链无法删除)
-Z:置零指定链中所有规则的计数器;
-E: 重命名自定义的链;
iptables -E oldname newname
查看类:
-L: 显示指定表中的规则;
-n: 以数字格式显示主机地址和端口号;
-v: 显示链及规则的详细信息
-vv:
-x: 显示计数器的精确值
--line-numbers: 显示规则号码
查看规则:iptables [-t TABLE] -n -L
iptables [-t TABLE] -n -L -v 显示详细信息
iptables [-t TABLE] -n -L -line-numbers 显示行号的查看
iptables [-t TABLE] -n -L -x 显示计数器的精确值
六,动作(target):
ACCEPT:放行
DROP:丢弃
REJECT:拒绝
DNAT:目标地址转换
SNAT:源地址转换
REDIRECT:端口重定向
MASQUERADE:地址伪装 (做源地址转换时,目标地址为动态获取时)
LOG:日志
MARK:打标记
七,SNAT和DNAT的实现
1,SNAT基于原地址的转换
基于源地址的转换一般用在我们的许多内网用户通过一个外网的口上网的时候,这时我们将我们内网的地址转换为一个外网的IP,我们就可以实现连接其他外网IP的功能
源地址转换需要做在POSTROUTING链上。
例如;现在我们需要server(172.16.100.1)这台主机能够访问192.168.0.111,还能通过192.168.0.110这个接口访问互联网。
具体实现,请看准备工作的firewall和server两台主机的配置。
在firewall 这台主机上开启ip_forward的功能。编辑/etc/sysctl.conf 文件找到net.ipv4.ip_forward = 0 把0改为1.重读配置文件:sysctl -p 命令 这样就能永久有效了。临时开启的方法:echo "1" >/proc/sys/net/ipv4/ip_forward
在firewall主机中:iptables -t nat -A POSTROUTING -s 172.16.100.0/16 -j SNAT --to-source 192.168.0.110
那么,如果192.168.0.110不是固定的怎么办?
我们都知道当我们使用联通或者电信上网的时候,一般它都会在每次你开机的时候随机生成一个外网的IP,意思就是外网地址是动态变换的。这时我们就要将外网地址换成 MASQUERADE(动态伪装):它可以实现自动寻找到外网地址,而自动将其改为正确的外网地址。所以,我们就需要这样设置:
iptables -t nat -A POSTROUTING -s 172.16.100.0/16 -j MASQUERADE
这里要注意:地址伪装并不适用于所有的地方。
2.DNAT目标地址转换
对于目标地址转换,数据流向是从外向内的,外面的是客户端,里面的是服务器端通过目标地址转换,我们可以让外面的ip通过我们对外的外网ip来访问我们服务器不同的服务器,而我们的服务却放在内网服务器的不同的服务器上。
目标地址转换时需要做在PREROUTING链上
例如:现在我们需要物理主机window10 (19.168.0.111)想访问server(172.16.100.1)上的httpd 服务。
在firewall主机中:iptables -t nat -A PREROUTING -d 192.168.0.110 -p tcp --dprot 80 -j DNAT --to-destination 172.16.100.1
注意:访问httpd服务需要的是firewall(192.168.0.110)的地址。
DNAT 还可以做端口映射。如果httpd监听的不是在80端口而是在8080端口上,我们可以
iptables -t nat -A PREROUTING -d 192.168.0.110 -p tcp --dport 80 -j DNAT --to-destination 172.16.100.1:8080
八,控制规则的存放以及开启
注意:你所定义的所有内容,当你重启的时候都会失效,要想我们能够生效,需要使用一个命令将它保存起来
1.service iptables save 命令
它会保存在/etc/sysconfig/iptables这个文件中
2.iptables-save 命令
iptables-save > /etc/sysconfig/iptables
3.iptables-restore 命令
开机的时候,它会自动加载/etc/sysconfig/iptabels
如果开机不能加载或者没有加载,而你想让一个自己写的配置文件(假设为iptables.2)手动生效的话:
iptables-restore 则完成了将iptables中定义的规则手动生效
九:iptables 的总结
iptables 理论知识很重要,市场上的硬件防火墙就是变型的iptables规则,只是配置方法和写法不同。理论都是相通的。学好iptables/netfilter 对学习网络中的防火墙,有很大帮助。