基于状态的iptables
如果按照tcp/ip来划分连接状态,有11种之多(课后可以自己去读一下相关知识)
但iptables里只有4种状态;ESTABLISHED、NEW、RELATED及INVALID
这两个分类是两个不相干的定义。例如在TCP/IP标准描述下UDP及ICMP数据包是没有连接状态的,但在state模块的描述下,任何数据包都有连接状态。
1、ESTABLISHED
(1)与TCP数据包的关系:首先在防火墙主机上执行SSH Client,并且对网络上的SSH服务器提出服务请求,而这时送出的第一个数据包就是服务请求的数据包,如果这个数据包能够成功的穿越防火墙,那么接下来SSH Server与SSH Client之间的所有SSH数据包的状态都会是ESTABLISHED。
(2)与UDP数据包的关系:假设我们在防火墙主机上用firefox应用程序来浏览网页(通过域名方式),而浏览网页的动作需要DNS服务器的帮助才能完成,因此firefox会送出一个UDP数据包给DNS Server,以请求名称解析服务,如果这个数据包能够成功的穿越防火墙,那么接下来DNS Server与firefox之间的所有数据包的状态都会是ESTABLISHED。
(3)与ICMP数据包的关系:假设我们在防火墙主机ping指令来检测网络上的其他主机时,ping指令所送出的第一个ICMP数据包如果能够成功的穿越防火墙,那么接下来刚才ping的那个主机与防火墙主机之间的所有ICMP数据包的状态都会是ESTABLISHED。
由以上的解释可知,只要第一个数据包能够成功的穿越防火墙,那么之后的所有数据包(包含反向的所有数据包)状态都会是ESTABLISHED。
2、NEW
首先我们知道,NEW与协议无关,其所指的是每一条连接中的第一个数据包,假如我们使用SSH client连接SSH server时,这条连接中的第一个数据包的状态就是NEW。
3、RELATED
RELATED状态的数据包是指被动产生的数据包。而且这个连接是不属于现在任何连接的。RELATED状态的数据包与协议无关,只要回应回来的数据包是因为本机送出一个数据包导致另一个连接的产生,而这一条新连接上的所有数据包都是属于RELATED状态的数据包。
4、INVALID
INVALID状态是指状态不明的数据包,也就是不属于以上三种状态的封包。凡是属于INVALID状态的数据包都视为恶意的数据包,因此所有INVALID状态的数据包都应丢弃掉,匹配INVALID状态的数据包的方法如下:
iptables -A INPUT -p all -m state INVALID -j DROP
我们应将INVALID状态的数据包放在第一条。
|
随机 | 80 web
---------|--》
client | server
《---------|--
随机 | 80
|
client访问server过去
第一个数据包(new状态),如果拒绝,那么后续包都会被拒绝(因为后面来的都会是第一个,都为new状态)
第一个数据包如果允许过去,那么后续包的状态为established
server返回给client
返回的所有包都为established
例1:
有下面两台机
10.1.1.9 10.1.1.10
client server
10.1.1.9是可以ssh访问10.1.1.10,也可以elinks访问10.1.1.10
1,在10.1.1.10上
# iptables -P INPUT DROP
# iptables -P OUTPUT DROP
这里就把双链都关掉,10.1.1.9任何访问都过不来了
2,
按以前的做法:
在10.1.1.10上允许别人ssh进来
# iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
在10.1.1.10上允许别人elinks进来
# iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT
或者把上面四条合下面两条
# iptables -A INPUT -p tcp -m multiport --dport 22,80 -j ACCEPT
# iptables -A OUTPUT -p tcp -m multiport --sport 22,80 -j ACCEPT
把上面的两条再换成
# iptables -A INPUT -p tcp -m multiport --dport 22,80 -j ACCEPT
# iptables -A OUTPUT -p tcp -m state --state established -j ACCEPT
(后面一句可以翻译成tcp协议的连接只要你进得来,你就回得去)
(无论他是用哪个随机端口访问进来的;因为只要能进来,那么后续的包都属于ESTABLISHED状
例2:有些服务器,可能希望你ping不通他,但是他可以ping通你
方法一:
在服务器上把/proc/sys/net/ipv4/icmp_echo_ignore_all的值改为1
临时修改:# echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
永久修改:
# vim /etc/sysctl.conf --加上下面一句
net.ipv4.icmp_echo_ignore_all = 1
# sysctl -p --使用此命令让其生效
通过iptables的状态来实现
有下面两台机
10.1.1.9 10.1.1.10
实现10.1.1.10这个IP能ping通所有人.但所有人不能ping通10.1.1.10
|
--------------》| ------->
client | server
10.1.1.9 | 10.1.1.10
<-------------| <--------
NEW ESTABLISHED
INPUT 拒绝 允许
OUTPUT 允许 允许
1,在10.1.1.10上
# iptables -P INPUT DROP
# iptables -P OUTPUT DROP
这里就把双链都关掉,10.1.1.9任何访问都过不来了
2,在10.1.1.10上
# iptables -A INPUT -p icmp -m state --state ESTABLISHED -j ACCEPT
# iptables -A OUTPUT -p icmp -m state --state NEW,ESTABLISHED -j ACCEPT
---重点是INPUT那条不能允许NEW状态的;
---注意第二步的第二条(也就是output这条),如果只写了NEW状态,那么10.1.1.10ping所有人,都只能通第一个包;加上ESTABLISHED状态,所有包都能通
例3:
有一个服务器,搭建了http,ftp(主动和被动都要支持,被动端口为3000-3005)两个服务(需要开放给所有人访问);还要开放ssh和ping(但只开放给一个管理ip访问,比如此IP为10.1.1.X),其它任何进来的访问都拒绝
但此服务器要出去访问别的任何服务,自己的防火墙都要允许
需求一个一个的写:
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 21 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 20 -j ACCEPT
iptables -A INPUT -p tcp --dport 20 -j ACCEPT
iptables -A INPUT -p tcp --dport 3000:3005 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 3000:3005 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 10.1.1.x -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -d 10.1.1.x -j ACCEPT
iptables -A INPUT -p icmp -s 10.1.1.x -j ACCEPT
iptables -A OUTPUT -p icmp -d 10.1.1.x -j ACCEPT
iptables -A OUTPUT -p all -m state --state new,established,related -j ACCEPT
iptables -A INPUT -p all -m state --state established,related -j ACCEPT
把上面的综合起来:?
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -A INPUT -p tcp -m multiport --dport 80,21,3000,3001,3002,3003,3004,3005 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -s 10.1.1.x -j ACCEPT
iptables -A INPUT -p icmp -s 10.1.1.x -j ACCEPT
iptables -A INPUT -p all -m state --state established,related -j ACCEPT
iptables -A OUTPUT -p all -m state --state new,established,related -j ACCEPT