文章目录
iptables的工作原理
Linux的iptables概念框图:
iptable的链和表结构
iptable总体结构
5个链
- iptables结构:iptables –> tables –> chains –>rules
- iptables的表与链:iptables具有Filter,NAT,Mangle,Raw四种内建表
- Filter表:iptables的默认表,具有三种内建链
- input chain - 处理来之外部的数据
- output chain - 处理向外发送的数据
- forward chain- 将数据转发到本机的其它网卡上
- NAT表,有三种内建的链
- prerouting:处理刚到达本机并在路由转发前的数据包,它会转换数据包中的目标IP地址(destination ip address),通常用于DNAT(destination NAT)
- postrouting:处理即将离开本机数据包,它会转换数据包中的源目标IP地址(source ip address),通常SNAT(source NAT)
- output:处理本机产生的数据包
- Mangle表,用于指定如何处理数据包,它能改变TCP头中的Qos位,Mangle表具有5个内建链
- prerouting
- output
- forward
- input
- postrouting
- Raw表,用户处理异常,它具有2个内建链
- prerouting chain
- output chain
详细的数据包流程
iptables的工作机制
让内核空间当中的net filter来读取,并且实现让防火墙工作。而放入内核的地方必须要是特定的位置,必须是tcp/ip的协议栈经过的地方。而这个tcp/ip协议栈必须经过的地方,可以实现读取规则的地方叫做netfilter(网络过滤器),有五个位置,被称为五个钩子函数(hook functions),也叫五个规则链。
- PREROUTING 路由前(数据包从内核流入用户空间的)
- INPUT 数据包流入口(进入或者离开本机的外网接口)
- FORWARD 转发关卡(内核空间中:从一个网络接口进来,到另外一个网络接口中去的)
- OUTPUT 数据包进口(进入或者离开本机的内网接口)
- POSTROUTING 路由后(数据包从用户空间流出的)
这是netfilter 规定的五个规则链,任何一个数据包,只要经过本机,必须经过这个五个链中的其中一个链。
防火墙策略
防火墙策略一般分为两种,一种叫“通”策略,一种叫“堵”策略,通策略,默认门是关着的,必须要定义谁能进去。堵策略规则是,大门是洞开的,但是必须有身份证,否则不能进。当定义策略的时候,要分别定义多条功能,其中:定义数据包中允许或者不允许的策略,filter过滤的功能,而定义地址转换的功能的则是nat选项。为了让这些功能交替工作,制定出了“表”这个定义,区分各种不同的工作功能和处理方式,现在用的比较多个功能有3个:
- filter定义允许或者不允许的
- nat定义地址转换的
- mangle功能:修改报文原数据
- raw异常处理
小扩展:
- filter来讲一般只能做在3个链上:INPUT ,FORWARD ,OUTPUT
- nat来讲一般也只能做在3个链上:PREROUTING ,OUTPUT ,POSTROUTING
- mangle则是5个链都可以做:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
注意:规则的次序非常关键,谁的规则越严格,应该放的越靠前,而检测规则的时候,是按照从上往下的方式进行检查的。
iptables规则的写法:
格式:iptables [-t table] COMMAND chain CRETIRIA -j ACTION
- -t table :3个filter nat mangle
- chain :指定规则在那个链上生效(PREROUTING 、INPUT 、FORWARD、OUTPUT 、POSTROUTING ),当定义策略的时候,是可以省略的
- CRETIRIA :指定匹配标准
- -j ACTION:指定如何进行处理,ACCEPT 、DENY、DROP、REJECT、SNAT、DNAT
比如:
- 不允许172.16.0.0/24的进行访问:
iptables -t filter -A INPUT -s 172.16.0.0./16 -p udp --dport 53 -j DROP - 如果想拒绝的更彻底:
iptables -t filter -R INPUT -s 172.16.0.0/16 -p udp --dport 53 -j REJECT - 查看定义规则的详细信息
iptables -L -n -v
详解iptables的COMMAND:
- 链管理命令(这都是立即生效的)
- -P(–policy) :设置默认策略,默认策略一般只有两种:iptables -P INPUT (DROP|ACCEPT)默认是关着|默认是开的,比如:iptables -P INPUT DROP 默认规则是拒绝的,但是没有定义动作,所以关于外界连接的所有规则包括xshell连接之类的,远程连接都给拒绝。
- -F(–flush) :清空规则链的(注意每个规则链的管理权限),如:iptables -t nat -F PREROUTING(清空nat表的PREROUTING链)和iptables -t nat -F(清空nat表的所有链)
- -N(–new-chain) :支持用户新建一个链,如:iptables -N inbound_tcp_web(表示附在tcp表上用于检查web的)
- -X(–delete-chain):用删除用户定义的空链,使用方法跟-N相同,但是删除之前必须要将里面的链给清空
- -E(rename-chain):用来rename chain 主要是用来给用户自定义的链重命名,如: -E oldname newname
- -Z(–zero):清空链,以及链中默认规则的计数器的(有两个计数器,被匹配到多少个数据包,多少字节),如:iptables -Z(清空)
- 规则管理命令
- -A(–append):追加,在当前链的最后新增一个规则
- -I(–insert) num:插入 ,把当前规则而插入为第几条,如:-I 3 (插入为第三条)
- -R(–repalce) num replays:替换或者修改为第几条规则,格式: iptables -R 3 …
- -D(–delete) num:删除,明确指定删除第几条规则
- 查看管理命令 “-L”
- -n(–numeric):以数字方式显示ip,它会将ip直接显示出来,如果不加-n,则会将ip反向解析为主机名
- -v(–verbose):显示详细信息,如:-vv 或 -vvv 越多越详细
- -x(–exact):在计数器上显示精确值,不做单位换算
- –line-numbers:显示规则的行号
- -t nat:显示所有关卡的信息
- -L(–list):显示所选链的所有规则,经常配合-n -v结合使用
详细的CRETIRIA 匹配标准
- 通用匹配:源地址目标地址的匹配
- -s(–source):指定作为源地址匹配,这里不能指定主机名称,必须是ip,格式:IP/MASK ,如:192.168.1.10/24,而且地址可以取反,加一个"!"表示除了指定ip之外。
- -d(–destination):表示匹配目标地址
- -p(–protocol):用于匹配协议的(这里的协议通常有三种 TCP/UDP/ICMP)
- -i(–in-interface) eth0:从这块网卡流出的数据
- -o(–out-interface) eth0:从这块网卡流出的数据,流出一般在OUTPUT和POSTROUTING上
- 扩展匹配。隐含扩展匹配:对协议的扩展
-p tcp:TCP协议的扩展,一般有三种扩展。
- –dport XX-XX:指定目标端口,不能指定多个非连续端口,只能指定单个端口,比如:–dport 21 或者 --dport 21-23 (此时表示21,22,23)
- –sport :指定源端口
- –tcp-filags: TCP的标志位(SYN,ACK,FIN,PSH,RST,URG),一般要跟两个参数:检查的标志位 或 必须为1的标志位,如:–tcp-flags syn,ack,fin,rst syn 或 --syn(表示检查这4个位,这4个位中syn必须为1,其他的必须为0。用于检测三次握手的第一次包的。对于这种专门匹配第一包的SYN为1的包,还有一种简写方式–syn)
-p udp:UDP协议的扩展
- –dport
- –sport
-p icmp:icmp数据报文的扩展
- –icmp-type:echo-request(请求回显),一般用8 来表示,如: --icmp-type 8 匹配请求回显数据包,echo-reply (响应的数据包)一般用0来表示
- 显式扩展(-m),扩展各种模块
- -m multiport:表示启用多端口扩展之后,就可以启用比如 --dports 21,23,80
iptables的进阶使用
- limit限制流量
#-m limit --limit 1000/s(设置最大平均匹配速率)
#-m limit --limit-burst 15(设置一开始匹配的最大数据包数量)
#-m limit --limit 5/m --limit-burst 15(表示一开始能匹配的数据包数量为15个,每匹配到一个,limit-burst的值减1,所以匹配到15个时,该值为0,以后每过12s,limit-burst的值会加1,表示又能匹配1个数据包)
iptables -A INPUT -i eth0 -m limit --limit 5/m --limit-burst 15 -j ACCEPT
iptables -A INPUT -i eth0 -j DROP
- time :在特定时间内匹配
#--monthdays day1[,day2](在每个月的特定天匹配)
#--timestart hh:mm:ss(在每天的指定时间开始匹配)
#--timestop hh:mm:ss(在每天的指定时间停止匹配)
#--weekdays day1[,day2](在每个星期的指定工作日匹配,值可以是1-7)
iptables -A INPUT -i eth0 -m time --weekdays 1,2,3,4 -jACCEPT
iptables -A INPUT -i eth0 -j DROP
- ttl:匹配符合规则的ttl值的数据包
#--ttl -eq 100(匹配TTL值为100的数据包)
#--ttl -gt 100(匹配TTL值大于100的数据包)
#--ttl -lt 100(匹配TTL值小于100的数据包)
iptables -A OUTPUT -m ttl --ttl-eq 100 -j ACCEPT
- multiport:匹配离散的多个端口
#--sports port1[,port2,port3](匹配源端口)
#--dports port1[,port2,port3](匹配目的端口)
#--ports port1[,port2,port3](匹配源端口或目的端口)
iptables -A INPUT -m multiport --sports 22,80,8080 -j DROP
- state:匹配指定的状态数据包,value可以为NEW、RELATED(有关联的)、ESTABLISHED、INVALID(未知连接)
iptables -A INPUT -m state --state NEW,ESTABLISHED -j ACCEPT
- mark:匹配带有指定mark值的数据包
iptables -t mangle -A INPUT -m mark --mark 1 -j DROP
- mac:匹配特定的mac地址
iptables -A FORWARD -m mac --mac-source 00:0C:24:FA:19:80 -j DROP
详解-j ACTION
常用的ACTION:
- DROP:防火墙丢弃数据包,一般用DROP来隐藏身份,以及隐藏链表
- REJECT:明示拒绝
- ACCEPT:允许防火墙接收数据包
- QUEUE:防火墙将数据包移交到用户空间
- custom_chain:转向一个自定义的链
- DNAT:
- SNAT:
- MASQUERADE:源地址伪装
- REDIRECT:重定向:主要用于实现端口重定向
- MARK:打防火墙标记的
- RETURN:防火墙停止执行当前链中的后续rules规则,并返回到调用链(the calling chain)
案例1:
允许来自于172.16.0.0/16网段的访问本机的172.16.100.1的SSHD服务
分析:因为不需要做NAT地址转换之类的,查看SSHD服务,是在22号端口上,处理机制是接受,对于这个表,需要有一来一回两个规则,允许也好,拒绝也好,对于访问本机服务,最好是定义在INPUT链上,而OUTPUT再予以定义就好。所以规则就是:
#定义进来的
iptables -t filter -A INPUT -s 172.16.0.0/16 -d 172.16.100.1 -p tcp --dport 22 -j ACCEPT
#定义出去的
iptables -t filter -A OUTPUT -s 172.16.100.1 -d 172.16.0.0/16 -p tcp --dport 22 -j ACCEPT
#将默认策略改成DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
状态检测
- 是一种显式扩展,用于检测会话之间的连接关系的,可以实现会话间功能的扩展
- 对于整个TCP协议来讲,是一个有连接的协议,三次握手中,第一次握手,叫NEW连接,而从第二次握手以后的,ack都为1,这是正常的数据传输,和tcp的第二次第三次握手,叫做已建立的连接(ESTABLISHED),还有一种状态,比较诡异的,比如:SYN=1 ACK=1 RST=1,对于这种状态无法识别的,称之为INVALID无法识别的。还有第四种,FTP这种古老的拥有的特征,每个端口都是独立的,21号和20号端口都是一去一回,称之为RELATED。
- 状态一共有四种:NEW、ESTABLISHED、RELATED、INVALID
对于刚才的练习题,可以增加状态检测。比如进来的只允许状态为NEW和ESTABLISHED的进来,出去只允许ESTABLISHED的状态出去,这就可以将比较常见的反弹式木马有很好的控制机制。
#进来的只允许NEW和ESTABLISHED进来,出去只允许ESTABLISHED出去
#查看之前的规则位于第几行
iptables -L -n --line-number
#改写INPUT
iptables -R INPUT 2 -s 172.16.0.0/16 -d 172.16.100.1 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
#改写OUTPUT
iptables -R OUTPUT 1 -m state --state ESTABLISHED -j ACCEPT
#此时如果想再放行一个80端口如何放行
iptables -A INPUT -d 172.16.100.1 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -R INPUT 1 -d 172.16.100.1 -p udp --dport 53 -j ACCEPT
案例2
假如允许ping远端,但远端ping本地不通如何实现呢?
分析:对于ping这个协议,进来的为8(ping),出去的为0(响应),为了达到目的,需要8出去,允许0进来
#在出去的端口上
iptables -A OUTPUT -p icmp --icmp-type 8 -j ACCEPT
#在进来的端口上
iptables -A INPUT -p icmp --icmp-type 0 -j ACCEPT
小扩展:对于127.0.0.1比较特殊,我们需要明确定义它
iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
iptables -A OUTPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT
SNAT和DNAT的实现
通过iptables如何实现NAT的地址转换
SNAT基于源地址的转换
基于原地址的转换一般用在许多内网用户通过一个外网的口上网的时候,这时需要将内网的地址转换为 一个外网的IP,就可以实现连接其他外网IP的功能
#在iptables中就要定义转换,比如要将所有192.168.10.0网段的IP全部转换成172.16.100.1假设的外网地址
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j SNAT --to-source 172.16.100.1
#如果外网地址是动态变换,需要将外网地址换成MASQUERADE(动态伪装),实现自动寻找到外网地址,而自动将其改为正确的外网地址
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -j MASQUERADE
#这里要注意:地址伪装并不适用于所有的地方
#使用拨号网络上网
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
DNAT目标地址转换
对于目标地址转换,数据流向是从外向内的,例如外面的是客户端,里面的是服务器端,通过目标地址转换,可以让外面的ip通过外网ip来访问不同的内部服务器。
#目标地址转换,目标地址转换要做在到达网卡之前进行转换,所以要做在PREROUTING这个位置上
iptables -t nat -A PREROUTING -d 192.168.10.18 -p tcp --dport 80 -j DNAT --to-destination 172.16.100.2
iptables控制规则的存放以及开启
- 所定义的所有内容,当重启的时候都会失效,需要使用一个命令将它保存起来
service iptables save #保存在/etc/sysconfig/iptables这个文件中
#或
iptables-save > /etc/sysconfig/iptables
- iptables-restore 命令
#开机的时候,会自动加载/etc/sysconfig/iptabels
#如果开机不能加载或者没有加载,而是需要让某个配置文件(假设为iptables.2)手动生效,则执行
iptables-restore < /etc/sysconfig/iptables.2
iptable常用命令功
- 查看是否已经安装了iptables以及iptables版本号:iptables -V
- 关闭iptables:service iptables stop
- 启动iptables:service iptables start
- 重启iptables:service iptables restart
- 保存命令行中设置的iptables规则到iptables文件中
- 方法1:service iptables save
- 方法2:/etc/rc.d/init.d/iptables save
- 查看iptables规则
- 方法1:iptables -L -n
- 方法2:service iptables status
- 方法3:cat /etc/sysconfig/iptables
- 方法4:iptables --list
- 方法5:iptables-save
- 查看filter表:iptables -t filter -L
- 查看nat表:iptables -t nat -L
- 查看mangel表:iptables -t mangel -L
- 查看Raw表:iptables -t raw -L
- 清空所有的规则 :iptables –flush
- 显示规则序列号,如果需要删除规则的话,只需删除编号即可:iptables -L -n -v --line-numbers
iptable应用场景
内网服务器应用场景
- 网关服务器安全策略
目标 : 网关服务器系统自生安全策略,只对内网用户开放22端口(sshd服务)
说明: 防火墙的策略顺序一般都是 从 非信任 ==> 信任,默认关闭所有访问权限,然后按照需要逐条开放访问权限
#清空 filter table
[root@localhost]# iptables -F -t filter
[root@localhost]# iptables -X -t filter
[root@localhost]# iptables -Z -t filter
#清空 nat table
[root@localhost]# iptables -F -t nat
[root@localhost]# iptables -X -t nat
[root@localhost]# iptables -Z -t nat
#设置默认策略(INPUT链默认为DROP)
[root@localhost]# iptables -t filter -P INPUT DROP
[root@localhost]# iptables -t filter -P OUTPUT ACCEPT
[root@localhost]# iptables -t filter -P FORWARD ACCEPT
#回环接口(lo),默认accept
[root@localhost]# iptables -A INPUT -p ALL -i lo -j ACCEPT
#只对内网用户开放sshd服务
[root@localhost]# iptables -A INPUT -p tcp -s 192.168.138.0/24 --dport 22 -j ACCEPT
- 共享上网(nat)
目标:使局域网的用户都可以访问外网的服务器
说明: SNAT 和 MASQUERADE 区别。SNAT : 不管是几个地址,必须明确的指定要SNAT的ip,适合网关服务器有固定地址或者是固定地址范围. MASQUERADE : 是针对ADSL动态拨号这种场景而设计,从服务器的网络接口上,自动获取当前ip地址来做NAT,这样就实现了动态SNAT地址转换
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
- 内网的服务器对外服务(端口映射)
目标:使外网用户可以访问到局域网192.168.138.21这台HTTP服务
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A PREROUTING -p tcp -m tcp --dport 80 -j DNAT --to-destination 192.168.138.21
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
- 在网关服务器进行透明代理
目标: 使局域网用户,访问外网web服务时,自动使用squid作web透明代理服务器
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A PREROUTING -s 192.168.138.0/24 -p tcp --dport 80 -i eth0 -j DNAT --to 192.168.138.1
iptables -t nat -A PREROUTING -s 192.168.138.0/24 -p tcp --dport 80 -i eth0 -j REDIRECT --to 3128
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
ip映射
假设有一家ISP提供园区Internet接入服务,为了方便管理,该ISP分配给园区用户的IP地址都是伪IP,但是部分用户要求建立自己的WWW 服务器对外发布信息。可以再防火墙的外部网卡上绑定多个合法IP地址,然后通过ip映射使发给其中某一个IP地址的包转发至内部某一用户的WWW服务 器上,然后再将该内部WWW服务器响应包伪装成该合法IP发出的包。
- 该ISP分配给A单位www服务器的ip情况:伪ip(192.168.1.100)、真实ip(202.110.123.100)
- 该ISP分配给B单位www服务器的ip情况:伪ip(192.168.1.200)、真实ip(202.110.123.200)
- linux防火墙的ip地址情况:内网接口eth1(192.168.1.1)、外网eth0(202.110.123.1)
- 配置流程
#将分配给A、B单位的真实ip绑定到防火墙的外网接口,以root权限执行以下命令
ifconfig eth0 add 202.110.123.100 netmask 255.255.255.0
ifconfig eth0 add 202.110.123.200 netmask 255.255.255.0
#对防火墙接收到的目的ip为202.110.123.100和202.110.123.200的所有数据包进行目的NAT(DNAT)
iptables -A PREROUTING -i eth0 -d 202.110.123.100 -j DNAT --to 192.168.1.100
iptables -A PREROUTING -i eth0 -d 202.110.123.200 -j DNAT --to 192.168.1.200
#对防火墙接收到的源ip地址为192.168.1.100和192.168.1.200的数据包进行源NAT(SNAT)
iptables -A POSTROUTING -o eth0 -s 192.168.1.100 -j SNAT --to 202.110.123.100
iptables -A POSTROUTING -o eth0 -s 192.168.1.200 -j SNAT --to 202.110.123.200