搜尋此網誌

2013年9月23日 星期一

[工具介紹] 利用 knockd 實現複雜的敲門機制

funny-bear-knocking-door去年我介紹過如何利用 iptables 的 recent 模組來保護如 ssh 之類的網路服務。今天我要介紹的這個服務 – knockd,也可以達成類似的目的。不過不同於 iptables 的作法,knockd 可以輕鬆支援用多個網路埠的組合當做敲門的鑰匙,而且這些網路埠並不會對敲門動作的封包有所回應,可以達到更高的隱密性。此外,如果要保護的服務一多,將保護機制獨立在 iptables 的規則設定之外,也可以簡化 iptables 的複雜度,以避免設定錯誤的情況發生。
在今天的範例中,我們需要兩台 Linux 主機,其中一台當做利用 knockd 機制保護 ssh 服務的主機 (名稱為 knockd.cyril.idv,IP 位址為 192.168.199.103),另外一台用戶端電腦則是用來測試是否可以正常連上受保護的 ssh 服務 (名稱為 client.cyril.idv,IP位址為 192.168.199.102)。採用的 Linux 版本為 32 位元的 CentOS 6.4。為了測試方便,我們在兩台電腦的 /etc/hosts 各加上下列設定:
192.168.199.102 client.cyril.idv client
192.168.199.103 knockd.cyril.idv knockd
接下來,我們就一步步完成今天的範例。

第一階段 安裝與設定 knockd 服務
此階段的操作皆在 ssh 服務主機 (knockd.cyril.idv) 上進行。
  1. 加入對應的 repo
    新增檔案 /etc/yum.repos.d/nux-misc.repo 並加入下列內容
    [nux-misc]
    name=Nux Misc
    baseurl=http://li.nux.ro/download/nux/misc/el6/i386/
    enabled=0
    gpgcheck=1
    gpgkey=http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro
  2. 安裝 knock 服務
    指令是
    [root@knockd ~]# yum --enablerepo=nux-misc install knock-server –y
  3. 將目前執行中的防火牆規則導入至檔案
    指令是
    [root@knockd ~]# iptables-save > /tmp/iptables.sav
  4. 修改防火牆規則檔案
    直接修改上述檔案,將內容改為
    # Generated by iptables-save v1.4.7 on Mon Aug 17 21:32:51 2012
    *filter
    :INPUT DROP [0:0]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [149:22436]
    -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    -A INPUT -p icmp -j ACCEPT
    -A INPUT -i lo -j ACCEPT
    -A FORWARD -j REJECT --reject-with icmp-host-prohibited
    COMMIT
    # Completed on Mon Dec 17 21:32:51 2012
    除了將 INPUT 的預設動作由 ACCEPT 改為 DROP 之外,也移除掉原本 ssh 服務 (TCP Port 22) 的開放規則。
  5. 匯入新的防火牆規則
    指令是
    [root@knockd ~]# iptables-restore < /tmp/iptables.sav
  6. 移除防火牆規則檔案
    指令是
    [root@knockd ~]# rm –f /tmp/iptables.sav
  7. 確認目前的防火牆規則
    指令是
    [root@knockd ~]# iptables-save
    應可以看到類似下列的訊息:
    # Generated by iptables-save v1.4.7 on Mon Aug 17 21:42:57 2012
    *filter
    :INPUT DROP [17:1672]
    :FORWARD ACCEPT [0:0]
    :OUTPUT ACCEPT [149:22436]
    -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    -A INPUT -p icmp -j ACCEPT
    -A INPUT -i lo -j ACCEPT
    -A FORWARD -j REJECT --reject-with icmp-host-prohibited
    COMMIT
    # Completed on Mon Dec 17 21:42:57 2012
  8. 將目前的防火牆規則寫入系統設定
    指令是
    [root@knockd ~]# service iptables save
  9. 設定 knockd
    knock 服務預設的設定檔是 /etc/knockd.conf,修改成如下:
    [options]
            UseSyslog
    
    [opencloseSSH]
            sequence      = 4567:tcp,5678:tcp,6789:tcp
            seq_timeout   = 15
            tcpflags      = syn
            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
  10. 設定 knock 服務自動啟動
    指令是
    [root@knockd ~]# chkconfig knockd on
  11. 啟動 knock 服務
    指令是
    [root@knockd ~]# service knockd start

第二階段 安裝 knock 用戶端程式
雖然 knock 使用的敲門技術可以透過許多工具來產生所需的敲門封包,但是使用 knock 內建的工具可以簡化指令的操作。不過如果要進行比較複雜的敲門動作 (也就是送出比較複雜的封包),那就還是必須借助更複雜的封包產生工具了。
此階段的操作皆在 ssh 用戶端電腦 (client.cyril.idv) 上進行。
  1. 加入對應的 repo
    新增檔案 /etc/yum.repos.d/nux-misc.repo 並加入下列內容
    [nux-misc]
    name=Nux Misc
    baseurl=http://li.nux.ro/download/nux/misc/el6/i386/
    enabled=0
    gpgcheck=1
    gpgkey=http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro
  2. 安裝 knock 用戶端工具
    指令是
    [root@client ~]# yum install --enablerepo=nux-misc knock –y

第三階段 測試 knock 機制
  1. 直接嘗試連結 ssh 服務
    指令是
    [root@client ~]# ssh knockd
    我們發現指令一直沒有回應,必須透過 Ctrl-C 才能跳脫。
  2. 使用敲門機制
    指令是
    [root@client ~]# knock knockd 4567:tcp 5678:tcp 6789:tcp && ssh knockd
    此時我們應該可以透過 ssh 服務正常連結至主機 knockd (192.168.199.103),並看到類似下列訊息:
    Last login: Mon Aug 17 21:40:42 2012 from client.cyril.idv
    [root@knockd ~]#
  3. 檢查 knock 服務的日誌
    knock 服務預設會將日誌寫入 /var/log/secure 這個檔案中,在 ssh 服務主機 (192.168.199.103) 我們可以看到類似下列的訊息
    Aug 17 21:45:31 knockd knockd: waiting for child processes...
    Aug 17 21:45:31 knockd knockd: shutting down
    Aug 17 21:45:31 knockd knockd: starting up, listening on eth0
    Aug 17 21:45:42 knockd knockd: 192.168.199.102: opencloseSSH: Stage 1
    Aug 17 21:45:42 knockd knockd: 192.168.199.102: opencloseSSH: Stage 2
    Aug 17 21:45:42 knockd knockd: 192.168.199.102: opencloseSSH: Stage 3
    Aug 17 21:45:42 knockd knockd: 192.168.199.102: opencloseSSH: OPEN SESAME
    Aug 17 21:45:42 knockd knockd: opencloseSSH: running command: /sbin/iptables -A INPUT -s 192.168.199.102 -p tcp --dport ssh -j ACCEPT
    Aug 17 21:45:42 knockd sshd[2472]: Accepted publickey for root from 192.168.199.102 port 52920 ssh2
    Aug 17 21:45:42 knockd sshd[2472]: pam_unix(sshd:session): session opened for user root by (uid=0)
    Aug 17 21:45:52 knockd knockd: 192.168.199.102: opencloseSSH: command timeout
    Aug 17 21:45:52 knockd knockd: opencloseSSH: running command: /sbin/iptables -D INPUT -s 192.168.199.102 -p tcp --dport ssh -j ACCEPT
透過 knock 所提供的敲門機制,我們可以建立起複雜的敲門機制。以上述的例子而言,我們必須依序連接 3 個 TCP 埠,才能順利連結 ssh 服務。除了 TCP 埠,我們也可以選擇 UDP 埠。而因為對 knock 機制而言,其實只是在接受到敲門訊息後呼叫特定的指令,所以除了 iptables 的指令外,也可以用來呼叫其他指令,以達成不同的管理目的。

About