RHEL9.4安裝knock配置ssh

李蔚發表於2024-11-05

日期:2024.11.3
目的:RHEL9這臺物理機打算實現兩種登入方式,root只能基於key認證登入;另外一個賬戶可以用賬號密碼登入,但是登入埠不開放,透過安裝knock server,順序敲擊預設的埠,才開這個能夠用賬號密碼登入的埠。
參照:

  • 鳥哥Linux私房菜
    https://linux.vbird.org/linux_server/rocky9/0230sshd.php#10.2.2
  • tlanyan大佬的部落格文章:設定SSH埠使用不同認證方式
    https://itlanyan.com/ssh-set-port-specific-authentication/
  • EPEL源官方配置
    https://docs.fedoraproject.org/en-US/epel/getting-started/

knock是基於epel源的,檢視主機是否已經配置了epel

[root@RHEL9 ~]# dnf repolist epel
Updating Subscription Management repositories.
[root@RHEL9 ~]#

參照epel官方配置安裝

[root@RHEL9 ~]# subscription-manager repos --enable codeready-builder-for-rhel-9-$(arch)-rpms && dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm

安裝knock server

[root@RHEL9 ~]# dnf install -y knock-server

看下knock-server配置檔案位置

[root@RHEL9 ~]# rpm -qc knock-server 
/etc/knockd.conf
/etc/sysconfig/knockd

備份一下原來的配置檔案

[root@RHEL9 ~]# cp /etc/knockd.conf{,.bak}
[root@RHEL9 ~]# ll /etc/knockd.conf*
-rw-r--r--. 1 root root 303 Jan 25  2022 /etc/knockd.conf
-rw-r--r--. 1 root root 303 Nov  3 00:26 /etc/knockd.conf.bak

先看下防火牆指令能不能跑通,測試新增和移除一個規則,指定IP訪問22222埠,然後在寫配置檔案時把IP地址換成變數%IP%即可

[root@RHEL9 ~]# firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.5.253" port protocol="tcp" port="22222" accept'
success
[root@RHEL9 ~]# firewall-cmd --list-rich-rules 
rule family="ipv4" source address="192.168.5.253" port port="22222" protocol="tcp" accept
[root@RHEL9 ~]# firewall-cmd --remove-rich-rule='rule family="ipv4" source address="192.168.5.253" port protocol="tcp" port="22222" accept'
success
[root@RHEL9 ~]# firewall-cmd --list-rich-rules 

[root@RHEL9 ~]# 

開始編輯配置檔案

[root@RHEL9 ~]# vim /etc/knockd.conf
[options]
#UseSyslog
#註釋掉上面的使用系統日誌,單獨起一個日誌位置方便除錯時觀察
    LogFile       = /var/log/knockd.log
#監聽的網路卡介面,這裡要聽master的WANbridge,而不能聽slave的enp4s0
    Interface     = WANbridge
[opencloseSSH]
#敲擊埠的順序,我只設定兩個,原因後面會將,其實可以設定多個,只要按照順序依次敲擊就好
    sequence      = 7777:tcp,8888:tcp
#30秒內依次敲上面埠
    seq_timeout   = 30
#tcp的syn握手申請
    tcpflags      = syn 
#新增富規則對敲門的IP開放22222埠
    start_command = /usr/bin/firewall-cmd --add-rich-rule='rule family="ipv4" source address="%IP%" port protocol="tcp" port="22222" accept'
#20秒埠開放時間
    cmd_timeout   = 20
#刪除富規則關閉22222埠
    stop_command  = /usr/bin/firewall-cmd --remove-rich-rule='rule family="ipv4" source address="%IP%" port protocol="tcp" port="22222" accept'

關於敲門的方式,有用nmap敲的,有用knock client敲的,我的路由器有IDS入侵檢測系統
IDS:intrusion detection system
會把敲門的TCP SYN握手當作入侵掃描給攔截掉,所以nmap和knock client都敲不進去。關閉這個選項可以解決,但是我本意是要增強安全性才安裝的knock server,結果為了這個原因反而要關閉入侵檢測的一個功能,結果還把安全性給降低了,我認為得不償失

因此,我選擇直接用瀏覽器敲。直接在瀏覽器裡輸入IP地址:埠號就行。例如:221.229.XX.X1:22222
透過瀏覽器訪問這個埠也是會發起TCP SYN握手,只不過有一個問題,knock要求依次敲擊,但是瀏覽器訪問的時候會連續敲指定的埠直到手動停止,再透過修改位址列裡的埠號訪問下一個指定的埠繼續連續敲,如下所示
knock要求:
向7777埠發起TCP SYN連線1次,進入第一階段
向8888埠發起TCP SYN連線1次,進入第二階段
向9999埠發起TCP SYN連線1次,進入第三階段
每個埠依次敲擊,開門
瀏覽器敲門:
訪問7777埠,發起TCP SYN連線N次,進入第一階段,手動停止
訪問8888埠,發起TCP SYN連線的第1次,就會進入第二階段,然後再發起N次連線,直到手動停止
由於很難控制8888埠只敲1次就停,所以很難達到三個埠依次各敲一次的條件,第三階段幾乎無法達成
因此我僅設定兩個埠,在二階段就開門,雖然安全係數低一點,但是相比關閉路由的TCP SYN入侵檢測來看,我還是選擇這個方案
進入路由器把埠7777和8888轉發到本機

tcpdump監聽7777埠,然後瀏覽器輸入221.229.XX.X1:7777訪問

[root@RHEL9 ~]# tcpdump port 7777
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on enp4s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
02:19:24.639781 IP 221.229.XX.X1.55195 > RHEL9.cbt: Flags [S], seq 495572742, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
02:19:24.639808 IP 221.229.XX.X1.55196 > RHEL9.cbt: Flags [S], seq 1686601064, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0

監聽8888埠也一樣,先確保敲門訊號能夠透過路由器來到主機上

[root@RHEL9 ~]# tcpdump port 8888
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on enp4s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
02:22:20.297021 IP 221.229.XX.X1.55239 > RHEL9.ddi-tcp-1: Flags [S], seq 2212466356, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0
02:22:20.297059 IP 221.229.XX.X1.55240 > RHEL9.ddi-tcp-1: Flags [S], seq 2750412576, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0

起服務,tail -f看日誌,然後瀏覽器準備好依次訪問7777和8888埠

[root@RHEL9 ~]# systemctl enable --now knockd.service
[root@RHEL9 ~]# tail /var/log/knockd.log -f
[2024-11-03 02:59] starting up, listening on WANbridge
[2024-11-03 03:00] 221.229.XX.X1: opencloseSSH: Stage 1
[2024-11-03 03:00] 221.229.XX.X1: opencloseSSH: Stage 1
[2024-11-03 03:00] 221.229.XX.X1: opencloseSSH: Stage 1
[2024-11-03 03:00] 221.229.XX.X1: opencloseSSH: Stage 2
[2024-11-03 03:00] 221.229.XX.X1: opencloseSSH: OPEN SESAME
[2024-11-03 03:00] opencloseSSH: running command: /usr/bin/firewall-cmd --add-rich-rule='rule family="ipv4" source address="221.229.XX.X1" port protocol="tcp" port="22222" accept'

指令生效,防火牆埠開啟
下面進入路由設定轉發,之前是設定62222轉發到本機22埠,現在新增一條將22222埠轉發給本機
想訪問主機22埠,就訪問公網的62222
想訪問主機的22222埠,就訪問公網的22222

開始配置ssh實現埠登入限制。先配置ssh監聽22222埠,目前ssh只監聽預設的22埠

[root@RHEL9 ~]# grep -n \#Port /etc/ssh/sshd_config
21:#Port 22
[root@RHEL9 ~]# cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
[root@RHEL9 ~]# sed -Ei 's/\#Port 22/Port 22/' /etc/ssh/sshd_config
[root@RHEL9 ~]# sed -Ei '/Port 22/a Port 22222' /etc/ssh/sshd_config
[root@RHEL9 ~]# grep -n Port /etc/ssh/sshd_config
21:Port 22
22:Port 22222
101:#GatewayPorts no

重啟下服務

[root@RHEL9 ~]# systemctl restart sshd.service 
[root@RHEL9 ~]# ss -tpln
State     Recv-Q    Send-Q       Local Address:Port       Peer Address:Port   Process                            
LISTEN    0         128                0.0.0.0:22              0.0.0.0:*       users:(("sshd",pid=1590,fd=3))    
LISTEN    0         128                   [::]:22                 [::]:*       users:(("sshd",pid=1590,fd=4))    

重啟服務後沒有監聽22222埠,應該是沒有配置22222埠的SELinux安全文字的原因

[root@RHEL9 ~]# grep -in selinux /etc/ssh/sshd_config -A1
17:# If you want to change the port on a SELinux system, you have to tell
18:# SELinux about this change.
19-# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER

配置完成,reload也可以生效

[root@RHEL9 ~]# semanage port -a -t ssh_port_t -p tcp 22222
[root@RHEL9 ~]# semanage port -l | grep 22222
ssh_port_t                     tcp      22222, 22
[root@RHEL9 ~]# systemctl reload sshd.service 
[root@RHEL9 ~]# ss -tpln
State     Recv-Q    Send-Q       Local Address:Port        Peer Address:Port   Process                           
LISTEN    0         128                0.0.0.0:22               0.0.0.0:*       users:(("sshd",pid=1590,fd=5))   
LISTEN    0         128                0.0.0.0:22222            0.0.0.0:*       users:(("sshd",pid=1590,fd=3))   
LISTEN    0         128                   [::]:22                  [::]:*       users:(("sshd",pid=1590,fd=6))   
LISTEN    0         128                   [::]:22222               [::]:*       users:(("sshd",pid=1590,fd=4))   

如需移除新增的埠,指令如下

[root@RHEL9 ~]# semanage port -d -p tcp 22222
[root@RHEL9 ~]# semanage port -l | grep ssh
ssh_port_t                     tcp      22

新增兩個使用者用來測試

[root@RHEL9 ~]# useradd monalisa;echo 'whoisshe' | passwd --stdin monalisa
Changing password for user monalisa.
passwd: all authentication tokens updated successfully.
[root@RHEL9 ~]# useradd davinci;echo 'whoishee' | passwd --stdin davinci
Changing password for user davinci.
passwd: all authentication tokens updated successfully.

目前兩個埠應該都能正常登入才對

[root@RHEL9 ~]# ssh -p 62222 monalisa@221.229.XX.X1
monalisa@221.229.XX.X1's password: 
Register this system with Red Hat Insights: insights-client --register
Create an account or view all your systems at https://red.ht/insights-dashboard
Last login: Mon Nov  4 00:25:47 2024 from 221.229.XX.X1
[monalisa@RHEL9 ~]$ logout
Connection to 221.229.XX.X1 closed.
[root@RHEL9 ~]# ssh -p 22222 monalisa@221.229.XX.X1
monalisa@221.229.XX.X1's password: 
Register this system with Red Hat Insights: insights-client --register
Create an account or view all your systems at https://red.ht/insights-dashboard
Last login: Mon Nov  4 00:48:40 2024 from 221.229.XX.X1
[monalisa@RHEL9 ~]$ logout 
Connection to 221.229.XX.X1 closed.

先修改sshd配置檔案禁止密碼登入,讓所有使用者輸密碼都登不上來,無論哪個埠

[root@RHEL9 ~]# grep -in passwordauth /etc/ssh/sshd_config
66:#PasswordAuthentication yes
89:# PasswordAuthentication.  Depending on your PAM configuration,
93:# PAM authentication, then enable this but set PasswordAuthentication
[root@RHEL9 ~]# sed -Ei 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
[root@RHEL9 ~]# grep -n ^PasswordAuthentication /etc/ssh/sshd_config
66:PasswordAuthentication no

[root@RHEL9 ~]# systemctl reload sshd.service 
[root@RHEL9 ~]# ssh -p 62222 monalisa@221.229.XX.X1
monalisa@221.229.XX.X1: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
[root@RHEL9 ~]# ssh -p 22222 monalisa@221.229.XX.X1
monalisa@221.229.XX.X1: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
[root@RHEL9 ~]# ssh -p 62222 davinci@221.229.XX.X1
davinci@221.229.XX.X1: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
[root@RHEL9 ~]# ssh -p 22222 davinci@221.229.XX.X1
davinci@221.229.XX.X1: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

在sshd_config檔案末尾追加match規則

[root@RHEL9 ~]# cat <<EOF>> /etc/ssh/sshd_config
> Match LocalPort 22222
>     PasswordAuthentication yes
> EOF
[root@RHEL9 ~]# tail -3 /etc/ssh/sshd_config
#	ForceCommand cvs server
Match LocalPort 22222
    PasswordAuthentication yes

目前應該是22222埠可以密碼登入,62222埠無法登入

[root@RHEL9 ~]# systemctl reload sshd.service
[root@RHEL9 ~]# ssh -p 62222 monalisa@221.229.XX.X1
monalisa@221.229.XX.X1: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
[root@RHEL9 ~]# ssh -p 22222 monalisa@221.229.XX.X1
monalisa@221.229.XX.X1's password: 

[root@RHEL9 ~]# ssh -p 62222 davinci@221.229.XX.X1
davinci@221.229.XX.X1: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
[root@RHEL9 ~]# ssh -p 22222 davinci@221.229.XX.X1
davinci@221.229.XX.X1's password: 

單獨把monalisa賬號加入match規則

[root@RHEL9 ~]# echo '    AllowUsers monalisa' >> /etc/ssh/sshd_config
[root@RHEL9 ~]# tail -4 /etc/ssh/sshd_config
#	ForceCommand cvs server
Match LocalPort 22222
    PasswordAuthentication yes
    AllowUsers monalisa
[root@RHEL9 ~]# systemctl reload sshd.service 

現在應該是62222埠仍沒人能登入,22222埠monalisa可以密碼登入,davinci不可以

[root@RHEL9 ~]# ssh -p 62222 monalisa@221.229.XX.X1
monalisa@221.229.XX.X1: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
[root@RHEL9 ~]# ssh -p 22222 monalisa@221.229.XX.X1
monalisa@221.229.XX.X1's password: 
Register this system with Red Hat Insights: insights-client --register
Create an account or view all your systems at https://red.ht/insights-dashboard
Last login: Mon Nov  4 02:05:21 2024 from 221.229.XX.X1
[monalisa@RHEL9 ~]$ logout
Connection to 221.229.XX.X1 closed.

[root@RHEL9 ~]# ssh -p 62222 davinci@221.229.XX.X1
davinci@221.229.XX.X1: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
[root@RHEL9 ~]# ssh -p 22222 davinci@221.229.XX.X1
davinci@221.229.XX.X1's password: 
Permission denied, please try again.
davinci@221.229.XX.X1's password: 
Permission denied, please try again.
davinci@221.229.XX.X1's password: 
davinci@221.229.XX.X1: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).

加入davinci到match規則裡

[root@RHEL9 ~]# sed -Ei 's/^(    AllowUsers monalisa)/\1 davinci/' /etc/ssh/sshd_config
[root@RHEL9 ~]# tail -4 /etc/ssh/sshd_config
#	ForceCommand cvs server
Match LocalPort 22222
    PasswordAuthentication yes
    AllowUsers monalisa davinci

測試davinci登陸結果

[root@RHEL9 ~]# systemctl reload sshd.service 
[root@RHEL9 ~]# ssh -p 62222 davinci@221.229.XX.X1
davinci@221.229.XX.X1: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
[root@RHEL9 ~]# ssh -p 22222 davinci@221.229.XX.X1
davinci@221.229.XX.X1's password: 
Register this system with Red Hat Insights: insights-client --register
Create an account or view all your systems at https://red.ht/insights-dashboard
Last failed login: Mon Nov  4 06:00:57 CST 2024 from 221.229.XX.X1 on ssh:notty
There were 8 failed login attempts since the last successful login.
Last login: Mon Nov  4 02:15:54 2024 from 221.229.XX.X1
[davinci@RHEL9 ~]$ logout
Connection to 221.229.XX.X1 closed.

控制root使用者登入的預設引數為
PermitRootLogin prohibit-password
禁止密碼登入,在此狀態下,即使把root賬戶加入最後的match規則裡,root賬戶也不能密碼登入

[root@RHEL9 ~]# grep -ni root /etc/ssh/sshd_config
41:#PermitRootLogin prohibit-password
91:# the setting of "PermitRootLogin without-password".
117:#ChrootDirectory none
[root@RHEL9 ~]# sed -Ei 's/^(    AllowUsers monalisa davinci)/\1 root/' /etc/ssh/sshd_config
[root@RHEL9 ~]# tail -4 /etc/ssh/sshd_config
#	ForceCommand cvs server
Match LocalPort 22222
    PasswordAuthentication yes
    AllowUsers monalisa davinci root
[root@RHEL9 ~]# ssh -p 22222 root@221.229.XX.X1
root@221.229.XX.X1's password: 
Permission denied, please try again.
root@221.229.XX.X1's password: 
Permission denied, please try again.
root@221.229.XX.X1's password: 
root@221.229.XX.X1: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).

最後測試確保敲開的埠20秒內可以自動關閉

[root@RHEL9 ~]# tail -f /var/log/knockd.log 
[2024-11-04 06:22] 183.208.XX.X1: opencloseSSH: Stage 1
[2024-11-04 06:22] 183.208.XX.X1: opencloseSSH: Stage 1
[2024-11-04 06:22] 183.208.XX.X1: opencloseSSH: Stage 2
[2024-11-04 06:22] 183.208.XX.X1: opencloseSSH: OPEN SESAME
[2024-11-04 06:22] opencloseSSH: running command: /usr/bin/firewall-cmd --add-rich-rule='rule family="ipv4" source address="183.208.XX.X1" port protocol="tcp" port="22222" accept'

[2024-11-04 06:23] 183.208.XX.X1: opencloseSSH: command timeout
[2024-11-04 06:23] opencloseSSH: running command: /usr/bin/firewall-cmd --remove-rich-rule='rule family="ipv4" source address="183.208.XX.X1" port protocol="tcp" port="22222" accept'
[root@RHEL9 ~]# firewall-cmd --list-rich-rules

[root@RHEL9 ~]# 

後續的一些問題

  • 我測試的配置敲門埠的時候用6666埠失敗了,本來是選的6666和7777兩個埠,後來換成了7777和8888兩個埠。個人認為是瀏覽器沒有對6666埠發起連線導致的,似乎瀏覽器不認為6666是一個有效的埠,也有可能是別的原因。我用chrome和Microsoft Edge測試都失敗了,但是之前用10000以上的埠測試都沒問題,建議把埠號調大。
  • 重啟系統後knock server失效了,7777埠可以監聽到敲門的資料,但是日誌裡沒有反應。在重啟一遍服務又恢復正常了。個人認為是因為我監聽的埠是我配置的網橋WANbirdge,極有可能是knock server啟動好的時候配置的網橋WANbirdge還沒有啟動好,導致監聽不到這個網路介面。所以等到網橋啟動好後,重啟knock server服務又恢復正常了。因此,設定knock server延遲啟動應該可以解決。如果監聽物理網路卡,不監聽網橋,個人認為應該不會有這個問題,不需要做以下配置。
[root@RHEL9 ~]# rpm -ql knock-server | grep service
/usr/lib/systemd/system/knockd.service
[root@RHEL9 ~]# vim /usr/lib/systemd/system/knockd.service

[Unit]
Description=A port-knocking server
After=network.target

[Service]
#睡90秒再啟動
ExecStartPre=/usr/bin/sleep 90
#避免程序因啟動超時被殺掉,手動設定超時時間
TimeoutStartSec=120
Type=forking
EnvironmentFile=-/etc/sysconfig/knockd
ExecStart=/usr/sbin/knockd -d $OPTIONS

[Install]
WantedBy=multi-user.target

[root@RHEL9 ~]# systemctl daemon-reload 
[root@RHEL9 ~]# systemctl restart knockd.service &
[1] 4793
[root@RHEL9 ~]# watch -n3 systemctl status knockd.service 

用watch每隔3秒觀察knock.service狀態,由Active: activating (start-pre)變為Active: active (running)

[root@RHEL9 ~]# watch -n3 systemctl status knockd.service
Every 3.0s: systemctl status knockd.service                                                       RHEL9: Tue Nov  5 03:56:23 2024

● knockd.service - A port-knocking server
     Loaded: loaded (/usr/lib/systemd/system/knockd.service; enabled; preset: disabled)
     Active: activating (start-pre) since Tue 2024-11-05 03:55:45 CST; 37s ago
Cntrl PID: 4795 (sleep)
      Tasks: 1 (limit: 101263)
     Memory: 196.0K
        CPU: 1ms
     CGroup: /system.slice/knockd.service
             └─4795 /usr/bin/sleep 90

Nov 05 03:55:45 RHEL9 systemd[1]: Starting A port-knocking server...

Every 3.0s: systemctl status knockd.service                                                       RHEL9: Tue Nov  5 03:59:06 2024

● knockd.service - A port-knocking server
     Loaded: loaded (/usr/lib/systemd/system/knockd.service; enabled; preset: disabled)
     Active: active (running) since Tue 2024-11-05 03:57:15 CST; 1min 50s ago
    Process: 4795 ExecStartPre=/usr/bin/sleep 90 (code=exited, status=0/SUCCESS)
    Process: 4821 ExecStart=/usr/sbin/knockd -d $OPTIONS (code=exited, status=0/SUCCESS)
   Main PID: 4822 (knockd)
      Tasks: 1 (limit: 101263)
     Memory: 404.0K
        CPU: 3ms
     CGroup: /system.slice/knockd.service
             └─4822 /usr/sbin/knockd -d

Nov 05 03:55:45 RHEL9 systemd[1]: Starting A port-knocking server...
Nov 05 03:57:15 RHEL9 systemd[1]: Started A port-knocking server.
指令碼實現自動化
#rhel9knock.sh
#Date: 2024-11-04
#!/bin/bash

##################################
###請根據作業系統選擇配置epel源###
##################################
#rhel9配置epel源
#dnf config-manager --set-enabled crb && dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
#紅帽家族9配置epel源
#dnf config-manager --set-enabled crb && dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
#rhel8配置epel源
#subscription-manager repos --enable codeready-builder-for-rhel-8-$(arch)-rpms && dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
#紅帽家族8配置epel源
#dnf config-manager --set-enabled powertools && dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm

##################
#設定服務延時啟動#
##################
#編輯/usr/lib/systemd/system/knockd.service配置knock服務延遲啟動,一般用在監聽的網路介面不是真實的物理網路卡介面,而是網橋類的master介面的情況,如knock服務正常使用可忽略
#dnf install -y knock-server && sed -Ei.bak '/\[Service\]/a ExecStartPre=/usr/bin/sleep 90\nTimeoutStartSec=120' /usr/lib/systemd/system/knockd.service

#配置:監聽網路卡,敲門埠1,敲門埠2,開啟埠,敲擊時間,連線時間,連線賬戶(非root)
knock_if=
knock_p1=
knock_p2=
ssh_port=
knock_time=
close_time=
ssh_user=

#安裝knock
rpm -q knock-server || dnf install -y knock-server

#編輯/etc/knockd.conf
cp /etc/knockd.conf{,.bak}
#使用tab縮排來對其文字"\\\\t",\t為sed裡的tab縮排,單引號內需要把\轉義,寫為\\t,雙引號內需要把兩個\都轉義,寫為\\\\t
sed -Ei "/\[options\]/a\\\\tInterface     = ${knock_if}" /etc/knockd.conf
sed -Ei 's/(^[[:blank:]]+)UseSyslog.*$/\1LogFile       = \/var\/log\/knockd.log/' /etc/knockd.conf
sed -Ei "s/^([[:blank:]]+sequence      = ).+$/\1${knock_p1},${knock_p2}/" /etc/knockd.conf
sed -Ei "s/^([[:blank:]]+seq_timeout   = ).+$/\1${knock_time}/" /etc/knockd.conf
sed -Ei "s/^([[:blank:]]+tcpflags      = syn).+$/\1/" /etc/knockd.conf
sed -Ei "s/^([[:blank:]]+start_command = ).+$/\1\/usr\/bin\/firewall-cmd --add-rich-rule='rule family=\"ipv4\" source address=\"%IP%\" port protocol=\"tcp\" port=\"${ssh_port}\" accept'/" /etc/knockd.conf
sed -Ei "s/^([[:blank:]]+cmd_timeout   = ).+$/\1${close_time}/" /etc/knockd.conf
sed -Ei "s/^([[:blank:]]+stop_command  = ).+$/\1\/usr\/bin\/firewall-cmd --remove-rich-rule='rule family=\"ipv4\" source address=\"%IP%\" port protocol=\"tcp\" port=\"${ssh_port}\" accept'/" /etc/knockd.conf

#根據SELINUX狀態選擇是否新增新增ssh埠的安全文字
[  "$(getenforce)"  ==  "Enforcing"  ] && semanage port -a -t ssh_port_t -p tcp ${ssh_port}

#編輯/etc/ssh/sshd_config檔案
sed -Ei.bak "s/\#Port 22/Port 22\nPort ${ssh_port}/" /etc/ssh/sshd_config
sed -Ei 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
cat <<EOF>> /etc/ssh/sshd_config
Match LocalPort ${ssh_port}
    PasswordAuthentication yes
    AllowUsers ${ssh_user}
EOF
systemctl reload sshd.service

#起動knockd.service服務
systemctl daemon-reload
systemctl enable --now knockd.service

相關文章