标签:linux中的iptables的知识 dnat iptables的规则编写和snat
iptables 可以理解为包过滤型防火墙,严格来说iptbles就是规则管理工具
Firewall: 防火墙,隔离工具;
防火墙:工作于主机或网络的边缘,对于进出本主机或网络的报文根据事先定义好的检查规则作匹配检测,对于能够被规则所匹配到的报文做出相应处理的组件;
防火墙按工作的位置可以分为:
主机防火墙:就是对进入本机的报文进行检查和过滤
网络防火墙:是工作于一个网络的边缘,对进入本网络的报文进行检查和过滤的
iptables的功能(也叫表):
filter:过滤,防火墙
nat:网络地址转换,转换源地址(SNAT),转换目的地址(DNAT)
mangle:拆解报文,做出修改,封装报文
raw:关闭nat表上启用的连接追踪机制
链(内置的):
PREROUTING:报文最开始进入主机的位置
INPUT:报文进入主机的用户空间
FORWARD:在主机的内核空间,
OUTPUT:由内核准备发出的
POSTROUTING:出本机的最后一个位置
链还可以自定义,但报文不会经过自定义链,只能在内置链上通过规则进行引用后生效
iptables有四表五链
各功能的实现:
filter:INPUT, FORWARD, OUTPUT
nat: PREROUTING(DNAT), OUTPUT, POSTROUTING(SNAT)
mangle:PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING
raw:PREROUTING, OUTPUT
添加规则的时候需要注意:
(1) 要实现哪种功能:判断添加在哪张表上;
(2) 报文流经的路径:判断添加在哪个链上;
链:链上规则的次序,即为检查的次序;因此隐含一定的法则
(1) 同类规则(访问同一应用),匹配范围小的放上面;
(2) 不同类规则(访问不同应用),匹配到报文频率较大的放上面;
(3) 将那些可由一条规则描述的多个规则合并为一个;
(4) 设置默认策略;
规则的组成部分:报文的匹配条件,匹配到之后的动作
iptables的常用命令格式:
iptables [-t table] {-A|-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
-t table:
filter, nat, mangle, raw
链管理:
-F:flush,清空规则链;省略链,表示清空指定表上的所有的链;
-N:new, 创建新的自定义规则链; 例:iptables -t filter -N IN_public
-X:drop, 删除用户自定义的空的规则链;
-Z:zero,清零,置零规则计数器;
-P:Policy,为指定链设置默认策略;对filter表中的链而言,默认策略通常有ACCEPT, DROP, REJECT;
-E: rEname,重命令自定义链;引用计数不为0的自定义链,无法改名,也无法删除;
规则管理:
-A:append,将新规则追加于指定链的尾部;
-I:insert,将新规则插入至指定链的指定位置;
-D:delete,删除指定链上的指定规则;
有两种指定方式:
(1) 指定匹配条件;
(2) 指定规则编号;
-R:replace,替换指定链上的指定规则;
查看:
-L:list,列出指定链上的所有规则;
-n: numberic,以数字格式显示地址和端口号;
-v: verbose,显示详细信息;
--line-numbers:显示规则编号;
-x: exactly, 显示计数器计数结果的精确值;
匹配条件:
基本匹配:(!是取反的)
[!] -s, --src, --source IP|Netaddr:检查报文中源IP地址是否符合此处指定的地址范围;
[!] -d, --dst, --destination IP|Netaddr:检查报文中目的IP地址是否符合此处指定的地址范围;
[!] -p, --protocol {tcp|udp|icmp}:检查报文中的协议,即ip首部中的协议位所标识的协议;
[!] -i, --in-interface IFACE:数据报文的流入接口;仅能用于PREROUTING, INPUT及FORWARD链上;
[!] -o, --out-interface IFACE:数据报文的流出
扩展匹配:-m macth_name(模块名) --spec_options(选项)
例如:-m tcp --dport 22
扩展匹配分为隐式扩展和显示扩展
隐式扩展:对-p protocol指明的协议进行的扩展,可省略-m选项;
-p tcp:
--dport PORT[-PORT]:目标端口,可以是单个端口或连续多个端口;
--sport PORT[-PORT]
--tcp-flags LIST1 LIST2:检查LIST1所指明的所有标志位,且这其中,LIST2所表示出的所有标记位必须为1,而余下的必须为0;没有LIST1中指明的,不作检查;
一般常用的标志位为SYN, ACK, FIN, RST, PSH, URG
--tcp-flags SYN,ACK,FIN,RST SYN 这个式子等于--syn,这个式子代表的是TCP建立连接的第一个报文
-p udp:--dport;--sport
-p icmp:--icmp-type
可用数字表示其类型:0:echo-reply (ping的响应报文)8: echo-request(ping的请求报文)
显式扩展: 必须使用-m选项指定使用的扩展;
1、multiport扩展:以离散方式定义多端口匹配;最多指定15个端口;
[!] --source-ports,--sports port[,port|,port:port]...:指明多个源端口;
[!] --destination-ports,--dports port[,port|,port:port]...:指明多个离散的目标端口;
[!] --ports port[,port|,port:port]...
2、iprange扩展:指明连续的(但一般是不能扩展为整个网络)ip地址范围时使用;
[!] --src-range from[-to]:指明连续的源IP地址范围;
[!] --dst-range from[-to]:指明连续的目标IP地址范围;
3、string扩展:检查报文中出现的字符串;
4、time扩展:根据报文到达的时间与指定的时间范围进行匹配;
5、connlimit扩展:根据每客户端IP(也可以是地址块)做并发连接数数量匹配;
6、limit扩展:基于收发报文的速率做检查;
7、state扩展:根据连接追踪机制检查连接的状态;
可追踪的连接状态:
NEW:新发出的请求;连接追踪模板中不存此连接相关的信息条目,因此,将其识别为第一次发出的请求;
ESTABLISHED:NEW状态之后,连接追踪模板中为其建立的条目失效之前期间内所进行的通信的状态;
RELATED:相关的连接;如ftp协议的命令连接与数据连接之间的关系;
INVALIED:无法识别的连接;
目标(动作):
-j TARGET:jump至指定的TARGET
TARGRT常用的有以下:
ACCEPT: 接受
DROP: 丢弃
REJECT: 拒绝
RETURN: 返回调用链
REDIRECT:端口重定向
LOG: 记录日志
MARK:做防火墙标记
DNAT:目标地址转换
SNAT:源地址转换
MASQUERADE:地址伪装
...
自定义链:由自定义链上的规则进行匹配检查
保存及重载规则:
保存规则至指定文件:
iptables-save > /PATH/TO/SOMEFILE(路径)
从指定文件重载规则:
iptables-restore < /PATH/FROM/SOMEFILE(路径)
下面做几个实例来演示iptables的命令(是在CentOS6下实现的)
一、主机防火墙
就是在一个主机的内部做iptables
在主机内部放行,ssh(端口22/tcp),telnet(端口23/tcp),web服务(端口80/tcp),dns服务(53/udp,53/tcp)dns直接查询使用的是53/udp,如果是做区域传送使用的是53/tcp
首先打开虚拟机,然后查看规则 iptables -L -n
1、然后在这个虚拟机上做好ftp服务,web服务,然后进行测试
从图中可以看出,ftp telnet http访问都没有问题,远程连接ssh也没有问题
2、打开防火墙,修改默认规则为DROP,但是这更改之前先把ssh的规则做好再更改,避免你连不上主机
一定要先加入ssh的规则之后再把默认的规则改为DROP
iptables -A INPUT -p tcp -d 172.16.249.110 --dport 22 -j ACCEPT
iptables -A OUTPUT -p tcp -s 172.16.249.110 --sport 22 -j ACCEPT
在你更改默认规则时,远程连接没断开,证明你这两条规则是正确的
3、现在在测试ftp,telent,http,ping都是不通的
4、写入让http能访问的规则
iptables -A INPUT -p tcp -d 172.16.249.110 --dport 80 -j ACCEPT
iptables -A OUTPUT -ptcp -s 172.16.249.110 --sport 80 -j ACCEPT
写入让http能访问的规则
iptables -A INPUT -p tcp -d 172.16.249.110 --dport 23 -j ACCEPT
iptables -A OUTPUT -ptcp -s 172.16.249.110 --sport 23 -j ACCEPT
可以把这几条规则合并到一起
iptables -A INPUT -p tcp -d 172.16.249.110 -m multiport --dports 22,23,80 -j ACCEPT
iptables -A OUTPUT -ptcp -s 172.16.249.110 -m multiport --sports 22,23,80 -j ACCEPT
删除第一条规则,然后查看规则,测试通不通
写入规则让ping能通,规则如下
iptables -A INPUT -p icmp -d 172.16.249.110 -j ACCEPT
iptables-A OUTPUT -p icmp -s 172.16.249.110 -jACCEPT
这样ping,telnet,ssh,http都可以正常通信了,
还可以只让自己能ping同别的主机,别的主机ping不通你
规则如下:
首先把做的icmp的规则删掉,然后添加如下规则
iptables -A INPUT -d 172.16.249.110 -p icmp --icmp-type 0 -j ACCEPT 这是只让响应的icmp报文进入,
iptables-A OUTPUT -s 172.16.249.110 -p icmp --icmp-type 8 -j ACCEPT 这是只让请求的icmp报文出去,
可以看到自己的主机可以ping通别的主机,别的主机不能ping通自己
5、下面做ftp的规则
ftp访问比较麻烦,需要借助扩展模块还需要安装一个内核模块,因为ftp访问是两条连接,一条命令连接(端口21),一条数据连接(端口随机)
(1) 装载ftp追踪时的专用的模块:
modprobe nf_conntrack_ftp
(2)放行请求报文:
命令连接:状态为 NEW,ESTABLISHED
数据连接:RELATED,ESTABLISHED
iptables -A INPUT -d 172.16.249.110 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -d 172.16.249.110 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
(3)放行响应报文:
iptables -A OUTPUT -s 172.16.249.110 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
OUTPUT加入RELATED状态是为了,如果自己的主机去访问别的ftp服务器会不通,只有加上这个状态你才能访问别的ftp服务
这样ftp的iptanble规则就做好了
6、DNS就只做查询了,
首先做好dns,然后自己测试下
用别的主机进行dns查询,
然后在做规则,如果想让自己能查询到,别的主机也能查到,规则要写成下面这样
iptables -A INPUT -p udp -d 172.16.249.124 --sport 53 -j ACCEPT
iptables -A INPUT -p udp -d 172.16.249.124 --dport 53 -j ACCEPT
iptables -A OUTPUT -p udp -s 172.16.249.124 --sport 53 -j ACCEPT
iptables -A OUTPUT -p udp -s 172.16.249.124 --dport 53 -j ACCEPT
可以看到自己和别的主机都能查询了
如果自己主机查询不行,别的主机可以查询,规则只需要写下面两条就行了
iptables -A INPUT -p udp -d 172.16.249.124 --dport 53 -j ACCEPT
iptables -A OUTPUT -p udp -s 172.16.249.124 --sport 53 -j ACCEPT
查询结果,可以看到自己不能查询,别的主机可以
如果是区域传送需要打开tcp的53端口,规则跟上面的类似,这里不再演示了
二 网络防火墙
需要打开三台虚拟机,一台模拟外网即互联网上的web服务,另一台做内网主机,剩下的一台做路由器使用,要打开它的核心转发功能,而且要有两块网卡,一块连接内网网络,一块连接外网网络。
外网主机的地址为172.16.249.110 做路由器的连接外网的网卡地址为172.16.249.123,连接内网的网卡地址为192.168.36.1;内网的主机地址为192.168.36.2;
ftp,telnet,http,dns能正常访问,这个跟上面的主机防火墙类似,这是把规则写在做转发的那个主机上,规则内容与上面做的主机防火墙一样,只是写在FORWARD链上;
然后做SNAT和DNAT
NAT:
SNAT: 只修改请求报文的源地址;
DNAT:只修改请求报文的目标地址;
nat表有三条链:
PREROUTING:DNAT
OUTPUT
POSTROUTING:SNAT
源地址转换:iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNet -j SNAT --to-source ExtIP
iptables -t nat -A POSTROUTING -s LocalNET ! -d LocalNet -j MASQUERADE(这是自动给分配一个可以去外网的地址)
目标地址转换:iptables -t nat -A PREROUTING -d ExtIP -p tcp|udp --dport PORT -j DNAT --to-destination InterSeverIP[:PORT]
先给做转发的这台主机添加一块网卡类型选择VMnet2类型,地址添加为192.168.36.1;然后把内网的这一台主机的网卡类型也改为VMnet2类型,然后给内网主机添加地址192.168.36.2,然后网关指向192.168.36.1;或者配一条默认路由指向192.168.36.1
然后从内网主机测试下ping192.168.36.1 是否通
然后给转发主机开启核心转发功能
然后ping172.16.249.123 能通,ping外网主机发现不通,是因为有去的但没有回来的报文,需要给外网主机配一条默认路由,然后在ping就通了
默认路由 route add -net 192.168.36.0/24 gw 172.16.249.123
这样外部网络就做好了,下面开始写iptables规则,ftp和http,ping都能正常访问
1、把转发主机的FORWARD的默认规则改为DROP
iptables -P FORWARD DROP
这个时候再从内网主机ping外网主机就不通了,web也不能访问
加上规则,放行web服务
iptables -A FORWARD -d 172.16.249.110 -p tcp --dport 80 -j ACCEPT
iptables -A FORWARD -s 172.16.249.110 -p tcp --sport 80 -j ACCEPT
测试一下,这个时候能访问http服务,但还是ping不通,因为我们没有做规则
添加这一条iptables -A FORWARD -p icmp -j ACCEPT或者下面两条
iptables -A FORWARD -d 172.16.249.110 -p icmp -j ACCEPT
iptables -A FORWARD -s 172.16.249.110 -p icmp -j ACCEPT
可以ping通了,然后在把tcp的23号端口加入前面写的规则里,telnet也就能通过了
iptables -A FORWARD -d 172.16.249.110 -p tcp -m multiport --dports 23,80 -j ACCEPT
iptables -A FORWARD -s 172.16.249.110 -p tcp -m multiport --sports 23,80 -j ACCEPT
但是会自动关闭,因为telent认为这是不安全的,就强制关闭了,通过抓包可以看到三次握手建立成功了
以ssh为例,把22端口加进去,
iptables -R FORWARD 2 -d 172.16.249.110 -p tcp -m multiport --dports 22,23,80 -j ACCEPT
iptables -R FORWARD 3 -s 172.16.249.110 -p tcp -m multiport --sports 22,23,80 -j ACCEPT
可以通过,
下面做ftp ,
(1) 装载ftp追踪时的专用的模块:
modprobe nf_conntrack_ftp
(2)放行请求报文:
命令连接:状态为 NEW,ESTABLISHED
数据连接:RELATED,ESTABLISHED
iptables -A FORWARD -d 172.16.249.110 -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -d 172.16.249.110 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
(3)放行响应报文:
iptables -A FORWARD -s 172.16.249.110 -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT
可以看到可以访问,
我们--dport在192.168.36.2上做的DNS,
需要在172.16.249.110上能查询需要写如下规则
iptables -A FORWARD -p udp -d 192.168.36.2 --dport 53 -j ACCEPT
iptables -A FORWARD -p udp -s 192.168.36.2 --sport 53 -j ACCEPT
可以看到能访问
如果是区域传送需要打开tcp的53端口,规则跟上面的类似,这里不再演示了
下面做SNAT和DNAT
首先在外网主机上启用抓包命令,tcpdump -i eth0 dst host 172.16.249.110,然后在内网主机192.168.36.2上使用curl http://172.16.249.110访问以下,抓的包如下
可以清晰看到这个包的源地址是192.168.36.2
然后在外网主机172.16.249.110上把刚才加的默认路由删掉,让内外网主机不能通信
这个时候内网主机在访问,抓到的包,可以看到,请求过来了,但是没响应成功
下面在做转发的主机上,写入SNAT,把来至192.168.36.0这一网段的地址转换为172.16.249.123;
转换规则为iptables -t nat -A POSTROUTING -s 192.168.36.0/24 ! -d 192.168.36.0/24 -j SNAT --to-source 172.16.249.123
查看下转发主机上nat表中有没有规则
然后加入上面的规则
然后让内网主机访问外网主机,然后抓包
可以看到能正常访问,可以看到是172.16.249.123这个地址过来访问的
从日志中也可以看到,请求是172.16.249.123而不是192.168.36.2
这样SNAT就做好了,
下面做DNAT,就是把SNAT的过程反转过来,内网主机来提供web服务,外网主机来访问
首先把nat中的规则清掉,然后在内网主机上开启httpd服务,写一个测试页,
内容为Hello , This is 192.168.36.2;这个时候外网主机是访问不到的,它们之间是不通的,外网主机可以访问到网关地址即172.16.249.123,所以我们宣称172.16.249.123这个上有web服务
然后写入规则
iptables -t nat -A PREROUTING -d 172.16.249.123 -p tcp --dport 80 -j DNAT --to-destination 192.168.36.2:80(这个端口如果相同可以省略,如果不同必须加上)
然后在外网主机上进行访问,访问172.16.249.123
这样就可以访问到web服务了,其实172.16.249.123的web服务是没启动的
这样DNAT就做好了,就是把访问的目标地址改变
在内网主机192.168.36.2上抓包可以看到,请求是172.16.249.110发过来的,
这样DNAT就做好了
这样iptables的常用的配置就大致上做完了,如有不对和建议请写入评论。
本文出自 “10520982” 博客,请务必保留此出处http://10530982.blog.51cto.com/10520982/1700728
标签:linux中的iptables的知识 dnat iptables的规则编写和snat
原文地址:http://10530982.blog.51cto.com/10520982/1700728