首頁 > 軟體

Ubuntu ufw防火牆規則順序問題

2020-06-16 17:49:58

本文以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的罪惡可以參考下面這些文章,

CentOS7/RHEL7 systemd詳解   http://www.linuxidc.com/Linux/2015-04/115937.htm

為什麼systemd會被如此迅速的採用? http://www.linuxidc.com/Linux/2014-08/105789.htm

systemd 與 sysVinit 彩版對照表 http://www.linuxidc.com/Linux/2014-09/106455.htm

太有用了!用systemd命令來管理Linux系統!  http://www.linuxidc.com/Linux/2014-09/106490.htm

淺析 Linux 初始化 init 系統,第 3 部分: Systemd  http://www.linuxidc.com/Linux/2014-12/110383.htm

--------------------------------此處應該優雅的使用分割線--------------------------------

終於到了在這裡簡潔的介紹一下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--


IT145.com E-mail:sddin#qq.com