您的位置:首页 > 运维架构 > Linux

Linux的iptables的基本应用

2016-04-29 19:31 501 查看
iptables原理: 包过滤型的防火墙

Firewall:防火墙,是一个隔离工具,能够对报文进行规则匹配,主要工作于主机或者网络边缘,对于匹配到报文进行相应的处理。所以其工作的范围又分为两类:
主机防火墙:对进出本主机的数据包进行规制匹配,并作出相应的处理动作。
网络防火墙:对流经本网络的数据包进行规制匹配,并作出相应的处理动作,工作在网络出口处,一般作为网关防火墙。
防火墙的的匹配规则顺序:自上而下按顺序进行匹配,对于匹配到的规则则按相应的处理动作进行处理,如果没有一条规则能匹配到则按默认规则进行处理,比如RETURN(返回调用链),默认存在。所以说对于同种规则大范围的规则应该放最上面,然后往下越来越严格。

iptables:
真正工作的并不是iptables,而是netfilter,是存在于内核中的一个模块,实现防火墙的功能,而iptables只是管理netfilter的一个工具。
iptables的功能:
五链:prerouting、input、output、forward、postrouting 即五个钩子函数,链还可以自定义
四表:filter、mangle、nat、raw
filter:主要是过滤,对应的链为input、output、forward
mangle:拆解报文,做出修改,并重新封装报文,对应的链为prerouting、input、output、forward、postrouting
nat:网络地址转换,实现地址或者端口的伪装,对应的链为prerouting、postrouting、output
raw:主要关闭nat表上启用的追踪功能,对应的链为prerouting、output
注意:在高并发的服务器上,比如前端httpd服务器,是需要关闭追踪功能的,因为追踪表有大小,如果超出了表的大小的话就会出现tcp连接超时,新的请求会请求不进来,虽然可以增大追踪表的容量,但会消耗更多的资源,而且效率也会降低。
报文在主机内的流向图:




报文的流向:
1、报文进入本机--->prerouting--->input--->用户空间--->output-->postrouting
2、报文流入本机--->prerouting--->forward--->postrouting
报文进入本机时,会先判断报文的是否是发给本机的,如果是则进入iput,然后进入内核空间,如果不是则通过forward链进行转发,最后判断应该从哪个网卡流出前往下一跳。
注意:当主机作为网络防火墙时,应用的就是forward链,所以需要开启转发功,把/proc/sys/net/ipv4/ip_forward改成1即可,这只是临时生效,想要永久生效得写进内核参数文件中
[root@localhost ipv4]# vim /etc/sysctl.conf
# Controls IP packet forwarding
net.ipv4.ip_forward = 1
[root@localhost ipv4]# /sbin/sysctl -p          //让参数立即生效
表的优先级示意图: 对比相同的链,raw>mangle>net>filter




iptables的规则: 根据规定的匹配条件来匹配报文,一旦匹配成功则按照规则定义的处理动作进行处理
组成部分:匹配条件和处理动作
匹配条件:基本匹配条件、扩展匹配条件
处理动作:基本处理动作、扩展处理动作、自定义处理动作
iptables的基本命令:
iptables [-t table] {-A|-C|-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 tables:指明哪个表,raw,mangle,nat,filter,如果不加-t 指明表示默认是filter表

链管理:
-N:表示新建一条自定义规则链
-X:表示删除一条规则链
-P:表示修改默认策略,对于filter表而言,其默认策略为:ACCEPT、REJECT、DROP
-E:表示重命名一条未被调用的自定义链,只要referneces为0。
规则管理:
-A:表示追加一条规则
-I :表示插入一条规则,可以指明插入位置,如果不指明则默认是第一条
-D:表示删除一条规则,需指明规则的序列号
-R:表示替换指定链上的规则,也需要指明规则的序列号
-F:表示清空规则,可以指定清空哪条规则链上的规则
-Z:置零,主要清空规则链上经过的包和字节数
iptables的每条规则都有两个计数器:
(1) 由本规制匹配到的报文的个数;
(2) 由本规制匹配到的所有报文的大小之和;
规则的查看:
-L:列出指定链上的所有规则

-n:以数字格式显示地址和端口号
-v:显示详细信息

-x:显示计数器的精确值
--line-numbers:显示规则的序列号

处理动作:
-j targetname [per-target-options] ACCEPT:接受 DROP :丢弃 REJECT:拒绝 RETURN:返回调用链; REDIRECT:端口重定向; LOG:记录日志; MARK:做防火墙标记; DNAT:目标地址转换; SNAT:源地址转换; MASQUERADE:地址伪装; 自定义链:注意:在写规则时,需要考虑以下几方面:
1、要实现哪种功能:需要添加在哪个表上
2、报文流径的路径:需要添加在哪个链上
规则的检查次序:
1、同类规则(访问同一应用),匹配范围小的放上面 2、不同类规则(访问不同应用),匹配到报文频率较大的放上面 3、将那些可由一条规则标书的多个规则合并为一个 4、设置默认策略 白名单(先允许特定访问,其他全部拒绝) 黑名单(先拒绝特定访问,其他全部允许)匹配条件: 基本匹配条件:无需加载任何模块,由iptables/netfilter自行提供;
[!] -s, --source address[/mask][,...]:检查报文中的源IP地址是否符合此处指定的地址或范围;
[!] -d, --destination address[/mask][,...]:检查报文中的目标IP地址是否符合此处指定的地址或范围;
[!] -p, --protocol protocol :限制协议,一般只限制tcp、udp、icmp
[!] -i, --in-interface name:数据报文流入的接口;只能应用于数据报文流入的环节,只能应用于PREROUTING,INPUT和FORWARD链;
[!] -o, --out-interface name:数据报文流出的接口;只能应用于数据报文流出的环节,只能应用于FORWARD、OUTPUT和POSTROUTING链;
扩展匹配条件:分为隐式扩展和显示扩展
隐式扩展:不需要手动加载扩展模块;因为它们是对协议的扩展,所以,但凡使用-p指明了协议,就表示已经指明了要扩展的模块;
不需要-m选项指明加载扩展选项,前提要使用-p选项可匹配何种协议
tcp:
[!] --source-port, --sport port[:port]:匹配报文的源端口;可以是端口范围;
[!] --destination-port,--dport port[:port]:匹配报文的目标端口;可以是端口范围;
[!] --tcp-flags mask comp:检查报文中mask指明的tcp标志位,而要这小标志位comp中必须为1
--tcp-flags SYN,ACK,FIN,RST SYN :表示要检查的标志位为SYN,ACK,FIN,RST四个,其中SYN必须为1,余下的必须为0;
--tcp-flags SYN,ACK,FIN,RST ack,fin :表示要检查ack,fin
[!] --syn:用于匹配第一次握手,相当于”--tcp-flags SYN,ACK,FIN,RST SYN“;
]# iptables -A INPUT -s 0/0 -d 10.0.1.2 -p tcp --dport 80 --tcp-flags SYN,ACK,FIN,RST SYN  -j ACCEPT
]# iptables -A INPUT -d 0/0 -s 10.0.1.2 -p tcp --sport 80 -j ACCEPT
udp:
[!] --source-port, --sport port[:port]:匹配报文的源端口;可以是端口范围;
[!] --destination-port,--dport port[:port]:匹配报文的目标端口;可以是端口范围;
]# iptables -A INPUT -s 0/0 -d 10.0.1.2 -p udp --dprot 53 -j ACCEPT
icmp:
[!] --icmp-type [type]
0: 回显应答 ping应答
8: 回显请求 ping请求
]# iptables -A INPUT -d 172.18.250.76 -p icmp --icmp-type 8 -j ACCEPT
]# iptables -A OUTPUT -s 172.18.250.76 -p icmp --icmp-type 0 -j ACCEPT
显示扩展:必须由-m选项来指定加载模块

1、multiport,以离散方式定义多个端口匹配,最多只能定义15个
[!] --source-ports,--sports port[,port|,port:port]...:指定多个源端口;
[!] --destination-ports,--dports port[,port|,port:port]...:指定多个目标端口;
[!] --ports port[,port|,port:port]...:指明多个端口;
]# iptables -A INPUT -d 172.18.250.76 -p tcp -m multiport --dports 80,8080,10050 -j ACCEPT
2、iprange扩展:指明连续的IP地址范围,但一般不指整个网络
[!] --src-range from[-to]:源IP地址;
[!] --dst-range from[-to]:目标IP地址;
]# iptables -A INPUT -d 172.18.250.76 -p tcp --dport 80 -m iprange --src-range 172.18.1.0-172.18.10.0 -j ACCEPT
3、string扩展:对报文中的应用层数据做字符串匹配,这条规则得放在OUTPUT链上
--algo {bm|kmp}:字符串匹配检测算法;
bm:Boyer-Moore
kmp:Knuth-Pratt-Morris
[!] --string pattern:要检测的字符串模式;
[!] --hex-string pattern:要检测的字符串模式,16进制格式;
]# iptables -A OUTPUT -s 172.18.250.76 -p tcp --dport 80 -m string --algo bm --string "Hello"  -j DROP
4、time扩展,根据将报文到达的时间/日期与指定的时间/日期范围进行匹配;
--datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:起始时间日期
--datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]: 结束日期时间
--timestart hh:mm[:ss]:起始时间
--timestop hh:mm[:ss]: 结束时间
[!] --monthdays day[,day...]:匹配一个月中的哪些天
[!] --weekdays day[,day...]:匹配一周中的哪些天
--kerneltz:使用内核上的时区,而非默认的UTC;
]# iptables -A INPUT -d 172.18.250.76 -p tcp --dport 80 -m time --timestart 8:30 --timestop 18:00 ! --weekdays 1 -j ACCEPT
5、connlimit扩展:根据客户端的IP做并发IP连接数的匹配
--connlimit-upto n:连接的数量小于等于n时匹配;
--connlimit-above n:连接的数量大于n时匹配;
]# iptables -A INPUT -d 172.18.250.76 -p tcp --dport 22 -m connlimit --connlimit-above 5 -j DROP
6、limit扩展:根据令牌桶算法对报文的速率进行匹配
--limit rate[/second|/minute|/hour|/day] :每秒/分/时/天请求的个数
--limit-burst number:突发速率个数
]# iptables -A INPUT -d 172.18.250.76 -p icmp --icmp-type 8 -m limit --limit 3/s --limit-burst 5 -j ACCEPT
7、state扩展,是conntrack的子集,用于对报文的状态做连接追踪,根据”连接追踪机制“去检查连接的状态;
conntrack机制:追踪本机上的请求和响应之间的关系;状态有如下几种:
NEW:新发出请求;连接追踪模板中不存在此连接的相关信息条目,因此,将其识别为第一次发出的请求;
ESTABLISHED:NEW状态之后,连接追踪模板中为其建立的条目失效之前期间内所进行的通信状态;
RELATED:相关联的连接;如ftp协议中的数据连接与命令连接之间的关系;
INVALID:无效的连接,无法识别的连接
UNTRACKED:未进行追踪的连接,
[!] --state state
]# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
]# iptables -A INPUT -s 0/0 -d 172.18.250.76 -p tcp --dport 80 -m state --state NEW -j ACCEPT
对于协议连接的会把连接状态记录在一张表里,在/proc/sys/net/nf_conntrack里,可以调整该表的大小,可通过调整/proc/net/ nf_conntrack_max的值,对于连接超时的状态对从表里进行删除,但一旦表满载的话,会导致后续的tcp连接超时。
对于不同的协议的连接追踪时长也不同,可以通过/proc/sys/net/netfilter文件查看。

解决tcp连接超时的办法:

1、加大nf_conntrack_max的值
]# vim /etc/sysctl.conf
net.ipv4.nf_conntrack_max = 393216
net.ipv4.netfilter.nf_conntrack_max = 393216
2、降低nf_conntrack条目的超时时长
]# vim /etc/sysctl.conf
net.ipv4.netfilter.nf_conntrack_tcp_timeout_established = 300
net.ipv4.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.ipv4.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.ipv4.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
如何开放被动模式的ftp服务?

对于ftp的连接追踪需要加载ftp模块
]# modprobe  nf_conntrack_ftp
]# iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
]# iptables -A INPUT -d 172.18.250.76 -p tcp --dport 21 -m state --state NEW -j ACCEPT
]# iptables -A OUTPUT -s 172.18.250.76 -p tcp --dport 21 -m state --state ESTABLISHED -j ACCEPT
如何保存编写好的iptables?
[root@localhost ipv4]# service iptables save
[root@localhost ipv4]# chkconfig iptables on
FORWARD链:
前提准备:
一台内网虚拟机:10.0.1.22/24,网关设置为10.0.1.2
一台转发虚拟机:172.18.250.76,10.0.1.2/24

一台外网虚拟机:172.18.250.77
开启核心转发功能:
[root@localhost ipv4]# vim /etc/sysctl.conf
# Controls IP packet forwarding
net.ipv4.ip_forward = 1
[root@localhost ipv4]# /sbin/sysctl -p          //让参数立即生效
测试能否ping通:
]# ping 10.0.1.2
PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data.
64 bytes from 10.0.1.2: icmp_seq=1 ttl=64 time=11.0 ms
]# ping 172.18.250.76
PING 172.18.250.76 (172.18.250.76) 56(84) bytes of data.
64 bytes from 172.18.250.76: icmp_seq=1 ttl=64 time=1.96 ms
注意:如果内网虚拟机没有设置网关为10.0.1.2的话,是ping不同172.18.250.76的。
]# ping 172.18.250.76
PING 172.18.250.77 (172.18.250.77) 56(84) bytes of data.    //这次没设置网关
这是因为内网虚拟机不知道改把报文发送给谁,没网关就不能跨网进行通信,只能在本地局域网通信
]# ping 172.18.250.77
PING 172.18.250.77 (172.18.250.77) 56(84) bytes of data.  //恢复网关后ping外网虚拟机
在外网服务器上抓包:
[root@localhost rules.d]# tcpdump -i eno16777736 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eno16777736, link-type EN10MB (Ethernet), capture size 65535 bytes
15:53:34.430441 IP 10.0.1.22 > 172.18.250.77: ICMP echo request, id 262, seq 48, length 64
15:53:34.430597 IP 172.18.250.77 > 10.0.1.22: ICMP echo reply, id 262, seq 48, length 64
这时可以看到报文已经到达了172.18.250.77,也返回了ping应答,但是内网虚拟机接受不到,是因为外网虚拟机会在本地找10.0.1.22的主机,或者通过设定的路由条目返回给其他10.0.1.22的主机。所以内网虚拟机接受不到。只要添加一个路由条目,指定到达10.0.1.0的网络通过172.18.250.76
[root@localhost rules.d]# route add -net 10.0.1.0/24 gw 172.18.250.76
4]# ping 172.18.250.77
PING 172.18.250.77 (172.18.250.77) 56(84) bytes of data.
64 bytes from 172.18.250.77: icmp_seq=453 ttl=63 time=1.98 ms   //添加完就可以通了
以上都是在iptables没任何规则测试的。。。
把FORWARD的策略改成DROP后:
设置内网可以ping外网,外网不能Ping内网:

]# iptables -A FORWARD -s 10.0.1.22 -p icmp --icmp-type 8 -j ACCEPT
]# iptables -A FORWARD -d 10.0.1.22 -p icmp --icmp-type 0  -j ACCEPT
设置外网可以Ping内网:
]# iptables -A FORWARD -s 172.18.0.0/16 -d 10.0.1.22 -p icmp --icmp-type 8  -j ACCEPT
]# iptables -A FORWARD -d 172.18.0.0/16 -s 10.0.1.22 -p icmp --icmp-type 0  -j ACCEPT


处理动作:
LOG:开启日志记录功能,要放在reject或drop,accept处理动作之前
--log-level level 日志级别 error、warn
--log-prefix prefix 日志行前缀
]# iptables -A FORWARD -s 10.0.1.0/24 -p tcp --dport 80 -m state --state NEW -j LOG --log-prefix "new connctions: "
]# iptables -A FORWARD -s 10.0.1.0/24 -p tcp --dport 80 -m state --state NEW -j ACCEPT
RETURN:返回调用者,默认是存在
]# iptables -N web
]# iptables -A web -s 10.0.1.0/24 -p tcp --dport 80 -m state --state NEW -j ACCEPT
]# iptables -I web -m state --state ESTABLISHED -j ACCEP
]# iptables -A FORWARD -p tcp -j web                  //调用web链
]# iptables -A FORWARD -s 10.0.1.0/24 -p tcp --dport 22 -m state --state NEW -j ACCEPT
//没写返回调用者,依然能远程登录外网
]# iptables -A web -j RETURN  //返回调用者
REDIRECT:端口重定向 应用在PREROUTING上重定向
--to-ports port
]# iptables -t nat -A PREROUTING -d 172.18.250.77 -p tcp --dport 80 -j REDIRECT --to-ports 8080
SNAT:源地址转换 (主机是客户端,向外访问) 在POSTROUTING链实现转换
修改IP报文中的源IP地址
让本地网络中的主机可使用统一地址与外部主机通信,从而实现地址伪装;
请求:修改源IP,如果修改则由管理员定义
响应:修改目标IP,由nat自动根据会话表中追踪机制实现相应修改
--to-source ipaddr
--random: 端口随机
]# iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -j SNAT --to-source 172.18.250.76
MASQUERADE: 应用在动态拨号获得IP地址的,POSTROUTING,需要消耗额外的资源,静态地址不建议
当源地址为动态获取的地址时,MASQUERADE可自行判断要转换为的地址
--to-ports port[-port]
]# iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -j MASQUERADE
DNAT:目标地址转换 (主机是服务器,外网访问进来),在PREROUTING链实现转换
修改IP报文中的目标IP地址
让本地网络中服务器使用统一的地址向外提供服务(发布服务),但隐藏了自己的真实地址;
请求:由外网主机发起,修改其目标地址,由管理员定义
响应:修改源地址,但由nat自动根据会话表中追踪机制实现相应修改
--to-destination [ipaddr[-ipaddr]][:port[-port]]
支持目标端口转换
]# iptables -t nat -A PREROUTING  -d 172.18.250.76 -p tcp --dport 80 -j DNAT --to-destination 10.0.1.22
]# iptables -t nat -A PREROUTING  -d 172.18.250.76 -p tcp --dport 80 -j DNAT --to-destination 10.0.1.22:8080   //请求的是80  但转换成真实的8080端口
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: