About me

Sunday, 16 October 2016

[Linux] Uncomplicated Firewall (UFW)

  
  Uncomplicated Firewall

  之前一直在用firewalld,用法請參考之前的文章『firewalld』,但是我的PC安裝的是Ubuntu阿,
  所以還是來研究一下UFW (Uncomplicated Firewall),然後將firewalld取代掉吧。

  在Linux的kernel裡面提供了一個過濾封包的subsystem稱為『netfilter』,主要用來決定外來或內部網路封包是否可以通過的規則,傳統操縱netfilter的介面是『iptables套件』,iptables提供了一套完全彈性和很好去組態的防火牆機制。但是想要精通iptables需要花很多時間,而且對於初學者來說想要使用iptables來設定你的防火牆是一件非常堅巨的任務。所以有許多的前端軟體被建立出來,每個都有不同的用途。

  UFW是Ubuntu上的防火牆(iptables)的前端CLI工具,提供了控制netfilter的framework,但是在其他的distros上面也可以安裝,如果不喜歡用CLI的話,可以使用『Gufw』這套GUI程式。而UFW是在Ubuntu 版本8.04 LTS (Hardy Heron)被引入的,後面的版本都可以直接安裝:


  - Ubuntu 12.04 LTS: 0.31.1-1
  - Ubuntu 14.04 LTS: 0.34~rc-0ubuntu2
  - Ubuntu 15.10: 0.34-2
  - Ubuntu 16.04 LTS: 0.35-0ubuntu2
  - Ubuntu Core: 0.35pre


  
內容 -預設規則 -啟動與關閉 UFW -規則與狀態查詢 -刪除既定的規則 -以Port來管理 -以Services名稱來管理 -以Package名稱來管理 -特定 IP管理 -子網域管理 -特定 IP + Port -特定IP + Port +特定協定 -允許/拒絕 PING -使用 numbered參數 -IP Masquerading -進階範例 -Dry run -Logging -Log 參數說明 -其他 -REF
預設規則 當你將UFW開啟時,就會是用一個預設的profile,而這個profile對於大部分的home使用者來說就夠用了,簡單來說就是除了幾個例外以外,幾乎所有的『incoming』都會被『denied』。
啟動與關閉 UFW 啟動 使用底下指令來開啟UFW sudo ufw enable 檢查UFW的狀態 sudo ufw status verbose 結果會像是: hugh@hugh:~$ sudo ufw status verbose Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), deny (routed) New profiles: skip 注意到上面,預設就是設定incoming為deny,其他的例外就要用底下的指令查看: sudo ufw show raw 列出來的rule可以檢視『/etc/ufw/*.rules』。 關閉 使用底下指令關閉ufw: sudo ufw disable
規則與狀態查詢 語法: sudo ufw status [verbose/numbered] 會列出你目前是否有開啟ufw還有列出所有的規則,像是如下: sudo ufw status Firewall loaded To Action From -- ------ ---- 22:tcp DENY 192.168.0.1 22:udp DENY 192.168.0.1 22:tcp DENY 192.168.0.7 22:udp DENY 192.168.0.7 22:tcp ALLOW 192.168.0.0/24 22:udp ALLOW 192.168.0.0/24 如果後面加參數『verbose』,將會顯示出更進階的訊息; 如果後面加參數『numbered』,將會在每行規則前面顯示一個索引值。
刪除既定的規則 要刪除某個防火牆規則,只要簡單的在前面加個delete,舉例來說,之前有宣告的規則如下: ufw deny 80/tcp 要把上列規則刪掉的話,只要用: sudo ufw delete deny 80/tcp
以Port來管理 Allow 語法如下: sudo ufw allow [port]/[optional: protocol] example 1 : 允許port 53進來的tcp/udp協定 sudo ufw allow 53 example 2: 只允許port 53進來的tcp協定 sudo ufw allow 53/tcp example 3: 只允許port 53進來的udp協定 sudo ufw allow 53/udp Deny 語法如下: sudo ufw deny [port]/[optional: protocol] example 1 : 禁止port 53進來的tcp/udp協定 sudo ufw deny 53 example 2: 只禁止port 53進來的tcp協定 sudo ufw deny 53/tcp example 3: 只禁止port 53進來的udp協定 sudo ufw deny 53/udp
以Services名稱來管理 上一節介紹的是port 防火牆規則的增加和刪除,這一節主要是使用service的名字來制定規則,如果你不知道你目前系統預設service的話,可以看你的檔案『/etc/services』,裡面有很多定義,講白一點就是一定要這個檔案有定義,你才可以直接用service name來定義防火牆規則。 Allow 如果要允許某個service的通行的話,語法如下: sudo ufw allow [service name] example: 允許ssh sudo ufw allow ssh Deny 如果要禁止某個service的通行的話,語法如下: sudo ufw deny [service name] example: 禁止ssh sudo ufw deny ssh 上一節的port rule和這一節的 service rule其實算是同一件事,只是要看有沒有定義,就像是底下這個案例可以達到樣效果(因為dns就是用port 53): sudo ufw allow dns sudo ufw allow 53
以Package名稱來管理 除了上面提過的用Service name來制定某些port的規則,還有另外一種方式,是使用安裝的軟體為單位來制定規則,但是這部份需要依賴profile,這些profile都位於『/etc/ufw/applications.d/』,你可以直接檢視這些profile或是使用底下語法查看: sudo ufw app list 得出底下結果: Available applications: Apache Apache Full Apache Secure CUPS Samba 列出profile內容可用底下語法: sudo ufw app info Samba 接下來如果要允許軟體samba的所有port通過的話,使用底下指令: sudo ufw allow Samba 或者是使用更進階的設定,設定區網內對samba的存取: ufw allow from 192.168.0.0/24 to any app Samba 至於如果本身軟體沒有profile沒有在系統裡,你想要新增的話,這部份就需要自己撰寫,那如果想要變成官方的預設profile的話,就要在官方Launchpad對這個軟體發起一個bug如下: ubuntu-bug nameofpackage
特定 IP管理 這一節介紹如何對特定IP制定防火牆規則,語法如下: Allow sudo ufw allow from [ip address] example : 假設要允許IP 192.168.1.12來的封包 sudo ufw allow from 192.268.1.12 Deny sudo ufw deny from [ip address] example : 假設要封鎖IP 192.168.1.12來的封包 sudo ufw deny from 192.268.1.12
子網域管理 如果想要針對特定區段(像是只限定同一個區網裡面的封包才能進入)去制定防火牆規則,語法如下: Allow sudo ufw allow from [ip address]/[mask] example: 允許192.168.1.0 ~ 192.168.1.255的封包進入 sudo ufw allow from 192.168.1.0/24 Deny sudo ufw deny from [ip address]/[mask] example: 禁止192.168.1.0 ~ 192.168.1.255的封包進入 sudo ufw deny from 192.168.1.0/24
特定 IP + Port 針對特定IP可以存取本機哪些port去制定規則,語法如下: Allow sudo ufw allow from [target] to [destination/protocal] port [port number] example: 允許IP 192.168.1.12來存取本機 port 22 (udp/tcp) sudo ufw allow from 192.168.1.12 to any port 22 Deny sudo ufw deny from [target] to [destination/protocal] port [port number] example: 拒絕IP 192.168.1.12來存取本機的port 22 (udp/tcp) sudo ufw deny from 192.168.1.12 to any port 22
特定IP + Port +特定協定 跟上一節很像,現在某個IP對本機的某個port存取,但是指定『tcp』或『udp』,語法如下: Allow sudo ufw allow from [target] to [destination] port [port number] proto [protocol name] example: 允許IP 192.168.1.12存取本機的port 22,而且只能是tcp sudo ufw allow from 192.168.1.12 to any port 22 proto tcp Deny sudo ufw deny from [target] to [destination] port [port number] proto [protocol name] example: 禁止IP 192.168.1.12存取本機的port 22,而且只有tcp sudo ufw deny from 192.168.1.12 to any port 22 proto tcp
允許/拒絕 PING UWF預設是沒有封鎖外部Ping本機的,如果你要讓外面沒辦法Ping本機的話,你需要修改檔案『/etc/ufw/before.rules』,你有以下兩種方式: #尋找底下的部份並刪掉 # ok icmp codes -A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT -A ufw-before-input -p icmp --icmp-type source-quench -j ACCEPT -A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT -A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT -A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT 或者是 #將這部份的『ACCEPT』改成『DROP』 # ok icmp codes -A ufw-before-input -p icmp --icmp-type destination-unreachable -j DROP -A ufw-before-input -p icmp --icmp-type source-quench -j DROP -A ufw-before-input -p icmp --icmp-type time-exceeded -j DROP -A ufw-before-input -p icmp --icmp-type parameter-problem -j DROP -A ufw-before-input -p icmp --icmp-type echo-request -j DROP
使用 numbered參數 前面有介紹過如果顯示狀態的指令加了參數-『numbered』,前面會有個索引值,如下顯示: ufw status numbered Status: active To Action From -- ------ ---- [ 1] Anywhere ALLOW IN 192.168.1.12 [ 2] Anywhere ALLOW IN 192.168.1.0/24 [ 3] 22/tcp ALLOW IN 192.168.1.12 其實這些索引值蠻重要的,因為用過iptables的人就知道,防火牆規則是有順序性的,後來的規則有可能會被之前的規則所擋掉,底下兩個主題是關於索引值的應用。 使用index刪除規則 刪除規則如果不想要像一樣打一長串的話,可以使用索引值來刪,像是如果要刪除上面的第一條規則的話: sudo ufw delete 1 在索引值位置增加規則 如果想要在特定的索引值位置加入規則,底下的例子是說在索引值為1的地方加入一條規則: sudo ufw insert 1 allow from 192.168.1.1
IP Masquerading 這個設定會牽涉到NAT的觀念,簡介可以參考我的上一篇firewalld的文章,『firewalld』,詳細內容一樣請參考鳥哥。 在UFW裡面要設定IP Masquerading就要使用客製化的ufw規則,因為目前UFW的後端還是使用iptables-restore,所有的規則檔都在『/etc/ufw/*』裡面。這部份的規則分為兩個部份,在UFW之前和UFW之後。其步驟如下描述: 1. 在UFW的sysctl 開啟ip-forward功能『/etc/ufw/sysctl.conf』: net/ipv4/ip_forward=1 如果是ipv6: net/ipv6/conf/default/forwarding=1 2. 在UFW裡面設定接受ip-forward『/etc/default/ufw』: DEFAULT_FORWARD_POLICY="ACCEPT" 3. 在『/etc/ufw/before.rules』裡面新增規則: # nat Table rules *nat :POSTROUTING ACCEPT [0:0] # Forward traffic from eth1 through eth0. -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE # don't delete the 'COMMIT' line or these nat table rules won't be processed COMMIT 注意一定要加在檔案最上頭,而那個『COMMIT』一定要在檔案的最後面。 4. 重啟UFW sudo ufw disable && sudo ufw enable
進階範例 底下有個比較進階的例子來說明如何使用防火牆的思維,假設現在你有個需求是: 1. 禁止IP 192.168.0.1 存取你的port 22。 2. 禁止IP 192.168.0.7 存取你的port 22。 3. 允許其他在192.168.0.0 ~ 192.168.0.255的IP存取你的 port 22。 則防火牆規則語法如下: sudo ufw deny from 192.168.0.1 to any port 22 sudo ufw deny from 192.168.0.7 to any port 22 sudo ufw allow from 192.168.0.0/24 to any port 22 proto tcp 接下來檢查狀態: sudo ufw status Firewall loaded To Action From -- ------ ---- 22:tcp DENY 192.168.0.1 22:udp DENY 192.168.0.1 22:tcp DENY 192.168.0.7 22:udp DENY 192.168.0.7 22:tcp ALLOW 192.168.0.0/24 這時候你又想要新增加一條規則: 1. 禁止IP 192.168.0.3 存取你的port 22。 一般如果你只是直接新增一條規則在最底下的話,像: sudo ufw deny from 192.168.0.3 to any port 22 你會發現怎麼192.168.0.3這台主機還是可以存取你的port 22,因為到底下這條規則時,就已經出去了: 22:tcp ALLOW 192.168.0.0/24 所以你應該要將你的規則給放在這條規則的上面: sudo ufw insert 1 deny from 192.168.0.3 to any port 22 然後就會變成這樣: sudo ufw status Firewall loaded To Action From -- ------ ---- 22:tcp DENY 192.168.0.1 22:udp DENY 192.168.0.1 22:tcp DENY 192.168.0.7 22:udp DENY 192.168.0.7 22:tcp DENY 192.168.0.3 22:udp DENY 192.168.0.3 22:tcp ALLOW 192.168.0.0/24 所以當你制定的規則沒效果時,這時候就要記得看一下你的順序是不是有牴觸。
Dry run ufw畢竟只是netfilter的前端,所以你用ufw status所看到的也只是最上層的規則,如果你想要看到這個命令底下所建立的iptables進階命令的話,可以使用『dry run』,這個參數只會列出,但是不會套用這個指令,底下是個例子: 我如果要看如果允許http協定時,底下所產生的命令,但是又不要套用它時,下以下指令: sudo ufw --dry-run allow http 輸出就會如以下: *filter :ufw-user-input - [0:0] :ufw-user-output - [0:0] :ufw-user-forward - [0:0] :ufw-user-limit - [0:0] :ufw-user-limit-accept - [0:0] ### RULES ### ### tuple ### allow tcp 80 0.0.0.0/0 any 0.0.0.0/0 -A ufw-user-input -p tcp --dport 80 -j ACCEPT ### END RULES ### -A ufw-user-input -j RETURN -A ufw-user-output -j RETURN -A ufw-user-forward -j RETURN -A ufw-user-limit -m limit --limit 3/minute -j LOG --log-prefix "[UFW LIMIT]: " -A ufw-user-limit -j REJECT -A ufw-user-limit-accept -j ACCEPT COMMIT Rules updated
Logging 雖然說如果有防火牆訊息的話可以經由dmesg來看,但是有時候還是想要把它寫到log裡,ufw本身就有這個功能,可以將防火牆訊息紀錄到路徑『/var/log/ufw.log』底下,語法如下: sudo ufw logging on sudo ufw logging off
Log 參數說明 上面有介紹過怎麼把ufw的log功能打開,這邊來解釋一下log的每筆紀錄的欄位的意義。 假設log裡面有一筆紀錄如下: Feb 4 23:33:37 hostname kernel: [ 3529.289825] [UFW BLOCK] IN=eth0 OUT= MAC=00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd SRC=444.333.222.111 DST=111.222.333.444 LEN=103 TOS=0x00 PREC=0x00 TTL=52 ID=0 DF PROTO=UDP SPT=53 DPT=36427 LEN=83 Date 如果你發現時間的順序不符邏輯,或是有一段的紀錄不見了,那可能有人曾經攻擊過你的電腦。 Hostname 那台主機的名稱。 Uptime 從開機以後的秒數。 Logged Event 簡短的介紹這次紀錄的原因,像是[UFW BLOCK]。 IN 如果有值的話,代表是個封包進入的事件。 OUT 如果有值的話,代表示封包送出的事件。 MAC 那台電腦的MAC值。 SRC 最初送出這個封包的IP位址。 DST 這個封包的目的地,你可以使用網頁whois.net或是cli-『whois』來查看這個ip的擁有者。 LEN 這個封包的長度。 TOS IPV4標頭檔的TOS欄位,詳細請參考 TCP Processing of the IPv4 Precedence Field。 PREC IPV4標頭檔的Precedence欄位。 TTL 這個封包的『Time to live』,也就是存活時間,每經過一個router就會減少1。詳細內容請參考: Time o live。 ID 根據官網,這個欄位不卻定是什麼,有可能是ufw的內部系統ID,也有可能是作業系統的ID。 PROTO 顯示這個封包是UDP還是TCP。 SPT 來源端的port值。 DPT 目的端的port值。 WINDOW 代表傳送者會收到的封包size。 RES 保留區,目前沒在用,所以都設定為0。 SYN URGP SYN代表這個連線需要『three-why handshake』,通常會是TCP協定。URGP代表是否跟『urgent pointer field』有關系。
其他 其他相關的資源如下: 1. official server guide 2. 使用『man ufw』或是參考網頁man page 3. 想要補充多一點防火牆的知識 --> Firewall 4. 想要多了解kernel裡面netfilter subsystem的介面 --> Iptables 5. UFW的wiki頁面 --> UncomplicatedFirewall 6. 想要了解UFW GUI --> Gufw
REF: https://wiki.ubuntu.com/UncomplicatedFirewall?action=show&redirect=UbuntuFirewall https://help.ubuntu.com/community/UFW

No comments:

Post a Comment