Ubuntu系統開啟 ufw 防火牆之後,iptables -A 和 -I的差異

今天在用 iptables 設定每個IP限制幾個連線時,來回好幾次怎麼設定都不能正常運作,正在納悶到底是怎麼一回事時,我把 -A 的參數改成 -I 之後竟然正常了。所以打算追根究柢看看到底哪裡出了什麼問題了。我們先說說這個命令好了,

iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 10 -j REJECT

一個簡單的 iptables 命令,限制每個 IP 只能 10 個 HTTP 連線,超過就丟棄封包不理它。無奈怎麼都不會正常運作,索性改成

iptables -I INPUT -p tcp --dport 80 -m connlimit --connlimit-above 10 -j REJECT

嘿,竟然正常了。根據 iptables 語法,-A代表是Append附加在既有規則上,-I則是代表Insert添加在最前面,所以我就把整個 iptables 規則 dump 出來看看

# iptables-save > ~/rules

一看規則,明白了,雖然兩行的命令是一樣的,但順序不一樣。一個在 ufw 前面,一個在 ufw 後面。

-A INPUT -p tcp -m tcp --dport 80 -m connlimit --connlimit-above 10 --connlimit-mask 32 --connlimit-sa
(上面的規則是 -I添加進來的)
...
...
...
-A INPUT -j ufw-before-logging-input
-A INPUT -j ufw-before-input
-A INPUT -j ufw-after-input
-A INPUT -j ufw-after-logging-input
-A INPUT -j ufw-reject-input
-A INPUT -j ufw-track-input
-A INPUT -p tcp -m tcp --dport 80 -m connlimit --connlimit-above 10 --connlimit-mask 32 --connlimit-sa
(上面的規則是 -A附加進來的)
...
...

我們知道 iptables 運作規定是由上往下執行,很顯然的,如果採用 -I,因為是添加在最前面,所以運作規則會在 ufw 之前。反之如果採用 -A,那麼附加的規則會在 ufw 之後。但是 ufw 之前已經設定

# ufw allow 80

所以按照 iptables 執行順序,只要是 80 port 的都會被 ufw 允許,所以 -A 添加的規則根本不會執行到,那當然運作就不正常了。而 -I 的命令則在 ufw 之前,所以才能先過濾掉,然後才交給 ufw 判斷,唉,浪費了不少時間。

CubieTruck 安裝設定 ufw 防火牆

一般上來說,在Linux上做防止別人攻擊,就是Windows上俗稱的防火牆,最後都是用 iptables 這隻程式完成的。例如我想要禁止某個 ip 位址連線進來,我只要下

iptables -A INPUT -s 11.22.33.44 -j DROP

11.22.33.44是我舉的例子,請勿輸入這行命令,這樣會把整個11.22.33.44連線給禁止(也許這正是我們想要的),因為 iptables 的功能很強大,很多時候不需要這麼粗魯。也正因為十分常強大,所以十分繁瑣,所以我建議大家先玩玩 ufw。

對了,剛剛那道指令下完之後,你可以使用

iptables -vnL

看看是否設定進去,通常是沒有什麼問題的。但是如果重新開機,這時候就會重新來過。如果想要每次開機都載入這樣的設定,你得把規則存好,這個規則放在 /etc/iptables-rules,指令為

iptables-save > /etc/iptables-rules

有興趣的人可以編輯 /etc/iptables-rules 這個檔案,就像當年在學 sendmail 一樣,裡面的英文字每個都懂,但整個看起來就像天書,有看沒有懂。所以我們先使用 ufw,Uncomplicated Firewall,照字面上的解釋,不複雜的防火牆,名字取的好。

一般 ufw 都已經預設安裝好了,如果沒有的話,去安裝吧。

apt-get install ufw

安裝好之後,在 /etc 目錄下會有個 ufw目錄,這就是裡面的設定了。 /etc/ufw/ufw.conf 裡面就只有兩個設定,開啟和Log。ufw不像iptables,一般狀況下都不需要編輯檔案,只需要下指令,它會自動幫你轉換成 iptables 的命令並且儲存,所以不必煩惱重新開機是否會自動載入。

第一個指令,很多人第一個指令就是 ufw enable,先不要,很多規則都沒有設定好,enable ufw可能會連你自己給搞到斷線。所以先來個

ufw status verbose

他會告訴你目前 防火牆是否開啟,預設連線進來和出去是允許(Allow)或是不可以(Deny),以及是否要記錄(Log)。正常狀況下,你目前一條規則也沒有。

ufw default allow

這條指令是告訴防火牆,預設狀況都讓它進來。沒關係,我們先都讓它進來,等設定好之後再Deny吧。反正這段時間也不會太長。

ufw allow proto tcp from 192.168.1.0/24 to any port 22

這道命令就比較複雜了。照字面上解是,防火牆想要允許tcp協議的封包,但什麼是 192.168.1.0/24呢?IP地址其實是四個8 bit的數字組合成的,分別從0到255。所有一個IP Address總共有32 bits(4*8),字面上的24的意思是說前面的24 bit必須一樣 (192.168.1要一模一樣,每個數字都是8 bit,8 * 3 = 24),但是後面的8(32-24=8) bit可以忽略,這就是我們在Windows常常用的 192.168.1.*的意思。to any port 22就是可以到22 port,協議是tcp。

至於Port的分配,有興趣的人可以到 /etc/services裡面看看,這個檔案會描述所有網路常用的Port號碼,22就是我們常用的SSH。80就是HTTP,以此類推。

所以剛剛那道命令的意思用白話文講就是,允許 192.168.1.*的IP位址的所有TCP封包進來我機器的SSH裡面來處理。為何要設允許,因為之後我們會把預設都設定為 Deny(禁止連線),所以才要一一新增到規則裡面。

SSH事關重大,所以要比較嚴謹一點,限制局網的人才能連線。但對於 HTTP,你總不能讓別人都連不進來吧?這樣什麼網頁也開不了了,所以什麼IP也不用設定了,比較簡單一點,

ufw allow 80

也就是說防火牆允許80 port (HTTP協議,請參考 /etc/services 檔案描述)的封包(沒有限制TCP/UDP)都進來給apache2處理吧。

ufw deny 21

因為 vsftpd (ftp 協議)之前有漏洞,所以只要是 21 port的封包都給丟棄了,不用再通知我了,即便ftp服務存在,它也收不到任何封包的。注意:這道指令會把 FTP 服務給全部禁止,小心使用。

ufw limit 9091

這道指令用到新的關鍵字 limit,限制的意思。就是代表限制某個 port (9091) 在三十秒內,超出六個以上的連線都會被不允許(Deny)。反正這個Port不常用,就用limit湊合著用吧!

其他的協議,就大約是依照這樣的方式設定。

SSH

ufw allow from 192.168.1.0/24 to any port 22

HTTP

ufw allow 80

HTTPS 加密HTTP協議

ufw allow 443

FTP 檔案傳輸協議

ufw deny 21

DNS 域名反查

ufw allow 53

Samba 網路芳鄰(一般只有局網)

ufw allow proto udp from 192.168.1.0/24 to any port 137
ufw allow proto udp from 192.168.1.0/24 to any port 138
ufw allow proto tcp from 192.168.1.0/24 to any port 139
ufw allow proto tcp from 192.168.1.0/24 to any port 445

UPnP(一般只有局網)

ufw allow proto udp from 192.168.1.0/24 to any port 1900
ufw allow proto udp from 192.168.1.0/24 to any port 1901

MiniDLNA(一般只有局網)

ufw allow proto tcp from 192.168.1.0/24 to any port 8200 ; 這在 /etc/minidlna.conf裡面有定義好

但是minidlna會隨機開一個udp port,所以只能全開給它了,不過只有局網UDP協議而已,除非有人入侵到你內部網路了

ufw allow proto udp from 192.168.1.0/24 to any port 1025:65535

1025:65535是只從 1025 Port到65535 Port都打開吧!

Transmission BT程序

ufw limit 9091

至於連線的socket,我還沒有研究,後面再補。

mysql

ufw allow from 192.168.1.0/24 to any port 3306

NTP 校時

ufw allow 123

NFS Server

ufw allow from 192.168.1.0/24 to any port 111
ufw allow from 192.168.1.0/24 to any port 2049
ufw allow from 192.168.1.0/24 to any port 13025

DHCP Server 動態IP分配伺服器

ufw allow proto udp from 192.168.1.0/24 to any port 67
ufw allow proto udp from 192.168.1.0/24 to any port 68

MemCached

ufw allow from 127.0.0.1 to 127.0.0.1 port 11211
ufw allow from 192.168.1.199 to 127.0.0.1 port 11211

PPTP VPN Server

這個比較複雜,不是打開就可以完成,之後再介紹。

看看是否有漏網之魚呢?

netstat -lptu --numeric-ports

一般這樣就夠了,然後下這道指令看看你勞動的成果吧!

ufw status verbose

如果確認沒有問題,就把預設值改為deny(不給連線)

ufw default deny

下這道指令時,它會告訴你可能會斷線,因為你可能使用SSH連線進來(可能你還沒打開),所以要小心。不然你就得重灌系統,或是用Console進來了。

然後正式啟動防火牆

ufw enable

如果要取消防火牆

ufw disable

這過程中如果之後要新增規則也行,但是 ufw 的 Log十分的多,多到你不想看 Log 檔了,這算不算一種Log Flood?如果不要的話,可以把紀錄給關了。這個命令在 ufw –help 裡面沒有的。

ufw logging off

如果有一行命令下錯想要刪除怎麼辦?可以先查看是哪一行有問題

ufw status numbered

它會把所有設定值出來,前面帶有順序號碼。根據這個號碼來進行刪除

ufw delete [number]

過程中可能 ufw 會告訴你 /etc /lib 的目錄權限不對,例如其他 group 可以寫入,你可以使用 chmod 去更改,照它的意思做就沒錯了,比較保險。

好了,先到這裡了。下一講,講講如何使用 ufw 防止 HTTP 暴力連線吧!

使用 iptables 禁止某個網路IP進入

近來有一些人會不斷地想要進入系統,希望他們是出自於學習的角度。不過為了保護系統,所以用 iptables 來禁止某些 ip 進入我的CubieTruck,這些 ip address 可以從 /var/log/auth.log 裡面得知,假定是 11.22.33.44,使用 iptables 來禁止他們進出系統

iptables -I INPUT -s 11.22.33.44 -j DROP
iptables -I OUTPUT -d 11.22.33.44 -j DROP

然後儲存規則,以利下次開機也可以使用

iptables-save > /etc/iptables-rules

如果想要查看目前規則,可以使用

iptables -L

如果要取消某個規則,則可以使用

iptables -D INPUT 剛剛看到的順序號碼

不要忘記修改完,要用 iptables-save 存檔喔。

寫一個 script 可以簡化這個流程

#! /bin/sh
echo "Ban IP for " $1
iptables -I INPUT -s $1 -j DROP
iptables -I OUTPUT -d $1 -j DROP