伺服器架設篇 - 其他文件

使用 knock 管理防火牆相關行為

knock 為一個好用的程式,可用以開放某些特定服務的防火牆功能

最近更新時間: 2007/09/22

『為自己開一個後門』是很多系統管理員常常需要思考的問題,因為我們常常需要在不同的環境裡面連線到主機去! 為了自己管理的方便,總希望可以這麼做。但是如此一來又擔心系統的網路安全問題。 所以,一般來說,為自己開一個後門最好是允許可信任的固定 IP 連線,這樣最簡單與單純, 而且,當然不要針對整個 Internet 開放具有較高危險的服務,舉例來說 ssh 就是其中一個啊!

不過,如果用戶端是非固定的 IP 時,這個時候難道要將伺服器的服務針對 Internet 進行開放嗎? 當然不行啦~如此一來,防火牆怎麼設計啊?真是很困擾!好在,這個 knockd 可以幫我們處理這個問題呢!

防火牆基礎

一部伺服器的維護與管理當中,最重要的是更新所提供的服務之軟體程式, 以避免可能會遭人入侵的漏洞問題。舉例來說,如果開放 WWW 就得要隨時更新 Apache 這支程式才好。 再來則是訂定一系列的災難復原標準操作行為,接下來才是防火牆的設定。所以說,防火牆的重要性還比不上軟體更新喔! 但是防火牆還是有他存在的必要啦,底下來簡單的說一說原因吧。

一般來說,在 Linux 伺服器上頭的封包過濾式防火牆主要有兩種,(1)是 Linux 核心支援的 iptables , (2)則是利用 TCP Wrappers (或 xinetd 這個 super daemon) ,亦即是利用 /etc/hosts.allow, /etc/hosts.deny 這兩個檔案來管理的方式。利用 iptables 可以即時更新防火牆機制,而且效能也是很不錯的。 至於使用 TCP Wrappers 的話,那就得要針對 /etc/hosts.{allow,deny} 修修改改的囉。

基本上,只要妳想要架設防火牆的話,就得要針對特定或不特定的 IP 來源進行開放或拒絕的動作。 所謂的『特定』指的是例如 192.168.0.0/24 或者是某個特定的 IP 或主機名稱,或者是某個特定的協定 (如 port 80) 等。 而不特定在這裡的意思表示針對整個 Internet 開放的意思。如果妳對於防火牆還有其他的問題, 可以先參考一下鳥哥之前寫的一篇 簡易防火牆 再說。 在這一章當中,鳥哥假設您已經學會 iptables 的相關語法與觀察的指令了。

雖然很多人都覺得防火牆是一部主機管理上最重要的地方,但其實鳥哥之前就曾談過, 防火牆基本上是沒有什麼用途的! ^_^!因為無論如何,妳都得要開放某些服務給用戶端登入對吧! 如此一來,防火牆當然無法抵擋對你所開放的服務之連線啦! 但防火牆也不是一無用處,至少他可以將伺服器所提供的網路服務『侷限』在某些特定的範圍內。 怎麼說呢?底下我們來舉個例子好了。

鳥哥有些 Linux 主機放置到崑山科大資訊傳播系內, 而且鳥哥常常需要在沒有固定 IP 的地方連線到這部主機上面進行操作,以秀給大家看一下主機的設定或者是一些 Linux 相關議題。 因為鳥哥所在的用戶端沒有固定 IP ,所以是否就得要針對整個 Internet 來開放那個可怕的 sshd 的服務嗎? 要注意, sshd 可是個很危險的服務喔,因為只要使用者登入主機,那麼他能夠作的事情實在太多了! 所以不要將 sshd 對整個 Internet 開放才好。您說是吧?

既然 sshd 不對整個 Internet 開放,然而鳥哥所在的位置又是非固定 IP 的來源,那我這部 Linux server 的防火牆要如何針對 sshd 進行設定啊?難道無解嗎?呵呵!沒問題,我們可以利用 knockd 這個 daemon 來負責的啦! 底下我們就來談一談 knockd 這個咚咚吧!

knockd 的使用

為了解決非固定 IP 來源用戶端的連線問題,我們可能得要手動的加入用戶端的防火牆設定於防火牆規則當中。 這很麻煩啦!那有沒有自動的方式可以讓防火牆規則自動的修改的?是有的~那就是利用 knockd 這個服務。 底下讓我們來談談這個玩意兒的特色與使用方式吧!

knockd 的功能與特色

knockd 主要的目的是希望可以動態的修改防火牆規則,他的運作流程是這樣的:
  1. 伺服器端的防火牆規則中先開放三個左右的埠口,這些埠口沒有被其他程式啟用,且可由 knockd 所偵測;
  2. 用戶端若依照設定的順序依序的連線到這三個埠口時, knockd 將進行動態防火牆規則的設定
  3. 防火牆規則被修改,且 knockd 持續進行偵測;
  4. 當用戶端讓 knockd 等候逾時,或者是用戶端離線後,剛剛步驟三的防火牆規則將會被移除。
如此一來,當我在非固定 IP 的網段想要連線到伺服器時,就可以透過這個機制來處理啦! 整個流程有點像底下的圖示:

knockd 的處理流程
圖一-a、用戶端必須要『依序』對某些埠口進行連線的動作

knockd 的處理流程
圖一-b、若通過 knockd 對埠口的設定,則 knockd 會動態的增加防火牆規則,且用戶端可以連線了

knockd 的處理流程
圖一-c、若用戶端離線,或者是 knockd 等待逾時,則 knockd 可主動的刪除剛剛建立的規則

您可以看到,防火牆的規則本來是關閉的,然後在用戶端依序碰觸某些埠口後, knockd 就能夠『僅針對此一 IP』啟動某些特定的埠口,此時用戶端就能夠透過這個特殊的埠口進行主機的連線。 並且可以在用戶端斷線後,將該防火牆規則拿掉!呵呵!如此一來,我們不論是在何處, 就可以使用這個功能來開啟某些比較危險的服務啦,例如 sshd 這個 port 22 囉!

knockd 的安裝

knockd 的安裝非常簡單,因為他除了提供 Tarball 之外,還提供 SRPM 哩!所以安裝方面非常容易! 鳥哥是將 knockd 安裝在 CentOS 5.x 上面的,所以使用 RPM 來測試給大家看看。 如果妳想要安裝 Tarball 的話,可以參考這一篇的說明: Tarball 與原始碼 。至於 knockd 的下載可以參考: 讓我們開始安裝吧!
1. 先下載這個軟體吧!
[root@linux ~]# wget  \
> http://www.invoca.ch/pub/packages/knock/knock-0.5-4.src.rpm

2. 開始編譯成為 RPM 檔案!
[root@linux ~]# rpmbuild --rebuild knock-0.5-4.src.rpm
Installing knock-0.5-4.src.rpm
error: Failed build dependencies:
        libpcap-devel is needed by knock-0.5-4.i386
# 如果出現類似上述的訊息,表示妳還有某些關鍵套件未安裝,請自行使用 yum 安裝
# 此外,請確認你已經安裝了發展工具組,包括 gcc, glibc-devel 等等,
# 當然,若有需要時,可以安裝整個發展工具套件: 
# yum groupinstall "Development Tools"

[root@linux ~]# rpmbuild --rebuild knock-0.5-4.src.rpm
Installing knock-0.5-4.src.rpm
Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.42725
+ umask 022
+ cd /usr/src/redhat/BUILD
.....(中間省略).....
Wrote: /usr/src/redhat/RPMS/i386/knock-0.5-4.i386.rpm
Wrote: /usr/src/redhat/RPMS/i386/knock-server-0.5-4.i386.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.26785
.....(底下省略).....
# 至少要出現如上的粗體字,才是正確的編譯成功喔!接下來準備安裝!

[root@linux ~]# rpm -ivh /usr/src/redhat/RPMS/i386/knock-*
Preparing...           ################################# [100%]
   1:knock-server      ################################# [ 50%]
   2:knock             ################################# [100%]
# 那個 knock 是 client 端的指令, knock-server 才是伺服器端的軟體!
有夠簡單吧!這樣就安裝妥當了~妳可以使用 rpm -ql knockd 及 rpm -ql knockd-server 去看看有啥資料在這個套件中, 然後可以使用 man knock 及 man knockd 分別察看 client/server 端的設定方法! 底下我們就開始來設定 knockd 吧!

knockd 的設定與啟動--以 SSH 為例

在開始玩 knockd 之前,請務必使用 man knockd 去查閱一下詳細的設定方法, 這很重要啊!不然妳不會知道底下設定檔的意義喔!好了,我們知道 knockd 是藉由偵測 port 來動態進行防火牆規則的修改, 所以我們當然就得要有設定檔啦。使用 RPM 安裝時,預設的設定檔在 /etc/knockd.conf , 這個檔案的原始內容是這樣的:
[root@linux ~]# vi /etc/knockd.conf
[options]
    UseSyslog
[opencloseSSH]
    sequence      = 2222:udp,3333:tcp,4444:udp
    seq_timeout   = 15
    tcpflags      = syn,ack
    start_command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport ssh -j ACCEPT
    cmd_timeout   = 10
    stop_command  = /sbin/iptables -D INPUT -s %IP% -p tcp --dport ssh -j ACCEPT
# 各參數的意義可由 man knockd 查到,簡單的說,各設定項目為:
# [options]:	 與 knockd 環境有關的設定資料;
# UseSyslog:	 與 knockd 有關的登入資料使用 syslogd 放置到 /var/log/messages
# [opencloseSSH] 開啟與關閉 SSH 防火牆的設定項目;
# sequence:	 knockd 偵測的埠口與封包協定 (tcp/udp)
# seq_timeout:	 需要在幾『秒鐘』內,連續上面的埠口接觸 (sequence 之設定);
# tcpflags:	 來源封包所需帶有的封包標誌,一般來說, UDP 封包不會有 ack ,
#		 所以上述的預設標籤與封包,其實是無法吻合的,所以需要修改。
# start_command: 若連續接觸所有的埠口,則 knockd 開始後續的指令;
# stop_command:	 若用戶端斷線了,那麼就執行後續的指令
# cmd_timeout:	 若設定 stop_command 則需此設定,訂定開始與結束防火牆的時間。
如上所述,其實預設的設定檔有點小問題的,所以此時我們需要修改一下設定檔才好。 鳥哥的設定檔長的有點像這樣:
[root@linux ~]# vi /etc/knockd.conf
[options]
    LogFile       = /var/log/knockd.log
    Interface     = eth0
    # 鳥哥將登錄檔獨立出來管理,且管制監聽的介面為 eth0

[opencloseSSH]
    sequence      = 2100:tcp,2200:udp,2300:tcp
    seq_timeout   = 15
    tcpflags      = syn
    start_command = /sbin/iptables -A INPUT -s %IP% -p tcp --dport ssh -j ACCEPT
    cmd_timeout   = 30
    # 在開放防火牆後,等待 30 秒,若用戶端沒有動作,則將該規則再關閉
    stop_command  = /sbin/iptables -D INPUT -s %IP% -p tcp --dport ssh -j ACCEPT
設定妥當之後就趕快來啟動他吧!啟動就更簡單了!
[root@linux ~]# /etc/init.d/knockd start
[root@linux ~]# chkconfig knockd on
這樣就搞定了 knockd 了!

knock 用戶端處理方式

既然 knockd 需要接觸伺服器的數個埠口,那麼用戶端該如何接觸呢?很簡單啊~ 妳可以使用 telnet 發送封包,也可以使用 knock 這個用戶端指令來處理。 knock 很不錯的地方,在於他同時提供 Linux/Windows 那個用戶端程式! 鳥哥也建議使用 knock 即可,因為使用 telnet 常常無法成功,真煩人~ 底下讓我們來實際測試看看囉:

用戶端為 Linux 系統

如果用戶端是 Linux 系統時,請前往前面安裝的地方,妳只要安裝 knock 即可,不需要安裝 knock-server 的啦! 那這個程式如何使用呢?非常簡單,只要這樣做即可:
[root@linux ~]# knock -v 192.168.1.254 2100:tcp 2200:udp 2300:tcp
hitting tcp 192.168.1.254:2100
hitting udp 192.168.1.254:2200
hitting tcp 192.168.1.254:2300
knock 之後加上主機名稱,然後後面就是接續的不同的埠口。至於 -v 的參數只是列出 knock 用戶的運作流程而已。 接下來用戶端有 30 秒的時間 (鳥哥的設定檔自訂的,您可以修改此項目) 可以連上主機, 如果超過 30 秒沒有回應的話,那麼該規則就會被再次的刪除喔!如果想要確認有無成功的話, 請到 knockd 主機上面,執行 iptables-save 查閱看看有沒有 IP 列表就知道啦!粉簡單吧!

用戶端為 Windows 系統

若用戶端為 Windows 系統時,knockd 官網已經很好心的將 knock 的用戶端軟體編譯成為 Win32 能執行的二進位檔案 (binary file) ,所以妳可以直接下載來使用。若需下載,請按底下的連結吧:
由於檔案是壓縮檔,因此妳必須要先解壓縮才行。解壓縮完畢後,進入新建的目錄會有底下的檔案:

Windows 用戶端
圖二、Windows 用戶端使用的 knock 軟體

上面的檔案都是原始碼,給大家參考用而已。在那個 Release 目錄內的檔案才是可執行檔。 建議妳可以將檔名為 knock.exe 的檔案 (在 Release 目錄內) 放置到 C:\Windows 底下, 這樣妳才可以在任何地方直接下達 knock 這個指令。接下來請打開 DOS 視窗,亦即『開始』-->『執行』 在出現的視窗當中輸入『 cmd 』,就能夠取得終端機了。之後的指令就如同 Linux 環境囉!

C:\>knock -v 192.168.1.254 2100:tcp 2200:udp 2300:tcp
hitting tcp 192.168.1.254:2100
hitting udp 192.168.1.254:2200
hitting tcp 192.168.1.254:2300
之後再以 pietty (http://ntu.csie.org/~piaip/pietty/) 立刻連上原本的 SSH 主機,嘿嘿!搞定~

參考資料

修改歷史:
2007/09/19:討論區的老周兄一直建議的好軟體,鳥哥來將他寫成簡單的文件吧!
2007/09/22:根據老周的來信,確認 iptables.rule 不需要修改!沒有開放 port 也可以。感謝 jou !

2007/09/19 以來統計人數

其他連結
環境工程模式篇
鳥園討論區
鳥哥舊站

今日 人數統計
昨日 人數統計
本月 人數統計
上月 人數統計