Ubuntu ufw防火墙规则顺序问题

本文以Ubuntu 14.04为例,讲讲ufw防火墙规则顺序问题。

--------------------------------此处应该优雅的使用分割线--------------------------------

先说原理再吐槽!

Linux系统及其许多其他软件中都有访问控制(Access Control)功能,比如系统中的防火墙,Cisco ios中的ACL(Access Control Lists),Web服务器中的Access Module。在有些访问控制的实现中,有一些访问控制的功能跟顺序有关,例如禁止所有其他主机访问本机端口但允许某一台主机访问本机端口,或者允许所有主机访问本机端口但禁止某一台主机访问本端口。这样的例子在netfilter iptables和Apache httpd 2.2版本中能很容易得到体现,这里主要讲讲Ubuntu的ufw。

首先要给大多数人纠正一下,ufw并不是一个防火墙,尽管它叫做Ubuntu firewall,但它本身并没有防火墙的功能,它只是一个管理netfilter防火墙的工具,其核心还是netfilter的iptables。这一点在ufw的man中很容易发现,ufw是管理netfilter的一个程序而已,此工具的目的在于帮助用户简化iptables的复杂使用方法。

在说Ubuntu ufw之前还是要说一下CentOS中的iptables,在CentOS中,iptables规则是从一个文件(/etc/sysconfig/iptables)中,从上到下读取配置的,后一条的规则能覆盖(override)前一条规则,例如默认规则下有2条拒绝规则:

-A INPUT -j REJECT --reject-with icmp-host-prohibited    
-A FORWARD -j REJECT --reject-with icmp-host-prohibited

这两条规则的含义是拒绝其他不符合规则的数据包,并且给被拒绝的主机发送一条icmp host prohibited的消息。并且这两条规则可以认为是iptables对默认规则的补充,因为在这些默认规则之前,有:INPUT ACCEPT [0:0]这样的规则,这些规则表示默认全部允许。

那说了这么多,到底要表达什么呢?不知道有没有这样的印象,就是在CentOS中直接使用iptables命令插入一个规则,并没有起作用,原因就是它默认被插入到了REJECT规则的下面?例如执行“iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 8088 -j ACCEPT”却发现不好用,原因是它插入到“-A INPUT -j REJECT --reject-with icmp-host-prohibited”的下面,要想好用,那必须插入到它的前面,例如执行“iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 8088 -j ACCEPT”,这样它就会被添加到INPUT链的最前端,也就起到预期的作用了。

现在再说Ubuntu ufw。Ubuntu ufw这个程序有点奇怪,它总是像Ubuntu系统一样,喜欢everything included,尽管ufw也不是简单的included,ufw自己做了一些类似脚本的东西以及有一堆相关的文件,它称之为ufw-framework,可以通过man ufw-framework看到它的介绍信息和相关文件,可以看到它不当作普通服务运行而是当作脚本运行(例如man中提到的a standard SysV style initscript used by the ufw command),如果想深入研究一下的话可以自己慢慢看man page以及查看相关的文件和资料。

在说ufw到底如何用之前,还是要继续强调一下。首先还是要说明,Ubuntu是一个对工程师很不友好的系统,它只亲爱它的开发人员,毕竟是开发人员开发出来的,因此许多像我这样的工程师都不喜欢用Ubuntu,而很多开发者却因为它看起来的简单易用而选择Ubuntu。在此列举一下我之前说过的一段话,“如果你要为你的Linux选择发行版本,无论如何都不要选择Ubuntu,如果你非要坚持选Ubuntu也一定要选12.xx(precise),不要选14.xx(trusty),而且不要升级到trusty。Ubuntu14.xx之前还不错,14.xx后有不少坑,这个与CentOS7有一点像,大都是因为systemd的原因,关于systemd的罪恶可以参考这篇文章,http://www.zdnet.com/article/linus-torvalds-and-others-on-linuxs-systemd/。”

--------------------------------此处应该优雅的使用分割线--------------------------------

终于到了在这里简洁的介绍一下ufw到底如何去用的时候了。本文只讲顺序问题不讲语法问题,语法问题可以自己查询man page或者其他网站的精彩文章。这里只说一些别的文章上不说的地方,从实际生产环境和多次测试得来经验。

那iptables通过-A和-I区分插入还是添加,ufw也是有的,而且ufw的本质还是跟iptables风格一样的配置文件(这个文件是/lib/ufw/user.rules,这个文件就像CentOS下的/etc/sysconfig/iptables文件一样,记录着用户自定义的规则),具体什么内容什么语法自己可以去查看。

此处以ssh默认端口22为例,列举一下允许所有主机访问本机22端口但禁止某一台主机(10.20.0.1)访问22端口的例子。

如果是初次配置ufw防火墙,那么可以这么做:

sudo ufw reset#重置防火墙    
sudo ufw enable#启用防火墙    
sudo ufw default reject#配置默认规则,拒绝    
sudo ufw deny from 10.20.0.1#拒绝某IP访问,或执行sudo ufw deny from 10.20.0.1 to 10.20.0.130 port 22    
sudo ufw allow 22/tcp#允许所有主机访问22端口    
sudo ufw status#查看ufw状态

如果ufw已经被配置过,规则已经有了,那就这么做:

sudo ufw status numbered#按照数字书序查看ufw状态,注意带v6的不用管    
sudo ufw insert 1 deny from 10.20.0.1#或者sudo ufw insert 1 deny from 10.20.0.1 to 10.20.0.130 port 22

sudo ufw allow 22/tcp    
sudo ufw status

经过上述配置以后,如/lib/ufw/user.rules文件会像下面显示:

### tuple ### deny any 22 10.20.0.130 any 10.20.0.1 in    
-A ufw-user-input -p tcp -d 10.20.0.130 --dport 22 -s 10.20.0.1 -j DROP    
-A ufw-user-input -p udp -d 10.20.0.130 --dport 22 -s 10.20.0.1 -j DROP

### tuple ### allow tcp 22 0.0.0.0/0 any 0.0.0.0/0 in    
-A ufw-user-input -p tcp --dport 22 -j ACCEPT

上面的###开始的注释能使ufw正确识别通过ufw命令添加的规则,自己可以手动用iptables命令去改写。因此通过命令也是可以添加这样的规则的。

例如:

iptables -I ufw-user-input -p tcp -d 10.20.0.130 --dport 22 -s 10.20.0.1 -j DROP      
iptables -I ufw-user-input -p udp -d 10.20.0.130 --dport 22 -s 10.20.0.1 -j DROP

iptables -I ufw-user-input -p tcp --dport 22 -j ACCEPT

为何能手动改写?原因可以通过先启用ufw后再用iptables-save命令查看:

-A ufw-user-input -s 10.20.0.1/32 -d 10.20.0.130/32 -p tcp -m tcp --dport 22 -j DROP    
-A ufw-user-input -s 10.20.0.1/32 -d 10.20.0.130/32 -p udp -m udp --dport 22 -j DROP    
-A ufw-user-input -p tcp -m tcp --dport 22 -j ACCEPT    
-A ufw-user-limit -m limit --limit 3/min -j LOG --log-prefix "[UFW LIMIT BLOCK] "    
-A ufw-user-limit -j REJECT --reject-with icmp-port-unreachable    
-A ufw-user-limit-accept -j ACCEPT

通过这一段信息可以发现,其实这跟/etc/sysconfig/iptables文件真的一样。

简单一句话,就是先deny,后allow,deny规则插入到allow规则前面,这样才能起到禁止的作用。

文中讲的不是特别详细,但绝对能有启发作用,希望当你通过ufw设定deny规则不好用时,可以想起这篇文章,哈哈。

--------------------------------此处应该优雅的使用分割线--------------------------------

一些可用的参考或资料:

Cisco Configuring IP Access Lists http://www.cisco.com/c/en/us/support/docs/security/ios-firewall/23602-confaccesslists.html#acl

Apache httpd 2.2 Access Control http://httpd.apache.org/docs/2.2/howto/access.html

Apache httpd 2.4 Access Control http://httpd.apache.org/docs/2.4/howto/access.html

Apache httpd Access Control – Order http://httpd.apache.org/docs/2.4/mod/mod_access_compat.html#order

tag:Ubuntu ufw用法,ufw规则无效,Ubuntu配置防火墙,Ubuntu ufw原理,Ubuntu ufw规则顺序

--end--

你可能感兴趣的:(Ubuntu ufw防火墙规则顺序问题)