首页 > 代码库 > iptables之一

iptables之一

扩展:multiport、iprange、connlimit、limit、time、string{kmp|bm} state [NEW、ESTABLISHED、RELATED、INVALID],作为一个主机防火墙,我们本机出去,本机服务器

对服务器而言,很少需要主动发起新请求去连接别的机子。因为要在OUTPUT,很多情况下要放行ESTABLISHED和RELATED,对于INPUT也是,而NEW很少放行,放行也仅是放行客户端建立连接的服务。

如TCP 80开放NEW。

优化的规则:尽量减少规则条目,属于同一功能匹配严格的一般放入上面。

由于规则限定很细,很多时候,需要自己自定义一个链,如何自定义呢?

对于filter表来说就三个链,INPUT.FORWARD.OUTPUT。由于自定义的链没有在内核上,所以只有被调用才会使用。

------------------------------------------------------------------------------------

关于主机防火墙,控制主机本身的进出规则~

案例:如果访问web服务就要自定义一条链,web拒绝172.16.1.50-172.16.1.100范围内的主机访问。

如果不自定义表的话,就用这个命令。

[root@libin ~]# iptables -A INPUT -d 192.168.1.162 -p tcp --dport 80 -m iprange --src-range 172.16.1.50-172.16.1.100 -j DROP

image 效果如左图

但是我们要自己创建定义链就要使用命令:

iptables –t filter (表面对哪个表,默认是filter) –N webin (新建一个叫webin的链)

image 一个叫webin的新链就建立好了,而我们的目的就是为了在这条webin的链上限定80的web服务。建立好了,我们开始创建规则吧

案例二

我们是web服务器端,我们可以让网络上任何主机都可以访问我们的80端口服务,但是限定192.168.1.128主机对服务器的web访问。

image

[root@libin ~]# iptables -A webin -d 192.168.1.162 -p tcp --dport 80  -s 192.168.1.128 -j DROP

而实际的效果是:

Chain webin (0 references)
target     prot opt source               destination        
DROP       tcp  --  192.168.1.128        192.168.1.162       tcp dpt:80

那么我们用192.168.1.128去测试一下实际效果:

[root@libin ~]# curl http://192.168.1.162

根本就是没有响应,说明拒绝了它的访问,如果我们同时允许除了它以外的其他人访问,也可以使用下列的命令。

iptables -A webin -d 192.168.1.162 -p tcp --dport 80 -m state --state NEW -j ACCEPT

-m state 因为我们想让它对第一次请求建立web服务的客户端放行,就要使用 – state NEW 表明第一次访问连接的就允许放行。

而后我们可以修改INPUT链中加入这一条:

[root@libin ~]# iptables -A INPUT -d 192.168.1.162 -m state --state ESTABLISHED  -j ACCEPT
[root@libin ~]# iptables -L -n
Chain INPUT (policy DROP)
target     prot opt source               destination        
ACCEPT     tcp  --  0.0.0.0/0            192.168.1.162       tcp dpt:22
DROP       tcp  --  0.0.0.0/0            192.168.1.162       tcp dpt:80 source IP range 172.16.1.50-172.16.1.100
ACCEPT     all  --  0.0.0.0/0            192.168.1.162       state ESTABLISHED

说明如果放行处于连接中的web服务。

案例三:设想一下,如果我们需要多次使用到ssh服务去远程连接服务器,也可以通过建立一个新的链来规定我们的ssh的。

[root@libin ~]# iptables -t filter -N sshin
[root@libin ~]# iptables -L -n

Chain sshin (0 references)
target     prot opt source               destination

现在建立完新链了,但是没有做调用,还是不生效的,所以还要调用它。就拿刚才的webin为例吧,如果我们想生效这个webin链,只需要写

[root@libin ~]# iptables -A INPUT -d 192.168.1.162 --dport 80 -j webin
iptables v1.4.7: unknown option `--dport‘
Try `iptables -h‘ or ‘iptables --help‘ for more information.

这里报了一个错,它说不知道的选项--dport,笔者曾经在此犯过错误,后来笔者细心的一看,原来经常忘记加-p tcp /udp 这里需要-p 协议名称,需要加协议的!

[root@libin ~]# iptables -A INPUT -d 192.168.1.162 -p tcp --dport 80 -j webin
[root@libin ~]#

这样就ok啦

webin      tcp  --  0.0.0.0/0            192.168.1.162       tcp dpt:80

显示写入跳转的规则,让我们看看匹配的实际效果。

[root@libin htdocs]# iptables -L -n -v
Chain INPUT (policy DROP 61 packets, 6558 bytes)
pkts bytes target     prot opt in     out     source               destination        
1929  140K ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.1.162       tcp dpt:22
    0     0 DROP       tcp  --  *      *       0.0.0.0/0            192.168.1.162       tcp dpt:80 source IP range 172.16.1.50-172.16.1.100
   32  3404 ACCEPT     all  --  *      *       0.0.0.0/0            192.168.1.162       state ESTABLISHED
    6   312 webin      tcp  --  *      *       0.0.0.0/0            192.168.1.162       tcp dpt:80

有6个包进来了,此时我们用物理机win7来做任意ip地址的客户端访问web服务器,此时会出现:

[root@libin htdocs]# iptables -L -n -v
Chain INPUT (policy DROP 84 packets, 9003 bytes)
pkts bytes target     prot opt in     out     source               destination        
1935  140K ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.1.162       tcp dpt:22
    0     0 DROP       tcp  --  *      *       0.0.0.0/0            192.168.1.162       tcp dpt:80 source IP range 172.16.1.50-172.16.1.100
   37  4064 ACCEPT     all  --  *      *       0.0.0.0/0            192.168.1.162       state ESTABLISHED
    7   364 webin      tcp  --  *      *       0.0.0.0/0            192.168.1.162       tcp dpt:80

出现了变化!

如果某个请求在定义的规则中匹配不到,怎么办?我们可以定义一个RETURN,定义如果匹配不到就回到主链上去

iptables –A webin –d 192.168.1.126 –j RETURN

Chain webin (1 references)
pkts bytes target     prot opt in     out     source               destination        
    0     0 DROP       tcp  --  *      *       192.168.1.128        192.168.1.162       tcp dpt:80
    8   416 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.1.162       tcp dpt:80 state NEW
    0     0 RETURN     all  --  *      *       0.0.0.0/0            192.168.1.162 

意思是如果匹配不到,回到主链上去。

由此可见,我们可以设计出一个这样的概念,让我们的服务器192.168.1.128仅仅支持自己的ssh远程连接和支持192.168.1.10-192.168.1.253,其他的一律拒绝.

image

Chain INPUT (policy DROP 562 packets, 74975 bytes)
pkts bytes target     prot opt in     out     source               destination        
4435  338K ACCEPT     all  --  *      *       0.0.0.0/0            192.168.1.128       state ESTABLISHED
    0     0 webin      tcp  --  *      *       0.0.0.0/0            192.168.1.128       tcp dpt:80
   37  2068 sshin      tcp  --  *      *       0.0.0.0/0            192.168.1.128       tcp dpt:22

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination        

Chain OUTPUT (policy DROP 184 packets, 55088 bytes)
pkts bytes target     prot opt in     out     source               destination        
2366  268K ACCEPT     all  --  *      *       192.168.1.128        0.0.0.0/0           state ESTABLISHED
    0     0 ACCEPT     tcp  --  *      *       192.168.1.128        0.0.0.0/0           tcp spt:22

Chain sshin (1 references)
pkts bytes target     prot opt in     out     source               destination        
    2   104 ACCEPT     tcp  --  *      *       192.168.1.179        192.168.1.128       tcp dpt:22
   20  1128 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0          

Chain webin (1 references)
pkts bytes target     prot opt in     out     source               destination        
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.1.128       tcp dpt:80 source IP range 192.168.1.10-192.168.1.253 state NEW
    0     0 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0

注意这里的192.168.1.179是物理机的ip地址,它通过ssh连接192.168.1.128这个服务器。

让我们做个测试:

image 显然是失败了

最后还有一步,就是我们把现在定义好的规则给它保存起来如何~

image 这个是已经保存好的规则了!

现在我们将iptables规则清空:

[root@libin tmp]# iptables -P INPUT ACCEPT
[root@libin tmp]# iptables -P OUTPUT ACCEPT
[root@libin tmp]# iptables -F
[root@libin tmp]# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination        

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination        

Chain sshin (0 references)
target     prot opt source               destination        

Chain webin (0 references)
target     prot opt source               destination  

然后用iptables-restore重新读取文件,看看能不能生效:

[root@libin tmp]# iptables-restore < /tmp/iptables_1.txt
[root@libin tmp]# iptables -L -n
Chain INPUT (policy DROP)
target     prot opt source               destination        
ACCEPT     all  --  0.0.0.0/0            192.168.1.128       state ESTABLISHED
webin      tcp  --  0.0.0.0/0            192.168.1.128       tcp dpt:80
sshin      tcp  --  0.0.0.0/0            192.168.1.128       tcp dpt:22

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination        

Chain OUTPUT (policy DROP)
target     prot opt source               destination        
ACCEPT     all  --  192.168.1.128        0.0.0.0/0           state ESTABLISHED
ACCEPT     tcp  --  192.168.1.128        0.0.0.0/0           tcp spt:22

Chain sshin (1 references)
target     prot opt source               destination        
ACCEPT     tcp  --  192.168.1.179        192.168.1.128       tcp dpt:22
RETURN     all  --  0.0.0.0/0            0.0.0.0/0          

Chain webin (1 references)
target     prot opt source               destination        
ACCEPT     tcp  --  0.0.0.0/0            192.168.1.128       tcp dpt:80 source IP range 192.168.1.10-192.168.1.253 state NEW
RETURN     all  --  0.0.0.0/0            0.0.0.0/0 

看来还是能的!

而且使用iptables –X 自定义链的链名(必须为空),可以删除自定义的链

[root@libin tmp]# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination        

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination        

Chain sshin (0 references)
target     prot opt source               destination        

Chain webin (0 references)
target     prot opt source               destination        
[root@libin tmp]# iptables -X sshin
[root@libin tmp]# iptables -X webin
[root@libin tmp]# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination        

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination 

没有webin和sshin啦!

使用重命名的(一定要是0引用的)iptables –E 自定义的老链名称  新的链名

------------------------------------------------------------------------------------------------------------------------------------

下面则是网络防火墙部分

image 计划:模拟一个外内网通信的模型,然后进一步设置FORWARD转发功能,进一步限制!

image 图←服务器192.168.1.128支持nat功能,可以转发内外主机的ip报文

image 图←内网主机192.168.5.1用ping的方式连接外网主机,结果显示成功!

image 图←外网主机192.168.1.162可以ping同外网的主机!

现在开始限定,先加入放行规则为已建立连接的就放行

[root@libin ~]# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        

Chain FORWARD (policy DROP)
target     prot opt source               destination        
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state ESTABLISHED

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination        
然后再添加:

[root@libin ~]# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        

Chain FORWARD (policy DROP)
target     prot opt source               destination        
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state ESTABLISHED
ACCEPT     tcp  --  0.0.0.0/0            192.168.5.10        tcp dpt:80 state NEW

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination   

意思就是对内网那个主机做80端口访问的都予以放行。这时我们就可以访问了。

[root@libin ~]# curl 192.168.5.10
<h1> this is 5.1 </h1>

[root@libin ~]#

出现了它的首页了。

那么我们如果清理了FORWARD链了呢?

[root@libin ~]# curl 192.168.5.10

就显示打不开,一直卡在那个页面上。

好的, 下面让我们看看ftp怎么限制访问:

这是内网主机开启了vsftpd,是ftp的服务器端

image 被动监听在21号端口!

然后我们用外网主机来联系它,通过网络防火墙:

[root@libin ~]# lftp 192.168.5.10
lftp 192.168.5.10:~> ls             
`ls‘ at 0 [Connecting...]

显示连接不上。。

我们修改网络防火墙规则:这里没有定义具体的那些端口,进而试试:

[root@libin ~]# iptables -A FORWARD -d 192.168.5.10 -s 192.168.1.162 -p tcp -m state --state NEW -j ACCEPT
You have new mail in /var/spool/mail/root
[root@libin ~]# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        

Chain FORWARD (policy DROP)
target     prot opt source               destination        
ACCEPT     tcp  --  192.168.1.162        192.168.5.10        state NEW

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination    

让我们来试一下:

image 显示连接不上去?为什么呢??还记得我们的ftp一般都是被动模式的,命令连接是被动的,还有一个数据连接呢?所以要加上RELATED,好吧,那我们加上去试一下。

[root@libin ~]# iptables -R FORWARD 2 -m state --state ESTABLISHED,RELATED -j ACCEPT
[root@libin ~]# iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        

Chain FORWARD (policy DROP)
target     prot opt source               destination        
ACCEPT     tcp  --  192.168.1.162        192.168.5.10        state NEW
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED

我们再去用外网主机FTP连接内网主机试试:

image !!竟然还是不行,原来是我们的模块没有加载,让我们重新加载一下模块。

[root@libin ~]# modprobe nf_conntrack_ftp加载nf_conntrack_ftp模块

[root@libin ~]# lftp 192.168.5.10
lftp 192.168.5.10:~> ls
drwxr-xr-x    2 0        0            4096 Mar 01  2013 pub

看!可以了

其实每次手动加载模块是很麻烦的事,我们需要编辑配置文件/etc/sysconfig/iptables-config 这个文件,在里面找到:

# Load additional iptables modules (nat helpers)
#   Default: -none-
# Space separated list of nat helpers (e.g. ‘ip_nat_ftp ip_nat_irc‘), which
# are loaded after the firewall rules are applied. Options for the helpers are
# stored in /etc/modprobe.conf.
IPTABLES_MODULES="nf_conntrack_ftp"就ok了

=======================================================================================================