iptables详解
iptables详解
基本概念:
1.防火墙工作在主机边缘:对于进出本网络或者本主机的数据报文,根据事先设定好的检查规则对其检查,对形迹可疑的报文一律按照事先定义好的处理机制做出相应处理
对linux而言tcp/ip协议栈是在内核当中,意味着报文的处理是在内核中处理的,也就是说防火墙必须在工作在内核中,防火墙必须在内核中完成tcp/ip报文所流进的位置,用规则去检查,才真正能工作起来。
iptables用来衡量tcp/ip报文的属性:源ip、目标ip、源端口、目标端口;
tcp标志位: syn、syn+ack、ack、 fin、urg、psh、rst ;
2.应用网关
众多代理服务器都是应用网关,比如squid(使用acl限制应用层)varish这一类代理服务等。
3,入侵检测系统(IDS):
·网络入侵检测系统 NIDS
·主机入侵检测系统 HIDS
对于IDS常用的检测服务有:snort等
4.入侵防御系统(IPS),比如蜜罐
部署一套入侵检测系统是非常麻烦的,因为必须检测网络任意一个位置
对于IPS常用的检测服务有: tripwire 等
iptables基本概念
对linux来说,是能够实现主机防火墙的功能组件,如果部署在网络边缘,那么既可以扮演网络防火墙的角色,而且是纯软件的
网络数据走向:
请求报文à网关à路由à应用程序(等待用户请求)à内核处理à路由à发送报文
iptables规则功能
filter表:
filter主要和主机自身有关,主要负责防火墙功能 过滤本机流入流出的数据包是默认使用的表;
input :负责过滤所有目标地址是本机地址的数据包,就是过滤进入主机的数据包;
forward :负责转发流经主机但不进入本机的数据包,和NAT关系很大;
output :负责处理源地址的数据包,就是对本机发出的数据包;
NAT表:
负责网络地址转换,即来源于目的IP地址和端口的转换,一般用于共享上网或特殊端口的转换服务
snat :地址转换
dnat :标地址转换
pnat :标端口转换
mangle 表:
将报文拆开来并修改报文标志位,最后封装起来
5个检查点(内置链)
·PREROUTING
·INPUT
·FORWORD
·OUTPUT
·POSTROUTING
多条链整合起来叫做表,比如,在input这个链,既有magle的规则也可能有fileter的规则。因此在编写规则的时候应该先指定表,再指定链
netfilter主要工作在tcp/ip协议栈上的,主要集中在tcp报文首部和udp报文首部
规则的属性定义:
1.网络层协议
主要集中在ip协议报文上
2.传输层协议属性:
主要集中在
tcp
udp
icmp icmp其并不是真正意义传输层的,而是工作在网络层和传输层之间的一种特殊的协议
3.ip报文的属性:
IP报文的属性为: 源地址.目标地址
4.iptables规则匹配
iptables如何查看表和链
大写字母选项:可以实现某种功能,比如添加删除清空规则链;
小写字母选项:用来匹配及其他;
-L :list 列表
-n :数字格式显示ip和端口;
--line-numbers:显示行号;
-x : 显示精确值,不要做单位换算;
-t : 指定表
-t{fillter|nat|mangle|raw}
-v : 显示详细信息 -v -vvv -vvvv ..可以显示更详细的信息
5.其他子命令:
管理链:
-F :清空链
清空nat表中的input链,格式如下:
#iptables-t nat -F INPUT
#清空fllter表所有链:
#iptables-F
-P : 设定默认策略,为指定链设置默认策略,格式如下:
#设置fllter表input链的默认规则为丢弃
iptables-t fllter -P INPUT DROP
-N : 新建一条自定义链(内置链不能删除,如果太多,可以自定义链)
#自定义连只能被调用才可以发挥作用
iptables-N fillter_web
-X : 删除自定义空链,如果链内有规则,则无法删除
-Z :计算器清零
iptables-Z
-E :重命名自定义链
iptables管理规则:
-A :append附加规则,将新增的规则添加到链的尾部
-I[n] :插入为第n条规则
-D : 删除第n条规则
-R[n] : 替换第N条
表和链的对应关系:
fillter :INPUT FORWORD OUTPUT
nat : PREROUTING POSTROUTING OUTPUT
使用-t指定表来查看指定表内的规则:
#iptables-t nat -L -n
raw : prerouting output
iptables-t raw -L -n
mangle: prerouting input forword output postrouting
iptables-t mangle -L -n
#查看规则
[root@test3~]# iptables -L -n
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot optsource destination
Chain OUTPUT (policy ACCEPT)
target prot optsource destination
通过以上可以观察到,每一个链都有默认策略:policy ACCEPT
通常只需要修改fllter表的默认策略即可,由此如果有报文请求来访问本机的某个服务,那么则会经过input链,因此进来的报文都是需要做过滤的,那么出去的报文则不需要过滤,在有些特定的场所下也需要做过滤
所以写规则的时候必须放将规则写在正确链上,意义非常重大
规则和默认策略都有2个计数器,通过-v选项可以观察规则的匹配情况
#iptables -t nat -L -n -v
[root@sshgw~]# iptables -L -n -v
ChainINPUT (policy ACCEPT 7 packets, 975 bytes)
pkts bytestarget prot opt in out source destination
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
0 0 DROP all -- eth2 * 101.61.0.0/10 0.0.0.0/0
0 0 DROP all -- eth2 * 127.0.0.0/8 0.0.0.0/0
0 0 DROP all -- eth2 * 162.254.0.0/16 0.0.0.0/0
0 0 DROP all -- eth2 * 192.0.0.0/24 0.0.0.0/0
0 0 DROP all -- eth2 * 192.0.2.0/24 0.0.0.0/0
0 0 DROP all -- eth2 * 197.18.0.0/15 0.0.0.0/0
0 0 DROP all -- eth2 * 197.51.100.0/24 0.0.0.0/0
0 0 DROP all -- eth2 * 203.0.111.0/24 0.0.0.0/0
0 0 DROP all -- eth2 * 224.0.0.0/4 0.0.0.0/0
0 0 DROP all -- eth2 * 240.0.0.0/4 0.0.0.0/0
776 37056 REFRESH_TEMP all -- * * 0.0.0.0/0 0.0.0.0/0
编写规则语法:
iptables [-t 表] 大写选项子命令 [规则号] 链名 匹配标准 -j 目标(规则)
目标:
DROP : 丢弃
REJECT : 拒绝
ACCEPT : 接受
RETURN : 返回主链继续匹配
REDIRECT: 端口重定向
MASQUERADE :地址伪装
DNAT : 目标地址转换
SNAT :源地址转换
MARK :打标签
LOG
自定义链
匹配标准
iptables的匹配标准大致分为两类:
1.通用匹配
-s | --src | --source [!] IP/NETWORK
-d ------------------------
-i :指定数据报文流入接口 input prerouting forward
-o :指定数据报文流出接口 output postrouting forward
-p :明确说明只放行哪种协议的报文匹配规则
以当前主机为例:
凡是来自于某个ip段的网络访问本机
[root@test3xtables-1.4.7]# iptables -A INPUT -s 10.0.10.0/24 -d 10.0.10.0/24 -j ACCEPT
[root@test3 xtables-1.4.7]# iptables -L -n -v
ChainINPUT (policy ACCEPT 10 packets, 1029 bytes)
pkts bytestarget prot opt in out source destination
22 1660 ACCEPT all -- * * 10.0.10.0/24 10.0.10.0/24
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 16 packets, 1536 bytes)
pkts bytes target prot opt in out source destination
pkts 被本机报文所匹配的个数
bytes 报文所有大小记起来之和
opt 额外的选项,--表示没有
target 处理机制
prot 放行哪种协议
source 源地址
destination 目标地址
对于严谨的规则,一般默认规则都是拒绝未知,允许已知
如下所示:
只放行信任IP地址段,其他全部禁止
iptables-P INPUT DORP
iptables-A INPUT -s 10.0.10.0/24 -d 10.0.10.0/24 -j ACCEPT
iptables-P OUTPUT DORP
iptables-A OUTPUT -d 10.0.10.0/24 -s 10.0.10.0/24-j ACCEPT
保存规则
[root@test3~]# /etc/init.d/iptables save
iptables:Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
保存规则至其他文件
[root@test3~]# iptables-save > /tmp/iptables
加载iptables文件规则
[root@test3~]# iptables-resotre < /tmp/iptables
1.2.规则的替换
首先来查看规则
[root@test3 ~]# iptables -L -n --line-number
ChainINPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- 10.0.10.0/24 10.0.10.0/24
ChainFORWARD (policy DROP)
num target prot opt source destination
ChainOUTPUT (policy ACCEPT)
num target prot opt source destination
替换规则:将规则1替换为 eth0只能够通过某个网段进来
[root@test3~]# iptables -R INPUT 1 -s 10.0.10.0/24-d 10.0.10.62 -i eth0 -j ACCEPT
[root@test3~]# iptables -L -n --line-number
ChainINPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT all -- 10.0.10.0/24 10.0.10.62
2.扩展匹配
#所有的扩展匹配表示要使用-m来指定扩展的名称来引用,而每个扩展模块一般都会有自己特有的专用选项,在这些选项中,有些是必备的:
2.1隐含扩展
如下所示:
#端口之间必须是连续的
-p tcp--sport|--dport 21-80
#取反,非21-80的端口
-p tcp--sport|--dport !21-80
#检测报文中的标志位
--tcp-flagsSYN,ACK,RST,FIN, SYN
ALL #表示为所有标志位
NONE #表示没有任何一个标志位
#--tcp-flags ALL NONE #表示所有标志位都检测,但是其中多有都为0
#--tcp-flage ALL SYN,FIN #表示SYN,FIN都为1(即握手又断开)
#生成环境下tcp-flags 用的非常多,意义非常重要
例:放行本机对web的访问
[root@test3~]# iptables -A INPUT -d 10.0.10.62 -ptcp --dport 80 -j ACCEPT
[root@test3~]# iptables -L -n
ChainINPUT (policy DROP)
target prot opt source destination
ACCEPT all -- 10.0.10.0/24 10.0.10.62
ACCEPT tcp -- 0.0.0.0/0 10.0.10.62 tcp dpt:80
放行出去的报文,源端口为80
[root@test3~]# iptables -A OUTPUT -s 10.0.10.62 -p tcp --sport 80 -j ACCEPT
查看匹配规则
[root@test3 ~]# iptables -L -n --line-number
ChainINPUT (policy DROP)
num target prot opt source destination
1 ACCEPT all -- 10.0.10.0/24 10.0.10.62
2 ACCEPT tcp -- 0.0.0.0/0 10.0.10.62 tcp dpt:80
ChainFORWARD (policy DROP)
num target prot opt source destination
ChainOUTPUT (policy DROP)
num target prot opt source destination
1 ACCEPT all -- 10.0.10.0/24 10.0.10.0/24
2 ACCEPT tcp -- 10.0.10.62 0.0.0.0/0 tcp spt:80
考虑要点:
(1)规则为放行出去的响应报文
(2)考虑源IP地址为本机,目标为访问的时候拆开报文才可以获知,而写规则的时候是面向所有主机,所以这里不用写
(3)源端口:80 ,因为用户访问的时候一定会访问其80端口,无可非议的
(4)目标端口:请求到来的时候事先无法断定对方的端口是多少,所以不用写
2.2协议匹配
通常对协议做匹配则使用 -p 参数 来指定协议即可
匹配UDP:UDP只有端口的匹配,没有任何可用扩展,格式如下
-p udp--sport | --dport
匹配ICMP格式如下
-picmp --icmp-[number]
icmp常见类型:请求为8(echo-request),响应为0(echo-reply)
例:默认规则input output 都为DROP,使其本机能ping(响应的报文)的报文出去
通过此机器去ping网关10.0.10.1 , 可结果却提示not permitted,使其能通10.0.10.0/24网段中的所有主机
[root@test3~]#iptables -A OUTPUT -s 10.0.10.62 -d 10.0.10.0/24 -p icmp --icmp-type8 -j ACCEPT
可看到无法响应:0表示响应进来的报文规则,并没有放行自己作为服务端的的角色规则
[root@test3~]# iptables -A INPUT -s 10.0.10.0/24 -d 10.0.10.62 -p icmp --icmp-type0 -j ACCEPT
#ping 10.0.10.x
允许类型为0(响应报文)出去
[root@test3~]# iptables -A OUTPUT -s 10.0.10.62 -d 10.0.10.0/24 -picmp --icmp-type 0 -j ACCEPT
例2:本机DNS服务器,要为本地客户端做递归查询;iptables的input output默认为drop 本机地址是10.0.10.62
[root@test3~]# iptables -A INPUT -d 10.0.10.62 -p udp --dprot 53 -j ACCEPT
[root@test3~]# iptables -A OUTPUT -S 10.0.10.62 -p udp --sprot 53 -j ACCEPT
客户端请求可以进来,响应也可以出去,但是自己作为客户端请求别人是没有办法出去的,所以:
[root@test3~]# iptables -A OUTPUT -s 10.0.10.62 -p udp --dport 53 -j ACCEPT
[root@test3~]# iptables -A INPUT -d 10.0.10.62 -p udp --sprot 53 -j ACCEPT
如果为tcp 则将以上udp改为tcp即可
2.3 TCP协议的报文走向
TCP连接的建立
双方主机为了实现tcp的通信,所以首先三次握手
客户端主动发出了SYN,服务器端处于监听状态,随时等待客户端的请求信息;
服务器端接收到了SYN请求,从而回应用户的请求,发送SYN_ACK ,从而转换为SYN_REVIN
客户端在发出了请求,从发出的那一刻close状态转换为SYN_SENT状态
客户端在SYN_SENT状态中一旦收到了服务端发来的SYN_ACK 之后,转换为ESTABLISHED状态,这时便可以开始传送数据了,无论怎么传都是ESTABLISHED状态
而服务器端收到了对方的ACK,同样处于ESTABLISHED状态
数据传输结束之后
客户端从ESTABLEISHED状态,发起四次断开请求
客户端发起FIN请求,从而进入等待状态
服务端收到断开请求之后,便发起ACK请求
客户端收到服务端发来的ACK确认信息后,从而又发起FIN_2 请求
等待服务端发来的FIN请求之后,便确认
服务器端收到FIN并发送ACK之后,服务器端便处于CLOSE_WAIT便自己发送FIN,从而进入LAST ACK模式 ,
确认完后不能立刻断开,还需要等待一定的时间(大约240秒),确认报文是否传递给对方
于是转换为CLOSED
iptables中有一个扩张参数--status
此扩展可以追踪tcp udp icmp等各种状态
其能够使用某种内核数据结构保持此前曾经建立的连接状态时间的功能,称为连接追踪
内核参数文件路径为:
[root@test3~]# ls /proc/sys/net/netfilter/
[root@test3~]# cat /proc/sys/net/netfilter/nf_conntrack_udp_timeout
30
以此为例,在其30秒钟内,曾经建立过的udp连接,这些连接都可以被追踪到的,可以明确知道在这期间哪个客户端曾经访问过,只要基于请求的序列,能跟此前保持会话信息,即可查询
2.4显式扩展
在iptalbes中数据包和被跟踪连接的4种不同状态相关联,这四种状态分别是NEW、ESTABLISHED、RELATED及INVALID,除了本机产生的数据包由NAT表的OUTPUT链处理外,所有连接跟踪都是在NAT表的PREROUTING链中进行处理的,也就是说iptables在NAT表的PREROUTING链里从新计算所有数据包的状态。如果发送一个流的初始化数据包,状态就会在NAT表的OUTPUT链里被设置为NEW,当收到回应的数据包时,状态就会在NAT表的PREROUTING链里被设置为ESTABLISHED,如果第一个数据包不是本机生成的,那就回在NAT表PREROUTING链里被设置为NEW状态,所以所有状态的改变和计算都是在NAT表中的表链和OUTPUT链里完成的。
使用-m来指定其状态并赋予匹配规则,语法如下
-mstate --state 状态
NEW
ESTABLISHED
RELATED
INVALID
NEW:
NEW状态的数据包说明这个数据包是收到的第一个数据包。比如收到一个SYN数据包,它是连接的第一个数据包,就会匹配NEW状态。第一个包也可能不是SYN包,但它仍会被认为是NEW状态。
ESTABLISHED:
只要发送并接到应答,一个数据连接就从NEW变为ESTABLISHED,而且该状态会继续匹配这个连接后继数据包。
RELATED:
当一个连接和某个已处于ESTABLISHED状态的连接有关系时,就被认为是RELATED,也就是说,一个连接想要是RELATED的,首先要有个ESTABLISHED的连接,这个ESTABLISHED连接再产生一个主连接之外的连接,这个新的连接就是RELATED。
INVALID:
INVALID状态说明数据包不能被识别属于哪个连接或没有任何状态。
例:
对本机22端口做状态监测:
进来的请求状态为new,而出去的状态则为ESTABLISHED,如果自动连接别人 状态肯定为NEW,如果正常去响应别人那么状态肯定是ESTABLISHED
[root@test3~]# iptables -I INPUT -s 10.0.10.0/24 -d 10.0.10.62 -p tcp --dport 22 -m state--state NEW,ESTABLISHED -j ACCEPT
出口的响应都必须是ESTABLISHED
[root@test3~]# iptables -A OUTPUT -s 10.0.10.62 -d 10.0.10.0/24 -p tcp --dport 22 -m state--state ESTABLISHED -j ACCEPT
[root@test3~]# iptables -L -n
ChainINPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 10.0.10.0/24 10.0.10.62 tcp dpt:22 state NEW,ESTABLISHED
ChainFORWARD (policy DROP)
target prot opt source destination
ChainOUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 10.0.10.62 10.0.10.0/24 tcp dpt:22state ESTABLISHED
多端口规则匹配
使用参数-m multiport 可以指定15个以内的非连续端口,比如21-22,80
-mmulitport
--src-prots
--dst-ports
--prots
#对多端口进行匹配,只要匹配以下端口,则全部放行
[root@test3~]# iptables -A INPUT -s 10.0.10.0/24 -d10.0.10.62 -p tcp -m state --state NEW -m mulitport--destination-ports 21,22,80 -j ACCEPT
多IP匹配,指定匹配的IP地址范围:
-miprange
--src-range
--dst-range
指定匹配的连续ip段
[root@test3~]# iptables -A INPUT -s -m iprange --src-range 10.0.10.100-10.0.10.200
指定速率匹配
默认为每秒匹配3个报文,基于令牌桶算法
-mlimit
--limit #NUMBER,表示允许收集多少个空闲令牌
--limit-burst #RATE,允许放行多少个报文
比如:ssh一分钟之内只能建立20个链接,平均5秒一个,而一次性只能放行2个空闲令牌
--limit 20/min
--limit-burst 2
只有在大量空闲令牌存储的情况下,才可有limit-burst控制
例:控制NEW状态的请求
[root@test3~]# iptables -A INPUT -s 10.0.10.0/24 -d 10.0.10.62 -m state --state NEW -mlimit --limit 12/min --limit 12/min --limit-burst 2 -j ACCEPT
例2:每次只允许2个ping包进来
[root@test3~]# iptables -F
[root@test3~]# iptables -A INPUT -s 10.0.10.0/24 -d 10.0.10.62 -p icmp --icmp-type 8 -mlimit --limit 20/min --limit-burst 5 -j ACCEPT
新建立一终端,在其终端ping10.0.10.62可以看到效果,不再演示
2.5对应用层进行匹配
对应用层编码字符串做相似匹配,常用算法使用--alog来指定 ,一般来讲算法一般为bm和kmp
-msrting
--string ""
--algo {bm|kmp}
例:
·假如我们期望web站点页面中任何包含"hello"的字符串的页面,则禁止访问,其他则放行
·请求报文中不会包含hello,一般来讲只包含访问某个页面,那么请求内容无非包含了请求某个链接而已
·响应报文中会封装页面的内容信息,因此 会出现在响应报文中,而不是请求报文
启动httpd服务
[root@test3~]# /etc/init.d/httpd start
在web站点新建页面1.html,内容为"hello" , 2.html内容为"word"
[root@test3domian]# echo hello > 1.html
[root@test3domian]# echo word > 2.html
在iptables的允许放行规则前面加一条更严谨的禁止规则:
[root@test3domian]# iptables -A OUTPUT -s 10.0.10.62 -p tcp --sport 80 -m string --string"hello" --algo kmp -j REJECT
再次访问
[root@test3domian]# curl -dump http://10.0.10.62/2.html
word
[root@test3domian]# curl -dump http://10.0.10.62/1html
#请求已发出去但是一直没有反应,我们来看一下防火墙规则是否被匹配到
[root@test3domian]# iptables -L -nv
ChainINPUT (policy ACCEPT 255 packets, 30024 bytes)
pkts bytes target prot opt in out source destination
ChainFORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
ChainOUTPUT (policy ACCEPT 201 packets, 29406 bytes)
pkts bytes target prot opt in out source destination
35 11209 REJECT tcp -- * * 10.0.10.62 0.0.0.0/0 tcp spt:80STRING match "hello" ALGO name kmp TO 65535 reject-withicmp-port-unreachable
基于时间限定
-m time
#指定日期起止范围
--datestart
--datestop
#指定时间的起止范围
--timestart
--timestop
#指定星期x范围
--weekdays
#指定月份
--monthdays
3.基于iptables实现NAT功能
3.1基于SNAT功能的实现
考虑场景:为解决IP地址不足,所以用NAT功能来实现成本节约
SNAT:源地址转换(代理内部客户端访问外部网络)在POSTROUTING或OUTPUT链上来做规则限制
参数选项:
-j SNAT --to-source IP
-j MASQUERADE
DNAT :目标地址转换(将内部服务器公开至外部网络)需在PREROUTING做限制
参数选项:
-j DNAT --to-destination IP:prot
NAT不但可以转换目标地址,还可以映射目标端口
拓补图如下:
假设iptables为网关服务器,192.168.0.0为内网地址段 10.0.10.0 为外网地址段
规划:
服务器角色 |
服务器内网IP地址 |
iptables |
10.0.10.62 、 192.168.0.4 |
client |
10.0.10.60 |
web server |
192.168.0.110 |
下面来配置服务器:
webserver服务器配置如下:
[root@mode~]# /etc/init.d/httpd start
[root@modehtml]# echo 111 > test.html
#查看路由信息
[root@modehtml]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1
10.0.10.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
0.0.0.0 192.168.0.4 0.0.0.0 UG 0 0 0 eth1
0.0.0.0 192.168.0.1 0.0.0.0 UG 0 0 0 eth1
iptables服务器配置如下:
开启路由转发功能
[root@test3domian]# echo 1 > /proc/sys/net/ipv4/ip_forward
client配置如下:
#将eth1的网卡关闭,真正意义上断开连接
[root@test~]# ifdown eth1
#添加直连路由
[root@test~]# route add default gw 10.0.10.62
[root@test~]# route -n
KernelIP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.0.10.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0
0.0.0.0 10.0.10.62 0.0.0.0 UG 0 0 0 eth0
这时去ping192.168.0.0 段的地址是通的,如下所示
[root@test~]# ping 192.168.0.4
PING192.168.0.4 (192.168.0.4) 56(84) bytes of data.
64bytes from 192.168.0.4: icmp_seq=1 ttl=64 time=22.0 ms
64bytes from 192.168.0.4: icmp_seq=2 ttl=64 time=0.245 ms
查看是否可访问webserver的web服务
[root@test ~]# curl -dumphttp://192.168.0.110/test.html
111
返回web server上查看访问日志
[root@modelogs]# tail access_log
10.0.10.60- - [02/Feb/2014:20:33:27 +0800] "POST /test.htmlHTTP/1.1" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu)libcurl/7.19.7 NSS/3.13.6.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
#源地址为10.60 由此可见,由路由来实现两台主机的通信
如果想使用nat方式来实现任何来自10.0/24的网络 通过此台服务器想访问web其他主机,都将源地址改为iptables的ip地址
#凡是来自10.0.10.0网段的主机都将其转换为自己的ip地址
[root@test3domian]# iptables -t nat -A POSTROUTING-s 10.0.10.0/24 -j SNAT --to-source 192.168.0.4
返回client端再次访问web server,并查看日志
[root@mode logs]# tail access_log
10.0.10.60- - [02/Feb/2014:20:33:27 +0800] "POST /test.html HTTP/1.1" 200 4"-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7NSS/3.13.6.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
192.168.0.4- - [02/Feb/2014:20:37:13 +0800] "POST /test.htmlHTTP/1.1" 200 4 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu)libcurl/7.19.7 NSS/3.13.6.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"
由此可见,来源IP为代理服务器,因此它是回给192.168.0.4的 ,由192.168.0.4通过nat路由表再返回给client
查看规则
[root@test3domian]# iptables -t nat -L -n -v
ChainPREROUTING (policy ACCEPT 3 packets, 387 bytes)
pkts bytes target prot opt in out source destination
ChainPOSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
2 144 SNAT all -- * * 10.0.10.0/24 0.0.0.0/0 to:192.168.0.4
ChainOUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
将其状态全部放行
[root@test3domian]# iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
[root@test3domian]# iptables -A FORWARD -s10.0.10.0/24 -p tcp --dport 80 -m state --state NEW -j ACCEPT
再来测试:切换至Client
[root@test~]# curl -dump http://192.168.0.110/test.html
111
返回iptables服务器,查看规则匹配情况
[root@test3domian]# iptables -L -nv
ChainINPUT (policy ACCEPT 45 packets, 3241 bytes)
pkts bytes target prot opt in out source destination
ChainFORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
27 2964 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 stateESTABLISHED
3 180 ACCEPT tcp -- * * 10.0.10.0/24 0.0.0.0/0 tcp dpt:80state NEW
ChainOUTPUT (policy ACCEPT 31 packets, 4064 bytes)
pkts bytes target prot opt in out source destination
通过规则匹配可以看到,首先其会先发起三次握手第一次由第二条规则先匹配到,而后来由状态规则ESTABLISHED进行匹配
3.2定义DNAT的实现
如果构建大并发的环境时,NAT并不适用,一般来讲能够并发用户请求的场景来讲,在2-3W 已经非常庞大了,通常都是专业级硬件分发设备或应用来做分发,下面尝试着使client能够访问web服务器,但期望的是今后访问web服务器不是访问192.168.0.110而是iptables服务器10.0.10.62
因为是实验环境,所以清空所有规则
[root@test3~]# iptables -t nat -F
[root@test3~]# iptables -F
[root@test3~]# iptables -P FORWARD ACCEPT
我们期望网关10.0.10.62为用户访问目标,而不是192.168.0.110,但62上是没有web服务的,所以有人访问62的web服务必须将其转换到110上
所以要在iptables服务器上操作:
[root@test3~]# iptables -t nat -A PREROUTING -d 10.0.10.62 -p tcp --dport 80 -j DNAT--to-destination 192.168.0.110
在客户端测试:
[root@test~]# curl -dump http://10.0.10.62/test.html
111
如果将FORWARD链的规则改为DROP那么该如何来实现:
[root@test3~]# iptables -P FORWARD DROP
再次测试,果然无法访问
它可以实现地址转换,但是地址转换后的报文是无法再转发至内部主机中去,因为forward规则给挡住了
可以将已经建立过连接的请求全部放行,于是乎:
[root@test3~]# iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@test3 ~]# iptables -A FORWARD -d 192.168.0.110 -p tcp --dport 80 -m state--state NEW -j ACCEPT
#目标地址必须是内部web地址 因为forward链在路由之后才可知其是否要进行转发
#也就是意味着用户的请求到达PREROUTING的时候,目标的地址已经改过了,当用户的请求FORWARD之后目标地址已经是web地址
放行转发ssh服务:
我们想请求iptables的22端口则转发至web server端的22端口上去
[root@test3~]# iptables -t nat -A PREROUTING -d 10.0.10.62 -p tcp --dport 22 -j DNAT --to-destination 192.168.0.110
[root@test3~]# iptables -A FORWARD -d 192.168.0.110 -p tcp --dport 22 -m state --state NEW-j ACCEPT
进行登录
[root@test~]# ssh 10.0.10.62
由此可见,以后想登陆10.62则登陆不上去了(可以更改为非22端口等,不再说明了哦)
将80端口请求转发至web端8080端口
更改apache服务的监听端口:
Listen8080
切换至iptables服务端添加规则:
[root@test3~]# iptables -t nat -A PREROUTING -d 10.0.10.62 -p tcp --dport 80 -j DNAT--to-destination 192.168.0.110:8080
[root@test3~]# iptables -t nat -L -nv
Chain PREROUTING (policy ACCEPT 2 packets, 458 bytes)
pkts bytes target prot opt in out source destination
6 360 DNAT tcp -- * * 0.0.0.0/0 10.0.10.62 tcp dpt:80to:192.168.0.110:8080
Chain POSTROUTING (policy ACCEPT 9 packets, 564 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 3 packets, 204 bytes)
pkts bytes target prot opt in out source destination
在端口映射环境下如何放行web服务:
在做地址转发的时候必须以转换之后的端口和地址为目标端口和目标ip地址
[root@test3~]# iptables -P FORWARD DROP
[root@test3 ~]# iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
[root@test3 ~]# iptables -A FORWARD -d 192.168.0.110 -p tcp --dport 8080 -mstate --state NEW -j ACCEPT
假设在此服务器上还有mysql服务,假设mysql在内网工作在正常服务端口,但告知外面工作在6789端口上,那么
进入mysql并授权
mysql>grant all on *.* to 'root'@'%' identified by '123456';
mysql>flush privileges;
在iptables服务器上添加规则如下
[root@test3 ~]# iptables -t nat -A PREROUTING-d 10.0.10.62 -p tcp --dport 6789 -j DNAT --to-destination 192.168.0.110:3306
[root@test3~]# iptables -A FORWARD -d 192.168.0.110 -p tcp --dport 3306 -m state --stateNEW -j ACCEPT
[root@test~]# mysql -uroot -h10.0.10.62 -P6789 -p
切换至client端进行测试
[root@test~]# mysql -uroot -h10.0.10.62 -P6789 -p
4.ip_conntrack 功能
其扩展模块路径为
/proc/net/nf_conntrack
/proc/sys/net/nf_conntrack_max
不同版本的值和相关信息未必一致
[root@test3~]# cat /proc/sys/net/nf_conntrack_max
31860
比起红帽5的值已经大的太多了
#这些超时时间非常长,如下所示:
[root@test3 ~]# cat/proc/net/nf_conntrack
ipv4 2 tcp 6 431999ESTABLISHED src=10.0.10.62 dst=10.0.10.1sport=22 dport=59448 src=10.0.10.1 dst=10.0.10.62 sport=59448 dport=22[ASSURED] mark=0 secmark=0 use=2
#可以在某些时候将值尽量调低,如果不尽量追踪过长时间
[root@test3~]# cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
432000 #5天时间
如果没有特殊需求的话,将其值调低,这样可以保证被追踪的连接尽早被记录的文件中清除出去,已腾出空间供其他被追踪使用
既然追踪连接功能有限制而且对性能有很大的影响为何还要开启呢?
启动其功能的原因在于 在某些场景中必须追踪状态,才能达到目的,如果在并发连接非常大的场景下启用连接追踪是不明智的
因此需自己判断好应用场景,不得不启用,连接数也非常大,方法如下:
(1).调小nf_conntrack_tcp_timeout_established
(2).调大 /proc/sys/net/nf_conntrack_max #需要一定的内存容量,只要空间充足即可
扩展模块connlimit:
connlimit 连接数限制,一般可以实现控制某源ip地址发起来某连接个数的
--connlimit-above[number] #连接数的上限,如果某个连接数的个数超过为某个值之后(高于),通常用取反的方法来放行:
#iptables-A INPUT -s 10.0.10.0/24 -p tcp --dport 80 -m connlimit ! --connlimit-above 5-j ACCEPT
hashlimit,limit #能够分析每个ip地址的速率
5.recent模块
利用iptables的recent模块来抵御DOS攻击: 22,建立一个列表,保存有所有访问过指定的服务的客户端IP 对本机ssh: 远程连接
(1).利用connlimit模块将单IP的并发设置为3;会误杀使用NAT上网的用户,可以根据实际情况增大该值;
iptables-I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP
第二句是记录访问tcp 22端口的新连接,记录名称为SSH --set 记录数据包的来源IP,如果IP已经存在将更新已经存在的条目
(2).利用recent和state模块限制单IP在300s内只能与本机建立2个新连接。被限制五分钟后即可恢复访问
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent--set --name SSH
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent--update --seconds 300 --hitcount 3 --name SSH -j LOG --log-prefix "SSHAttach: "
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent--update --seconds 300 --hitcount 3 --name SSH -j DROP
第三句是指SSH记录中的IP,300s内发起超过3次连接则拒绝此IP的连接。
--update 是指每次建立连接都更新列表;
--seconds必须与--rcheck或者--update同时使用
--hitcount必须与--rcheck或者--update同时使用
(3).iptables的记录:/proc/net/xt_recent/SSH
也可以使用下面的这句记录日志:
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent--update --name SSH --second 300 --hitcount 3 -j LOG --log-prefix "SSHAttack"
iptables [-t 表名] 选项 [链名] [条件] [-j 控制类型] 参数
-P 设置默认策略:iptables -P INPUT (DROP|ACCEPT)
-F 清空规则链
-L 查看规则链
-A 在规则链的末尾加入新规则
-I num 在规则链的头部加入新规则
-D num 删除某一条规则
-s 匹配来源地址IP/MASK,加叹号"!"表示除这个IP外。
-d 匹配目标地址
-i 网卡名称 匹配从这块网卡流入的数据
-o 网卡名称 匹配从这块网卡流出的数据
-p 匹配协议,如tcp,udp,icmp
--dport num 匹配目标端口号
--sport num 匹配来源端口号
示例
1. 删除已有规则
在开始创建iptables规则之前,你也许需要删除已有规则。
命令如下:
iptables -F
(or)
iptables –flush
2.设置链的默认策略
链的默认政策设置为”ACCEPT”(接受),若要将INPUT,FORWARD,OUTPUT链设置成”DROP”(拒绝),命令如下:
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
当INPUT链和OUTPUT链都设置成DROP时,对于每一个防火墙规则,我们都应该定义两个规则。例如:一个传入另一个传出。在下面所有的例子中,由于我们已将DROP设置成INPUT链和OUTPUT链的默认策略,每种情况我们都将制定两条规则。当然,如果你相信你的内部用户,则可以省略上面的最后一行。例如:默认不丢弃所有出站的数据包。在这种情况下,对于每一个防火墙规则要求,你只需要制定一个规则——只对进站的数据包制定规则。
3. 阻止指定IP地址
例:丢弃来自IP地址x.x.x.x的包
iptables -A INPUT -s x.x.x.x -j DROP
注:当你在log里发现来自某ip地址的异常记录,可以通过此命令暂时阻止该地址的访问以做更深入分析
例:阻止来自IP地址x.x.x.x eth0 tcp的包
iptables -A INPUT -i eth0 -s x.x.x.x -j DROP
iptables -A INPUT -i eth0 -p tcp -s x.x.x.x -j DROP
4. 允许所有SSH的连接请求
例:允许所有来自外部的SSH连接请求,即只允许进入eth0接口,并且目标端口为22的数据包
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
5. 仅允许来自指定网络的SSH连接请求
例:仅允许来自于192.168.100.0/24域的用户的ssh连接请求
iptables -A INPUT -i eth0 -p tcp -s 192.168.100.0/24 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
6.允许http和https的连接请求
例:允许所有来自web - http的连接请求
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT
例:允许所有来自web - https的连接请求
iptables -A INPUT -i eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
7. 使用multiport 将多个规则结合在一起
允许多个端口从外界连入,除了为每个端口都写一条独立的规则外,我们可以用multiport将其组合成一条规则。如下所示: 例:允许所有ssh,http,https的流量访问
iptables -A INPUT -i eth0 -p tcp -m multiport --dports 22,80,443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -m multiport --sports 22,80,443 -m state --state ESTABLISHED -j ACCEPT
8. 允许从本地发起的SSH
iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
请注意,这与允许ssh连入的规则略有不同。本例在OUTPUT链上,我们允许NEW和ESTABLISHED状态。在INPUT链上,我们只允许ESTABLISHED状态。ssh连入的规则与之相反。
9. 仅允许从本地发起到一个指定的网络域的SSH请求
例:仅允许从内部连接到网域192.168.100.0/24
iptables -A OUTPUT -o eth0 -p tcp -d 192.168.100.0/24 --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
10. 允许从本地发起的HTTPS连接请求
下面的规则允许输出安全的网络流量。如果你想允许用户访问互联网,这是非常有必要的。在服务器上,这些规则能让你使用wget从外部下载一些文件
iptables -A OUTPUT -o eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -i eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
注:对于HTTP web流量的外联请求,只需要将上述命令中的端口从443改成80即可。
11. 负载平衡传入的网络流量
使用iptables可以实现传入web流量的负载均衡,我们可以传入web流量负载平衡使用iptables防火墙规则。 例:使用iptables nth将HTTPS流量负载平衡至三个不同的ip地址。
iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 0 -j DNAT --to-destination 192.168.1.101:443
iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 1 -j DNAT --to-destination 192.168.1.102:443
iptables -A PREROUTING -i eth0 -p tcp --dport 443 -m state --state NEW -m nth --counter 0 --every 3 --packet 2 -j DNAT --to-destination 192.168.1.103:443
12. 允许外部主机ping内部主机
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT
13. 允许内部主机ping外部主机
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
14. 允许回环访问
例:在服务器上允许127.0.0.1回环访问。
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
15. 允许内部网络域外部网络的通信
防火墙服务器上的其中一个网卡连接到外部,另一个网卡连接到内部服务器,使用以下规则允许内部网络与外部网络的通信。此例中,eth1连接到外部网络(互联网),eth0连接到内部网络(例如:192.168.1.x)。
iptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
16. 允许出站的DNS连接
iptables -A OUTPUT -p udp -o eth0 --dport 53 -j ACCEPT
iptables -A INPUT -p udp -i eth0 --sport 53 -j ACCEPT
17. 允许NIS连接
如果你使用NIS管理用户帐户,你需要允许NIS连接。如果你不允许NIS相关的ypbind连接请求,即使SSH连接请求已被允许,用户仍然无法登录。NIS的端口是动态的,先使用命令rpcinfo –p来知道端口号,此例中为853和850端口。 rpcinfo -p | grep ypbind 例:允许来自111端口以及ypbind使用端口的连接请求
iptables -A INPUT -p tcp --dport 111 -j ACCEPT
iptables -A INPUT -p udp --dport 111 -j ACCEPT
iptables -A INPUT -p tcp --dport 853 -j ACCEPT
iptables -A INPUT -p udp --dport 853 -j ACCEPT
iptables -A INPUT -p tcp --dport 850 -j ACCEPT
iptables -A INPUT -p udp --dport 850 -j ACCEPT
注:当你重启ypbind之后端口将不同,上述命令将无效。有两种解决方案:1)使用你NIS的静态IP 2)编写shell脚本通过“rpcinfo - p”命令自动获取动态端口号,并在上述iptables规则中使用。
18. 允许来自指定网络的rsync连接请求
例:允许来自网络192.168.101.0/24的rsync连接请求
iptables -A INPUT -i eth0 -p tcp -s 192.168.101.0/24 --dport 873 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 873 -m state --state ESTABLISHED -j ACCEPT
19. 允许来自指定网络的MySQL连接请求
很多情况下,MySQL数据库与web服务跑在同一台服务器上。有时候我们仅希望DBA和开发人员从内部网络(192.168.100.0/24)直接登录数据库,可尝试以下命令:
iptables -A INPUT -i eth0 -p tcp -s 192.168.100.0/24 --dport 3306 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 3306 -m state --state ESTABLISHED -j ACCEPT
20. 允许Sendmail, Postfix邮件服务
Sendmail和postfix都使用了25端口,因此我们只需要允许来自25端口的连接请求即可。
iptables -A INPUT -i eth0 -p tcp --dport 25 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 25 -m state --state ESTABLISHED -j ACCEPT
21. 允许IMAP和IMAPS
例:允许IMAP/IMAP2流量,端口为143
iptables -A INPUT -i eth0 -p tcp --dport 143 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 143 -m state --state ESTABLISHED -j ACCEPT
例:允许IMAPS流量,端口为993
iptables -A INPUT -i eth0 -p tcp --dport 993 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 993 -m state --state ESTABLISHED -j ACCEPT
22. 允许POP3和POP3S
例:允许POP3访问
iptables -A INPUT -i eth0 -p tcp --dport 110 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 110 -m state --state ESTABLISHED -j ACCEPT
例:允许POP3S访问
iptables -A INPUT -i eth0 -p tcp --dport 995 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 995 -m state --state ESTABLISHED -j ACCEPT
23. 防止DoS攻击
iptables -A INPUT -p tcp --dport 80 -m limit --limit 25/minute --limit-burst 100 -j ACCEPT
上述例子中:
-m limit: 启用limit扩展
–limit 25/minute: 允许最多每分钟25个连接(根据需求更改)。
–limit-burst 100: 只有当连接达到limit-burst水平(此例为100)时才启用上述limit/minute限制。
24. 端口转发
例:将来自422端口的流量全部转到22端口。 这意味着我们既能通过422端口又能通过22端口进行ssh连接。启用DNAT转发。
iptables -t nat -A PREROUTING -p tcp -d 192.168.102.37 --dport 422 -j DNAT --to 192.168.102.37:22
除此之外,还需要允许连接到422端口的请求
iptables -A INPUT -i eth0 -p tcp --dport 422 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 422 -m state --state ESTABLISHED -j ACCEPT
25. 记录丢弃的数据表
第一步:新建名为LOGGING的链
iptables -N LOGGING
第二步:将所有来自INPUT链中的数据包跳转到LOGGING链中
iptables -A INPUT -j LOGGING
第三步:为这些包自定义个前缀,命名为”IPTables Packet Dropped”
iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables Packet Dropped: " --log-level 7
第四步:丢弃这些数据包
iptables -A LOGGING -j DROP
nat表需要的三个链:
1.PREROUTING:可以在这里定义进行目的NAT的规则,因为路由器进行路由时只检查数据包的目的ip地址,所以为了使数据包得以正确路由,我们必须在路由之前就进行目的NAT;
2.POSTROUTING:可以在这里定义进行源NAT的规则,系统在决定了数据包的路由以后在执行该链中的规则。
3.OUTPUT:定义对本地产生的数据包的目的NAT规则。
需要用到的几个动作选项:(真实环境中用大写)
redirect | 将数据包重定向到另一台主机的某个端口,通常用实现透明代理和对外开放内网某些服务。 | ||||
snat | 源地址转换,改变数据包的源地址 | ||||
dnat | 目的地址转换,改变数据包的目的地址 | ||||
masquerade | IP伪装,只适用于ADSL等动态拨号上网的IP伪装,如果主机IP是静态分配的,就用snat |
PRERROUTING:DNAT 、REDIRECT (路由之前)只支持-i,不支持-o。在作出路由之前,对目的地址进行修改
POSTROUTING:SNAT、MASQUERADE (路由之后)只支持-o,不支持-i。在作出路由之后,对源地址进行修改
OUTPUT:DNAT 、REDIRECT (本机)DNAT和REDIRECT规则用来处理来自NAT主机本身生成的出站数据包.
一、打开内核的路由功能。
要实现nat,要将文件/proc/sys/net/ipv4/ip_forward内的值改为1,(默认是0)。
二、nat不同动作的配置
1)MASQUERADE:是动态分配ip时用的IP伪装:在nat表的POSTROUTING链加入一条规则:所有从ppp0口送出的包会被伪装(MASQUERADE)
[root@localhost]# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
要想系统启动时自动实现nat,在/etc/rc.d/rc.local文件的末尾添加
[root@localhost]# echo "1">/proc/sys/net/ipv4/ip_forward
[root@localhost]# /sbin/iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
2) SNAT:一般正常共享上网都用的这个。
所有从eth0(外网卡)出来的数据包的源地址改成61.99.28.1(这里指定了一个网段,一般可以不指定)
[root@localhost]# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to 61.99.28.1
3)DNAT:目的nat 做智能DNS时会用到
智能DNS:就是客户端在dns项里无论输入任何ip,都会给他定向到服务器指定的一个dnsip上去。
在路由之前所有从eth0(内网卡)进入的目的端口为53的数据包,都发送到1.2.3.4这台服务器解析。
[root@localhost]# iptables -t nat -I PREROUTING -i eth0 -p udp --dport 53 -j DNAT --to-destination 1.2.3.4:53
[root@localhost]# iptables -t nat -I PREROUTING -i eth0 -p tcp --dport 53 -j DNAT --to-destination 1.2.3.4:53
4)REDIRECT:重定向,这个在squid透明代理时肯定要用到它
所有从eth1进入的请求80和82端口的数据,被转发到80端口,由squid处理。
[root@localhost]# iptables -t nat -A PREROUTING - -i eth1 -p tcp -m multiport --dports 80,82 -j REDIRECT --to-ports 80