iptables应用小攻略(笔记)
iptables
- 全名netfilter/iptables,ip信息包过滤系统,有两个组件netfilter, iptables组成
- netfilter:也称为【内核空间】,是内核的一部分,由一些信息包过滤表组成,这些表包含内核用来控制信息包过滤处理的规则集
- iptables:是个工具,也成为【用户空间】,它使得操作netfilter的规则集变得容易
-
netfilter/iptables后期简称为iptables。
- iptables是基于内核的防火墙,
- iptables内置了filter,nat,mangle三张表。
- 所有规则配置后不需要重启,立即生效。
-
三(四)张表
- filter表;负责过滤数据包,包括的规则链有,input, output, forward;
- nat表:涉及到网络地址转换,包括的规则链有,prerouting, postrouting, output;
- mangle表:主要应用在修改数据包内容上,用来做流量整形,给数据包打表示,默认的规则链有:input, output, nat, postrouting, prerouting;
- raw表:用于处理异常,包括的规则链有,prerouting,output;一般用不到。
-
五个链
- input 匹配目标IP是本机的数据包
- output 出口数据包,一般不在此链上做配置
- forward 匹配流经本机的数据包
- prerouting 用来修改目的地址,用来做DNAT。如:把内网中的80端口映射到路由器外网端口上
- postrouting 用来修改源地址,用来做SNAT。如:内网PC通过路由器NAT转换功能实现通过一个公网IP地址上网。(比如家里的路由器能让电脑上网)
-
总结:iptables三个表,五个链,结构如下图
- image.png
- 表 -> 链 -> 规则
iptables过滤封包流程
-
iptables过滤封包流程.png
数据包分两大类:1. 发给防火墙本身的数据包;2. 需要经过防火墙的软件包。
- 表之间的优先顺序
- raw > mangle > nat > filter
- 链之间的匹配顺序
- 入站数据:prerouting, input
- 出站数据:output, postrouting
- 转发数据:prerouting, forward, postrouting
- 链内的匹配顺序
- 自上向下按顺序一次进行检查,找到相匹配的规则即停止(LOG选项表示记录相关日志)
- 若在该链内找不到相匹配的规则,则按照该链的默认策略处理(未修改的情况下,默认策略为允许)
PS:iptables能干嘛:路由转发,内网上网,端口映射等
iptables命令操作
· iptables命令语法格式
- iptables [-t 表名] 管理选项 [链名] [条件匹配] [-j 目标动作或跳转]
- 注意事项:
- 不指定表名,默认filter
- 不指定链名,默认表内所有链
- 除非设置规则链的缺省策略,否则需要指定匹配条件
- iptables命令
- ![iptables语法总结](https://img.haomeiwen.com/i11732982/024310e08e886445.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
· iptables命令使用方法
- iptables [-t 表]
<操作命令>
[要操作的链]
[规则号码]
[匹配条件]
[-j 匹配到以后的动作]
- 操作命令:-A, -I, -D, -P, -F
- 查看命令:-[vnx]L
- -A <链名> ,APPEND, 追加一条规则(放到最后)
# 在filter表的INPUT链里追加一条规则(作为最后一条规则)
# 匹配所有访问本机IP的数据包,匹配到的丢弃
iptables -t filter -A INPUT -j DROP
-
-D <链名> <规则号码|具体规则内容> ,DELETE, 删除一条规则
删除规则
注意事项:
- 若规则列表中有多个相同的规则时,按内容匹配只删除序列号最小的一条
- 按号码匹配删除时,确保规则号码<= 已有规则数,否则报错
- 按内容匹配删除时,确保规则存在,否则报错
# 删除filter表INPUT链中内容为"-s 192.168.0.1 -j DROP"的规则
iptables -D INPUT -s 192.168.0.1 -j DROP(按内容匹配删除)
-
-P <链名> <动作>, POLICY,设置某个链的默认规则
修改前filter表INPUT链默认策略
修改后filter表INPUT链默认策略
注意:-P设置了DROP之后,使用-F一定要小心!!!
配置crontab:
*/15 * * * * iptables -P INPUT ACCEPT
*/15 * * * * iptables -F - -F -t <表> <链名>,清除指定表/链上的所有规则
注意:不会清除-P设置的默认规则
# 清除filter表INPUT链上的所有规则
iptables -F INPUT
# 清除filter表所有链上的所有规则
iptables -F
# 清除nat表PREROUTING链上的所有规则
iptables -t nat -F PREROUTING
匹配条件
- 流入,流出接口 (-i, -o)
- 来源,目的地址 (-s, -d)
- 协议类型 (-p)
- 来源,目的端口 (--sport, --dport)
按网络接口匹配
- -i <匹配数据进入的网络接口> #此参数主要应用于nat表,如:目标地址转换
例如:
-i eth0 #匹配是否从网络接口eth0进来
-i ppp0 #匹配是否从网络接口ppp0进来 - -o <匹配数据流出的网络接口>
例如:
-o eth0
iptables -t nat -o eth0 <条件> <动作> - -s <匹配来源地址>
可以是ip, net, domain,也可以空(任何地址)
例如:
-s 192.168.0.1 匹配来自192.168.0.1的数据包
-s 192.168.1.0/24 匹配来自192.168.1.0/24网络的数据包
-s 192.168.1.0/16 匹配来自192.168.1.0/16网络的数据包
-d <匹配目的地址>
可以是ip, net, domain,也可以空
例如:
-d 202.106.0.20 匹配去往202.106.0.20的数据包
-d 202.16.0.0/16 匹配去往202.106.0.0/16网络的数据包
-d www.abc.com 匹配去往域名www.abc.com的数据包
按协议类型匹配
- -p <匹配协议类型>
可以是tcp, udp, icmp等,也可以空
例如:
-p tcp
-p udp
-p icmp --icmp-type 类型
ping:type 8 pong:type 0
按来源目的端口匹配
-
--sport <匹配源端口>
可以是个别端口,可以是端口范围
例如:
--sport 1000 #匹配源端口是 1000 的数据包
--sport 1000:3000 #匹配源端口是 1000-3000 的数据包
--sport :3000 #匹配源端口是 3000以内(包括3000) 的数据包
--sport 1000: #匹配源端口是 1000以上(包括1000) 的数据包 -
--dport <匹配目的端口>
--dport 80 #匹配目的端口是80的数据包
--dport 6000:8000 #匹配目的端口是6000-8000的数据包(包括6000与8000)
--dport :3000 #匹配目的端口是3000以下的数据包(包括3000)
--dport 1000: #匹配目的端口是1000以上的数据包(包括1000)
注意: --sport和 --dport必须配合 -p 使用
匹配应用举例
- 端口匹配
-p tcp --dport 3306 #匹配网络中目的端口是3306的tcp协议数据包 - 地址匹配
-s 10.1.0.0/24 -d172.17.0.0/16 #匹配来自10.1.0.0/24去往172.17.0.0/16的所有数据包 - 端口和地址联合匹配
-s 192.168.0.1 -d www.abc.com -p tcp --dport 80 #匹配来自192.168.0.1,去往www.abc.com的80端口的tcp数据包
注意:
- --sport, --dport必须配合 -p 同时使用,必须指明协议类型
- 条件越多,匹配越细致,匹配范围越小
动作(处理方式)
- ACCEPT
- DROP
- REJECT
- SNAT
- DNAT
- MASQUERADE (假面舞会)伪装一个公网ip地址
-j ACCEPT
通过,允许数据包通过本链,不拦截
例如:
iptables -A INPUT -j ACCEPT
允许所有访问本机ip的数据包通过
-j DROP
丢弃,阻止数据包通过本链,丢弃
例如:
iptables -A FORWARD -j DROP
阻止来源地址为192.168.1.100的数据包本机
注意,这里是阻止通过,而不是阻止访问本机,所以要用FORWARD链
-j SNAT --to IP[-IP] [:端口-端口][(只能用于nat表的POSTROUTING链)
源地址转换,SNAT支持转换为单IP,也支持转换到IP地址池(一组连续的IP地址)
将内网192.168.0.0/24的ip修改为公网IP1.1.1.1
(在nat表里的POSTROUTING链上,把源地址是192.168.0.0/24的数据包的地址修改为1.1.1.1)
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to 1.1.1.1
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -j SNAT --to 1.1.1.1-1.1.1.10(转换到地址池)
扩展:一个IP地址做SNAT转换:可以让内网多少台PC实现上网?大约100台
-j DNAT --to IP[-IP] [:端口-端口][(只能用于nat表的PREROUTING链)
目的地址转换,DNAT支持转换为单IP,也支持转换到IP地址池
把从eth0进来的要访问TCP/80的数据包的目的地址改为192.168.0.1
(把进来的数据包,在nat表的PREROUTING 链上,筛选出进入网卡是eth0,协议是tcp,目标端口是80的数据包的目标地址修改为192.168.0.1)
写法1: iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.0.1
写法2: iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.0.1:80 ( ip+port的写法也可以)
写法3: iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.0.1-192.186.0.10 (转换到网段,有点负载均衡的意思)
-j MASQUERADE
动态源地址转换(动态IP的情况下使用)比如:ADSL
将源地址是192.168.0.0/24的数据包进行地址伪装,转换成eth0上的IP地址,eth0为路由器外网出口IP地址
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE(自动找外网的动态IP)
附加模块
- 按包状态匹配(state)
- 按来源MAC匹配(mac)
- 按包速率匹配(limit)
- 多端口匹配(multiport)
-
按包状态匹配
-m state --state 状态
状态:NEW, RELATED, ESTABLISHED, INVALID
NEW: 有别于tcp的syn
ESTABLISHED: 连接态
RELATED: 衍生态,与conntrack关联(FTP)
INVALID: 不能被识别属于哪个连接或没有任何状态
例:
接收已经建立连接和衍生态的数据包
iptables -A INPUT -m state --state RELATED, ESTABLISHED -j ACCEPT -
按来源MAC分配(mac)
-m mac --mac-source MAC
匹配某个MAC地址
例:
iptables -A FORWARD -m mac --mac-source xx:xx:xx:xx:xx:xx -j DROP
阻断来自某个MAC地址的数据包通过本机
注意:豹纹经过路由器后,数据包中原有的mac信息会被替换,所以在路由后POSTROUTING的iptables中使用mac模块是没有意义的 -
按包速率匹配(limit)
-m limit --limit 匹配速率[--burst 缓冲数量]
用一定速率去匹配数据包
例:
iptables -A FORWARD -d 192.168.0.1 -m limit --limit 50/s -j ACCEPT
iptables -A FORWARD -D 192.168.0.1 -j DROP
注意:两条命令需要同时存在,第一条设置每秒50个数据包,第二条设置超过的第51个数据包被DROP掉 -
多端口匹配(multiport)
-m multiport <--sport | --dport | --ports> 端口1[端口2, ... 端口n]
一次性匹配多个端口,可以区分源端口,目的端口或不指定端口
例:
iptables -A INPUT -p tcp -m multiport --dports 21,22,25,80,110 -J ACCEPT
允许所有数据包访问本服务器的21,22,25,80,110端口
注意:必须与 -p 参数一起使用
web服务器防火墙
单服务器的防护
- 浓情对外服务对象
- 书写规则
网络接口lo的处理
协议 + 端口的处理
状态监测的处理
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dports 22, 80 -j ACCEPT
# 也可以用下面2个规则替代multiport
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# 如果不加状态规则,那么服务器出外网后再回来就会被拒绝
iptables -A INPUT -m state --state RELATED, ESTABLISHED -j ACCEPT
iptables -P INPUT DROP
搭建路由器,通过SNAT使内网PC可以访问外网
- 63可以访问公网,
- 63做路由器,
-
64通过63上网
网络拓扑图
配置步骤
-
配置63的网卡(VM Ware虚拟机上的配置,ecs应该自带了2个网卡,其中有内网网卡)
配置路由转发服务器的eth1网卡
name:eth1
device:eth1
static ip: 192.168.2.1(作为内网客户端PC的网关)
net mask: 255.255.255.0
service network restart
-
启用63的路由转发功能
- vim /etc/systcl.conf,找到net.ipv4.ip_forward=1,将注释放开 开启路由转发
- 保存修改后使配置生效:sysctl -p
-
在63上配置SNAT
# 把来自192.168.2.0/24网段的数据包的源IP改成192.168.1.63(192.168.1.63是公网ip)
iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -j SNAT --to 192.168.1.63
- 配置64(客户端PC)
cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
NM_CONTROLLED=yes
IPADDR=192.168.2.2
NETMASK=255.255.255.0
GATEWAY=192.168.2.1 (这里应该是比较重要的)
DNS1=8.8.8.8
ONBOOT=yes
TYPE=Ethernet
...
NAME=‘’eth0''
HWAD=xx:xx:xx:xx:xx:xx
service network restart
拒绝访问服务器本身,拒绝通过服务器去访问别的机器。主要是考察是否明白iptables每个链的作用
- 过滤位置filter表FORWARD链
- 匹配条件 -s -d -p --sport --dport
- 动作处理 ACCEPT DROP
例:
拒绝访问服务器本身和通过服务器去访问别的机器
环境:
配置好网络和对应IP地址:
64: IP: 192.168.2.2 网卡:Vmnet4
64: GATEWAY: 192.168.2.1
63: eth1: IP: 192.168.2.1 网卡:Vmnet4
63: eth0: IP: 192.168.1.63
网络拓扑图如下:
实验环境网络拓扑图
在63上启用内核路由转发功能
永久生效
vim /etc/sysctl.conf
# net.ipv4.ip_forward=0 # 0改为1
net.ipv4.ip_forward=1
# 保存后执行
systcl -p
例1:禁止64通过63访问192.168.2.1。即不允许访问服务器自身
iptables -A INPUT -s 192.168.2.2 -j DROP
注意:添加在FORWARD链上,是不能阻止访问服务器本身的
引申:可否在OUTPUT链上添加规则,达到不让192.168.2.2访问自身服务器
不太好的方式:iptables -A OUTPUT -s 192.168.2.1 -j DROP
在OUTPUT链上属于出去流程,这时,源地址是本机地址192.168.2.1。这样做可以达到目的,但是伤害太大,所有访问服务器本机的客户端都会被DROP
较合理的方式:iptables -A OUTPUT -d 192.168.2.2 -j DROP
这样写的话,就合理很多,从本机出去时,目的地址是192.168.2.2的数据包被DROP
何时会需要在OUTPUT链上添加规则
当发现服务器被黑,当作肉鸡,不断向指定IP(x.x.x.x)发数据时,可以OUTPUT上限制x.x.x.x
例2:禁止64(192.168.2.2)这台机器通过服务器(63)上网
错误方法:iptables -A OUTPUT -s 192.168.2.2 -j DROP
这种不让数据包出去的思路是不对的,因为64通过63上网,走的是FORWARD链,不经过OUTPUT。请看参考下图
-
iptables过滤封包流程.png
正确方法:iptables -A FORWARD -s 192.168.2.2 -j DROP
使用DNAT功能,把内网web服务器端口映射到路由器外网
实验环境:
64: ip: 192.168.2.2 网卡:Vmnet4。内网,搭建nginx
63: eth1: ip: 192.168.2.1 网卡:Vmnet4
63: eth0: ip: 192.168.1.63
目的:通过访问192.168.1.63,会实际访问到64的nginx
80端口映射:
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j DNAT --to 192.168.2.2:80
通过eth0进入63的,协议是tcp的,访问端口是80的数据包,通过DNAT转到192.168.2.2的80端口上
或者如下写法:
iptables -t nat -A PREROUTING -d 192.168.1.63 -p tcp --dport 80 -j DNAT --to 192.168.2.2:80
目的地址是192.168.1.63的,协议是tcp的,访问端口是80的数据包,通过DNAT转到192.168.2.2的80端口上
如果是ADSL上网:
iptables -t nat -A PREROUTING -i ppp0 -p tcp --dport 81 -j DNAT --to 192.168.0.2:80