芝麻開門 Port-knocking

如果你有一臺公眾可訪問的伺服器,指令碼小子可以輕鬆掃描其IP地址,查詢伺服器上的開放埠(尤其是用於SSH的埠22),然後暴力破解。

防止SSH埠被暴力破解一般有以下幾種方式

1。修改預設埠22為其它埠

2。禁止密碼登陸,只允許金鑰登陸或者使用PAM模組開啟二次認證

3。使用ipfailban遮蔽暴力登陸的IP

除了以上幾種做法,還有一種安全加固的手段叫port knocking。如字面意思,類似‘敲門’,只是這裡敲的是‘埠’,而且需要按照順序‘敲’埠。如果敲擊規則匹配,則可以讓防火牆實時更改策略。從而達到開關防火牆的目的。

簡單的做法是安裝knockd。knockd是一種埠試探伺服器工具。它偵聽乙太網或其他可用介面上的所有流量,等待特殊序列的埠命中(port-hit)。telnet或Putty等客戶軟體透過向伺服器上的埠傳送TCP或資料包來啟動埠命中。

官網:https://zeroflux。org/projects。。。

安裝

並沒有yum源,所以只能自己編譯安裝

wget http://www。zeroflux。org/proj/knock/files/knock-0。8。tar。gzyum install libpcap-develyum install autoconfautoreconf -fi。/configure ——prefix=/usr/localmakesudo make installcp knockd。conf /etc/knockd -V

啟動服務

knockd -i ens192 -d -v

配置 knockd 服務

使用預設的配置檔案

cat /etc/knockd。conf[options] UseSyslog[openSSH] sequence = 7000,8000,9000 seq_timeout = 5 command = /sbin/iptables -A INPUT -s %IP% -p tcp ——dport 22 -j ACCEPT tcpflags = syn[closeSSH] sequence = 9000,8000,7000 seq_timeout = 5 command = /sbin/iptables -D INPUT -s %IP% -p tcp ——dport 22 -j ACCEPT tcpflags = syn

配置檔案裡有兩個引數:

sequence:按照順序依次訪問埠,command執行的條件。比如這裡是依次訪問7000, 8000, 9000埠,預設使用TCP訪問。

command:當knockd監測到sequence埠訪問完成,然後執行此處command,這裡為透過iptables開啟關閉ssh外部訪問。

構造knock sequence

直接手工構造

開啟 SSH iptables

telnet 7000telnet 8000telnet 9000

關閉 SSH iptables

telnet 9000telnet 8000telnet 7000

使用knock程式開啟 knock 7000 8000 9000 關閉 knock 9000 8000 7000

NC 或者 NmapOpen: nc -z 7000 8000 9000 Close: nc -z 9000 8000 7000 for x in 7000 8000 9000; do nmap -Pn ——host_timeout 201 ——max-retries 0 -p $x ; done一般情況到這裡就完了。但如果只是cv大法的話,就沒必要寫這篇文章了。

這裡有坑

按照預設配置,我以為這樣敲門knock -v 10。180。249。61 7000 8000 9000 應該是順理成章的,結果它給我來了這個

[root@manager knock-0。8]# knockd -i ens192 -vlistening on ens192。。。10。180。205。102: openSSH: Stage 110。180。205。102: openSSH: Stage 110。180。205。102: openSSH: Stage 110。180。205。102: openSSH: Stage 210。180。205。102: closeSSH: Stage 110。180。205。102: closeSSH: Stage 110。180。205。102: closeSSH: Stage 110。180。205。102: closeSSH: Stage 210。180。205。102: openSSH: Stage 110。180。205。102: openSSH: Stage 110。180。205。102: openSSH: Stage 1

咦,它把敲門訊號當成關門訊號了,好吧,我把敲門埠和關門埠全部設定成不同的埠,然而,依然是莫名奇妙的輸出,並不是我預料中的Stage 1,Stage 2,Stage 3 ,command這樣的執行日誌。能收到第一個和第二個訊號,但是第三個訊號無論如何都收不到。莫非前人欺我?

改成敲門,關門只接收兩個訊號

PS C:\Windows> telnet 10。180。249。61 7000正在連線10。180。249。61。。。無法開啟到主機的連線。 在埠 7000: 連線失敗PS C:\Windows> telnet 10。180。249。61 8000正在連線10。180。249。61。。。無法開啟到主機的連線。 在埠 8000: 連線失敗[root@manager knock-0。8]# knockd -i ens192 -vlistening on ens192。。。10。180。205。102: openSSH: Stage 110。180。205。102: openSSH: Stage 110。180。205。102: openSSH: Stage 110。180。205。102: openSSH: Stage 210。180。205。102: openSSH: OPEN SESAMEopenSSH: running command: /usr/sbin/iptables -A INPUT -s 10。180。205。102 -p tcp ——dport 22 -j ACCEPT[root@manager ~]# iptables -LChain INPUT (policy ACCEPT)target prot opt source destinationACCEPT tcp —— 10。180。205。102 anywhere tcp dpt:sshChain FORWARD (policy ACCEPT)target prot opt source destinationChain OUTPUT (policy ACCEPT)target prot opt source destination

也就是說,knock只能接收兩個敲門訊號,超過兩個就會導致敲不開門,關不了門。這是一個bug嗎?

機率是因為ip包到達伺服器的時間有可能是亂序的,這會導致敲門失敗,如果遇到只看到open/closeSSH: Stage 1或者open/closeSSH: Stage 2,看不到opencloseSSH: Stage 3的情況,可以多試幾次,或者手工依次執行。如果還是不行,建議檢查埠是否被佔用。如果最後依然不行,結論還是屬於knockd對tcp訊號處理的bug,不建議配置超出兩個的敲門訊號。

至於iptables的應用就不再細數了。另外,為了在重啟的過程儲存和恢復iptables設定,我們可以在knockd命令中增加相應的iptables-save和iptables-restore操作。

看來knock還是有一定侷限性。有沒有其它工具呢。knock官網也推薦了替代工具doorman和pasmal。

簡單直接不依賴三方工具實現Port-knocking

還有更簡單的嗎?直接用iptables就能搞定,先在伺服器新增兩條策略

iptables \ -i eth0 \ -t raw ——append PREROUTING \ -p tcp ——dport 8080 ——syn \ -m recent ——name knocked ! ——rcheck ——seconds 600 \ -j DROPiptables \ -i eth0 \ -t raw ——append PREROUTING \ -p udp ——dport 30000 \ -m string ——string “OpenSesame” ——algo bm \ -m recent ——name knocked ——set \ -j DROP

然後測試下

[root@manager ~]# yum install -y socat[root@manager ~]# curl -i ——connect-timeout 5 http://146。56。248。195:8080/hellocurl: (28) Connection timed out after 5001 milliseconds[root@manager ~]# echo “OpenSesame” | socat - udp4-datagram:146。56。248。195:30000[root@manager ~]# curl -i ——connect-timeout 5 http://146。56。248。195:8080/helloHTTP/1。1 200 OKDate: Tue, 27 Jul 2021 02:38:47 GMTContent-Type: text/plainContent-Length: 21Connection: keep-aliveExpires: Tue, 27 Jul 2021 02:38:46 GMTCache-Control: no-cachecontent-type: text/html

Hello World!

[root@manager ~]#

芝麻開門 Port-knocking

會敲門了,相信關門也會了。

Port-knocking 並不能作為一種獨立的安全防禦措施,因為它屬於security by obscurity。多種策略組合,才能提高系統的安全性