iptables可以实现主机防火墙,也可以实现网络防火墙,下面介绍主机防火墙。
语法:[!]-s --src --source IP|Netaddr
如:本机与任何主机通信的tcp协议的报文都放行
iptables -t filter -A OUTPUT -s 10.0.0.100 -p tcp -j ACCEPT
语法:[!] -d --dst --destination IP|Netaddr
如:访问本机的tcp全部放行
iptables -t filter -A INPUT -d 10.0.0.100 -p tcp -j ACCEPT
现在将默认规则改为拒绝,测试ping操作,已经无法ping通本机了,因为默认规则为DROP
iptables-P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
语法:[!] -p --protocol {tcp|udp|icmp} 这会检查IP首部的protocols所标识的协议
如:允许ping操作,任何目的地址为本机的icmp报文都放行,任何源地址为本机的icmp报文都放行。
iptables -A INPUT -d 10.0.0.100 -p icmp -j ACCEPT #放行进入本机的icmp报文
iptables -A OUTPUT -s 10.0.0.100 -p icmp -j ACCEPT #放行本机发出的icmp报文
语法:-i --in-interface <接口> 检查报文的流入接口,仅在:PREROUTING,INPUT,FORWARD链上
-o --out-interface <接口> 检查报文的流出接口,仅在:OUTPUT,POSTROUTING链上
如:放行由ens33网卡进入本机的报文
iptables -A INPUT -d 10.0.0.100 -i ens33 -j ACCEPT
如:放行由ens33网卡流出本机的报文
iptables -A OUTPUT -s 10.0.0.100 -o ens33 -j ACCEPT
隐式扩展:对于使用已经使用-p指明协议进行的扩展,可省略-m选项。
帮助手册:可以查询“man iptables-extensions”
语法:-m tcp --dport|--sport <ports>端口匹配检查,同样适用udp。
--dport PORT目标端口,可以使用冒号:分割多个连续的端口
--sport PORT源端口,可以使用冒号:分割多个连续的端口
如:仅放行对本机ssh服务的访问和流出
iptables-I INPUT -d10.0.0.100-ptcp--dport22 -j ACCEPT #放行进入本机目标地址为本机tcp22端口的报文
iptables -I OUTPUT -s 10.0.0.100 -p tcp --sport 22 -j ACCEPT #放行本机发出的源地址为本机tcp22端口的报文
如:仅放行对本机http服务的访问和流出
iptables -A INPUT -d 10.0.0.100 -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -s 10.0.0.100 -p tcp --sport 80 -j ACCEPT
放行DNS服务器的递归和迭代查询
iptables -A INPUT -d 172.16.1.100 -p udp --dport 53 -j ACCEPT #允许接收客户端递归查询
iptables -A OUTPUT -s 172.16.1.100 -p udp --sport 53 -j ACCEPT #允许本机发出递归查询响应报文
iptables -A OUTPUT -s 172.16.1.100 -p udp --dport 53 -j ACCEPT #允许发出迭代查询
iptables -A INPUT -d 172.16.1.100 -p udp --sport 53 -j ACCEPT #允许接收响应迭代查询报文
DNS主服务器允许区域传送
iptables -A INPUT -d 172.16.1.100 -p tcp --dport 53 -j ACCEPT #允许接收主机请求区域传送请求
iptables -A OUTPUT -s 172.16.1.100 -p tcp --sport 53 -j ACCEPT #允许本机发出区域传送响应报文
DNS从服务器允许区域传送
iptables -A OUTPUT -s 172.16.1.100 -p tcp --dport 53 -j ACCEPT #允许发出区域传送请求
iptables -A INPUT -d 172.16.1.100 -p tcp --sport 53 -j ACCEPT #允许接收区域传送响应报文
语法:-m tcp --tcp-flags list1 list2可检查:SYN ACK FIN RST PSH URG
在list2中列出list1内必须为1的标志位,list2没有列出的则list1必须为0;list1中没有指明的标志位不做检查。
例如:--tcp-flags SYN,ACK,FIN,RST SYN表示检查SYN,ACK,FIN,RST标志位,其中SYN必须为1,其它必须为0,意思是匹配建立TCP连接时的第一次请求。可以简写为--syn
语法:-m icmp --icmp-type <icmp报文类型> icmp报文类型以以数字表示,0表示响应报文,8表示请求报文
如:自己可以ping别人,别人不能ping自己
iptables-A OUTPUT -s10.0.0.100 -p icmp --icmp-type 8 -j ACCEPT #本机发出的icmp的请求报文放行
iptables -A INPUT -d 10.0.0.100 -p icmp --icmp-type 0 -j ACCEPT #进入本机的icmp的会显报文放行
显示扩展:必须使用-m选项指定的扩展使用的模块,
显示扩展模块:rpm -ql iptables |grep "[[:lower:]]+\\.so$"
帮助手册:可以查询“man iptables-extensions”
语法:-m multiport [!] --source-ports,--sports port[,port|,port:port] 匹配多个源端口
[!] --destination-ports,--dports port[,port|,port:port] 匹配多个目标端口
[!] --ports port[,port|,port:port] 同时匹配源端口和目标端口
如:一条规则放行22和80端口
iptables -I INPUT -d 10.0.0.100 -p tcp -m multiport --dports 22,80 -j ACCEPT
iptables -I OUTPUT -s 10.0.0.100 -p tcp -m multiport --sports 22,80 -j ACCEPT
语法:-miprange匹配地址范围扩展检查,指明连续的ip地址范围。一般不能扩展为整个网络。
[!] --src-range from[-to] 连续的源地址范围
[!] --dst-range from[-to] 连续的目标地址范围
如:仅放行来自10.0.0.100-10.0.0.253的IP访问22和80端口
iptables-I INPUT -d 10.0.0.100 -miprange--src-range10.0.0.100-10.0.0.253-ptcp-mmultiport--dports22,80 -j ACCEPT
iptables -I OUTPUT -s 10.0.0.100 -m iprange --dst-range 10.0.0.100-10.0.0.253 -p tcp -m multiport --sports 22,80 -j ACCEPT
1.3.3 MAC地址匹配检查
语法:-m mac --mac-source
如:禁止转发来自MAC地址为00:0C:29:27:55:3F的和主机的数据包
iptables -A FORWARD -m mac --mac-source 00:0c:29:27:55:3F -j DROP
语法:-mstring匹配字符串检查,检查报文中出现的字符串
--algo {bm|kmp} 指定字符串检查算法(必须指定),可使用:bm、kmp
[!] --string pattern 字符串匹配
[!] --hex-string pattern 十六进制格式编码字符匹配(比字符串效率高)
如:如果响应报文中包含movie,则丢弃
iptables-I OUTPUT -s10.0.0.100 -p tcp --sport 80 -mstring--algo bm --string‘movie‘ -j DROP
语法:-m time 匹配报文的到达的时间范围,如果在内则匹配成功,注意:CST和UTC时间之间换算
--datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]] 匹配起始日期,可以只给定日期,剩下会以0填充,格式:年月日T十分秒
--datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]] 匹配停止日期,可以只给定日期,剩下会以0填充,格式:年月日T十分秒
--timestart hh:mm[:ss] 只匹配起始时间
--timestop hh:mm[:ss] 只匹配结束时间
[!] --monthdays day[,day...] 每月仅在这些天进行检查
[!] --weekdays day[,day...] 每月仅在周几进行检查
如:web站点在每周日,凌晨1点-5点不允许访问http服务。
iptables -I INPUT -d 10.0.0.100 -p tcp --dport 80 -m time --weekdays 7 --timestart 01:00 --timestop 05:00 -j DROP
语法:-m connlimit 匹配每个IP并发连接数限制,根据客户端单个IP,进行并发访问进行限制
--connlimit-above N 超过N以后,则执行规则动作,一般动作为拒绝。默认策略为允许情况下使用。
--connlimit-upto n 小于N以后,则执行规则动作,一般动作为放行。默认策略为拒绝的情况下使用。
如:10.0.0.253对本机的22端口访问大于2时候则拒绝。
iptables -I INPUT -s 10.0.0.253 -p tcp --dport 22 -m connlimit --connlimit-above 2 -j REJECT
语法:-m limit 根据令牌桶算法,匹配收发报文的速率
--limit rate[/second|/minute|/hour|/day] 到达峰值后的速率,必选参数
--limit-burst number 定义峰值,一次性放行的报文数,可选参数
如:当别人ping本机时,开始不限制速率响应4个包,到达峰值后,每两秒响应一个包。
iptables-A INPUT -d10.0.0.100-picmp--icmp-type8-mlimit--limit-burst4--limit30/minute-j ACCEPT
iptables -A OUTPUT -s10.0.0.100-picmp --icmp-type 0 -j ACCEPT
语法:-mstate根据连接追踪机制检查连接的状态,与TCP有限状态机无关。
--state匹配连接状态,连接状态有以下几种。
注意:iptables的连接追踪功能会占用系统资源,追踪表满了新的请求会被拒绝,所以避免在繁忙的主机上启用。
连接状态 |
含义 |
NEW |
新发出的请求,连接追踪记录中不存在的连接,识别为第一次发来的请求 |
ESTABLISHED |
NEW状态之后,连接追踪记录中没有失效的的连接 |
RELATED |
相关的连接,例如:FTP的由命令连接建立起来的传输连接。 |
INVALID |
无法识别的连接,不是NEW,也不是ESTABLISHED的连接。 |
关于内核对连接追踪的设定相关文件 |
|
/proc/net/nf_conntrack |
已经追踪到的连接记录,能够记录多少条,由/proc/sys/net/nf_conntrack_max来决定 |
/proc/sys/net/nf_conntrack_max |
调整连接追踪功能所能容纳的最大连接数量,在非常繁忙的服务器上需要调整。 |
/proc/sys/net/netfilter/* |
每种连接可追踪的时长 |
如果连接追踪表满造成连接被拒绝,可以调整下面参数 |
|
加大连接追踪值 /proc/sys/net/nf_conntrack_max 修改为393216 /proc/sys/net/netfilter/nf_conntrack_max 降低/proc/sys/net/netfilter/目录中的追踪超时时间 nf_conntrack_tcp_timeout_established = 300 nf_conntrack_tcp_timeout_time_wait = 120 nf_conntrack_tcp_timeout_close_wait = 60 nf_conntrack_tcp_timeout_fin_wait = 120 |
如:主机只开放了22,80端口,我们只需要让这两个端口响应报文,而不能发起连接,这样能防止反弹式木马。
iptables -I INPUT -d10.0.0.100-p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT #放行22端口的新连接和已建立的连接进入
iptables -I INPUT -d 10.0.0.100 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT #放行80端口的新连接和已建立的连接进入
iptables -I OUTPUT -s 10.0.0.100 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT #放行22端口已建立的连接发出
iptables -I OUTPUT -s 10.0.0.100 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT #放行80端口已建立的连接发出
iptables-I INPUT -d 10.0.0.100 -p icmp --icmp-type 8 -mstate --state NEW,ESTABLISHED -j ACCEPT #放行icmp协议新连接和已建立连接进入
iptables-I OUTPUT -s10.0.0.100-picmp--icmp-type0-mstate--state ESTABLISHED -j ACCEPT #放行icmp协议已建立连接发出
对以上规则进行语句优化:
iptables -I INPUT -m state --state ESTABLISHED -j ACCEPT #直接放行状态为已连接的连接
iptables -I INPUT -d 10.0.0.100 -p tcp -m multiport --dports 22,80 -m state --state NEW -j ACCEPT #允许新连接进入
iptables -I INPUT -d 10.0.0.100 -p icmp --icmp-type 8 -m state --state NEW -j ACCEPT #允许icmp的新连接进入
iptables -I OUTPUT -m state --state ESTABLISHED -j ACCEPT #只允许连接状态为已连接的发出
如:基于上面命令增加开放被动模式下的ftp服务
1、装载FTP追踪时的专用模块
modprobenf_conntrack_ftp
2、放行命令连接:NEW,ESTABLISHED
iptables -I INPUT -d 10.0.0.100 -p tcp -m multiport --dports 21,22,80 -m state --state NEW -j ACCEPT
3、放行数据连接:RELATED,ESTABLISHED
iptables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
4、放行响应报文
iptables -I OUTPUT -m state --state ESTABLISHED -j ACCEPT
node1和node2处于不同的网络内,通过node3作为网络防火墙转发报文。
主机名 |
所处网络 |
网卡 |
IP地址 |
网络设定 |
运行服务 |
node1 |
内网 |
ens34 |
172.16.1.201/24 |
route add -net 10.0.0.0/24 gw 172.16.1.203 |
web,tfp,samba |
node2 |
外网 |
ens33 |
10.0.0.202/24 |
route add -net 172.16.1.0/24 gw 10.0.0.203 |
|
node3 |
网关 |
ens33、ens34 |
10.0.0.203、172.16.1.203 |
echo 1 >/proc/sys/net/ipv4/ip_forward |
iptables |
将FORWARD链默认规则修改为DROP
iptables-P FORWARD DROP
iptables-A FORWARD -d172.16.1.201-ptcp-mmultuiport--dports80-j ACCEPT
iptables -A FORWARD -s172.16.1.201 -p tcp -mmultuiport --sports 80 -j ACCEPT
1.4.3 内网主机可以响应外网主机请求,但不允许内网主机上外网
iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
iptables -A FORWARD -d172.16.1.201 -p tcp -m multiport --dports 22,80 -m state --state NEW -j ACCEPT
modprobe nf_conntrack_ftp
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -d 172.16.1.201 -p tcp -m multiport --dports 21,22,80 -m state --state NEW -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED -j ACCEPT
iptables -A FORWARD -d 172.16.1.201 -p tcp -m multiport --dports 137,445 -m state --state NEW -j ACCEPT
iptables -A FORWARD -d 172.16.1.201 -p udp --dport 137:138 -m state --state NEW -j ACCEPT
第2章 NAT表网络地址转换
2.1 NAT的简介
路由:仅仅是对请求进行转发,而不对报文进行任何修改。
NAT:转发的同时,对请求报文的源IP,当响应报文到达时,通过查找NAT表,对报文的目标IP进行修改。
SNAT:修改请求报文的源地址;DNAT:修改请求报文的目标地址;PNAT:端口转换
2.2 实验环境
node1和node2处于不同的网络内,通过node3作为网络防火墙转发报文。
主机名 |
所处网络 |
网卡 |
IP地址 |
网络设定 |
运行服务 |
node1 |
内网 |
ens34 |
172.16.1.201/24 |
route add -net 10.0.0.0/24 gw 172.16.1.203 |
web,tfp,samba |
node2 |
外网 |
ens33 |
10.0.0.202/24 |
route add -net 172.16.1.0/24 gw 10.0.0.203 |
web |
node3 |
网关 |
ens33、ens34 |
10.0.0.203、172.16.1.203 |
echo 1 >/proc/sys/net/ipv4/ip_forward |
iptables |
删除node2主机上路由表,并且在node2上安装web服务
route del -net 172.16.1.0/24 gw 10.0.0.203
此时在node1将无法访问node2,因为node2的响应报文无法返回给node1。
2.3 SNAT源地址转换
可以让内网主机访问互联网,比如,多个PC机使用iptables共享上网,每个PC机都配置了内网IP,PC机访问外部网络的时候,iptables将数据包的报头中的源地址替换成iptables服务器的外部ip。当外部网络的服务器比如网站web服务器接到访问请求的时候,他的日志记录下来的是路由器的ip地址,而不是PC机的内网ip。这是因为,这个服务器收到的数据包的报头里边的“源地址”,已经被替换了。所以叫做SNAT,基于源地址的地址转换,SNAT的地址可以是多个。
? 原理
Client(内网) |
Nat Getway |
Server(外网) |
发送请求报文给Server 报文结构为:CIP--SIP |
收到请求报文,发现地址为公网地址,需要修改源地址 PREROUTING OUTPUT POSTROUTING 在此处进行SNAT以后报文结构为:NIP--SIP 收到来自外网响应报文,通过查找NAT表,将目标NIP改CIP,这一步由NAT自行完成。 |
收到请求报文 报文结构为:NIP--SIP 响应报文结构:SIP--NIP |
语法:-j SNAT --to-source [ipaddr[-ipaddr]][:port[-port]]
示例:iptables -t nat -A POSTOUTING -s <本地网络> ! -d <本地网络> -j SNAT --to-source <NAT服务器外部IP>
如:现在需要处于内网的node1访问处于外网的node2,所以需要在node3上进行SNAT地址转换
iptables-tnat -A POSTROUTING -s172.16.1.0/24! -d 172.16.1.0/24 -j SNAT --to-source 10.0.0.203
当报文经过node3转发时,将报文的源地址修改为10.0.0.203,此时node1可以访问node2的web服务了
2.4 MASQUERADE地址伪装
假如当前NAT-Server用的是ADSL动态拨号方式访问互联网,那么每次拨号,出口IP都会改变, 这个时候如果按照SNAT的方式来配置iptables就会出现问题了。因为每次拨号后,服务器地址都会变化,而iptables规则SNAT是不会随着自动变化的,每次地址变化后都必须手工修改一次iptables,把规则里边的固定IP改成新的IP。这样是非常不好用的。MASQUERADE就是针对这种场景而设计的,他的作用是,从服务器的网卡上,自动获取当前ip地址来做NAT。
iptables -t nat -A POSTROUTING -s 172.16.1.0/24 ! -d 172.16.1.0/24 -j MASQUERADE
2.5 DNAT目标地址转换(端口映射)
DNAT是用来做目的网络地址转换的,就是重写包的目的IP地址。如果一个包被匹配了,那么和它属于同一个流的所有的包都会被自动转换,然后就可以被路由到正确的主机或网络。
比如,你的Web服务器在LAN内部,而且没有可在Internet上使用的真实IP地址,那就可以使用这个DNAT让iptables把所有到它自己80端口的包转发给LAN内部真正的Web服务器。目的地址也可以是一个范围,这样的话,DNAT会为每次请求随机分配一个机器,这样我们可以用这个DNAT做负载平衡。
? 原理
Client(外网) |
Nat Getway |
Server(内网) |
发送报文给Nat Getway 报文结构为:CIP--NIP |
收到报文,但是本机不真实提供服务,所以在进入本机前修改目标地址为内网的Server PREROUTING 由于本机是代理内网主机,所以在此处进行DNAT以后报文结构为:CIP--SIP OUTPUT POSTROUTING 收到来自内网的响应报文,直接基于IP协议路由给CIP |
收到请求报文 报文结构为:SIP--CIP 响应报文结构:SIP--CIP |
语法:--to-destination [ipaddr[-ipaddr]][:port[-port]]
示例:
iptables -t nat -A PREROUTING -d <外部IP> -p tcp --dport <外部端口> -j --to-destination <内部IP加端口>
如:现需要处于外网的node2访问处于内网的node1,所以需要node3代理node1的80端口,即端口映射
iptables-tnat -A PREROUTING -d 10.0.0.203 -p tcp --dport 80 -j DNAT --to-destination 172.16.1.201:80
当报文到达node3的80端口,则将报文的目标地址转换为node1,此时node2访问node3的web服务就相当与访问了node1。
文章写的不错?请扫下面作者的讨饭专用码,鼓励作者继续分享