20 個 OpenSSH 最佳安全實踐


        OpenSSH 是 SSH 協議的一個實現。一般通過 scp 或 sftp 用於遠程登錄、備份、遠程文件傳輸等功能。SSH能夠完美保障兩個網絡或系統間數據傳輸的保密性和完整性。儘管如此,它最大的優勢是使用公匙加密來進行服務器驗證。時不時會出現關於 OpenSSH 零日漏洞的傳言。本文將描述如何設置你的 Linux 或類 Unix 系統以提高 sshd 的安全性。


OpenSSH 默認設置


  • TCP 端口 – 22

  • OpenSSH 服務配置文件 – sshd_config (位於 /etc/ssh/)


1、 基於公匙的登錄


OpenSSH 服務支持各種驗證方式。推薦使用公匙加密驗證。首先,使用以下 ssh-keygen命令在本地電腦上創建密匙對:


1024 位或低於它的 DSA 和 RSA 加密是很弱的,請不要使用。當考慮 ssh 客戶端向後兼容性的時候,請使用 RSA密匙代替 ECDSA 密匙。所有的 ssh 密鑰要麼使用 ED25519 ,要麼使用 RSA,不要使用其它類型。


$ ssh-keygen -t key_type -b bits -C "comment"

 

示例:


$ ssh-keygen -t ed25519 -C "Login to production cluster at xyz corp"

$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_aws_$(date +%Y-%m-%d) -C "AWS key for abc corp clients"


下一步,使用 ssh-copy-id 命令安裝公匙:


$ ssh-copy-id -i /path/to/public-key-file user@host

$ ssh-copy-id user@remote-server-ip-or-dns-name


示例:


$ ssh-copy-id vivek@rhel7-aws-server

 

提示輸入用戶名和密碼的時候,確認基於 ssh 公匙的登錄是否工作:


$ ssh vivek@rhel7-aws-server

 




2、 禁用 root 用戶登錄


禁用 root 用戶登錄前,確認普通用戶可以以 root 身份登錄。例如,允許用戶 vivek 使用 sudo 命令以 root 身份登錄。


在 Debian/Ubuntu 系統中如何將用戶 vivek 添加到 sudo 組中


允許 sudo 組中的用戶執行任何命令。 將用戶 vivek 添加到 sudo 組中:


$ sudo adduser vivek sudo

 

使用 id 命令 驗證用戶組。


$ id vivek

 

在 CentOS/RHEL 系統中如何將用戶 vivek 添加到 sudo 組中


在 CentOS/RHEL 和 Fedora 系統中允許 wheel 組中的用戶執行所有的命令。使用 usermod 命令將用戶 vivek 添加到 wheel 組中:


$ sudo usermod -aG wheel vivek

$ id vivek


測試 sudo 權限並禁用 ssh root 登錄


測試並確保用戶 vivek 可以以 root 身份登錄執行以下命令:


$ sudo -i

$ sudo /etc/init.d/sshd status

$ sudo systemctl status httpd


添加以下內容到 sshd_config 文件中來禁用 root 登錄:


PermitRootLogin no

ChallengeResponseAuthentication no

PasswordAuthentication no

UsePAM no


3、 禁用密碼登錄


所有的密碼登錄都應該禁用,僅留下公匙登錄。添加以下內容到 sshd_config 文件中:


AuthenticationMethods publickey

PubkeyAuthentication yes


CentOS 6.x/RHEL 6.x 系統中老版本的 sshd 用戶可以使用以下設置:


PubkeyAuthentication yes

 

4、 限制用戶的 ssh 訪問


默認狀態下,所有的系統用戶都可以使用密碼或公匙登錄。但是有些時候需要爲 FTP 或者 email 服務創建 UNIX/Linux 用戶。然而,這些用戶也可以使用 ssh 登錄系統。他們將獲得訪問系統工具的完整權限,包括編譯器和諸如 Perl、Python(可以打開網絡端口乾很多瘋狂的事情)等的腳本語言。通過添加以下內容到 sshd_config 文件中來僅允許用戶 root、vivek 和 jerry 通過 SSH 登錄系統:


AllowUsers vivek jerry

 

當然,你也可以添加以下內容到 sshd_config 文件中來達到僅拒絕一部分用戶通過 SSH 登錄系統的效果。


DenyUsers root saroj anjali foo

 

你也可以通過配置 Linux PAM 來禁用或允許用戶通過 sshd 登錄。也可以允許或禁止一個用戶組列表通過 ssh 登錄系統。


5、 禁用空密碼


你需要明確禁止空密碼賬戶遠程登錄系統,更新 sshd_config 文件的以下內容:


PermitEmptyPasswords no

 

6、 爲 ssh 用戶或者密匙使用強密碼


爲密匙使用強密碼和短語的重要性再怎麼強調都不過分。暴力破解可以起作用就是因爲用戶使用了基於字典的密碼。你可以強制用戶避開字典密碼並使用約翰的開膛手工具來檢測弱密碼。以下是一個隨機密碼生成器(放到你的 ~/.bashrc 下):


genpasswd() {

    local l=$1

    [ "$l" == "" ] && l=20

    tr -dc A-Za-z0-9_ < /dev/urandom | head -c ${l} | xargs


運行:


genpasswd 16

 

輸出:


uw8CnDVMwC6vOKgW

 

7、 爲 SSH 的 22端口配置防火牆


你需要更新 iptables/ufw/firewall-cmd 或 pf 防火牆配置來爲 ssh 的 TCP 端口 22 配置防火牆。一般來說,OpenSSH 服務應該僅允許本地或者其他的遠端地址訪問。


Netfilter(Iptables) 配置


更新 /etc/sysconfig/iptables (Redhat 和其派生系統特有文件) 實現僅接受來自於 192.168.1.0/24 和 202.54.1.5/29 的連接,輸入:


-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 22 -j ACCEPT

-A RH-Firewall-1-INPUT -s 202.54.1.5/29 -m state --state NEW -p tcp --dport 22 -j ACCEPT


如果同時使用 IPv6 的話,可以編輯 /etc/sysconfig/ip6tables (Redhat 和其派生系統特有文件),輸入:


-A RH-Firewall-1-INPUT -s ipv6network::/ipv6mask -m tcp -p tcp --dport 22 -j ACCEPT

 

將 ipv6network::/ipv6mask 替換爲實際的 IPv6 網段。


Debian/Ubuntu Linux 下的 UFW


UFW 是 Uncomplicated FireWall 的首字母縮寫,主要用來管理 Linux 防火牆,目的是提供一種用戶友好的界面。輸入以下命令使得系統僅允許網段 202.54.1.5/29 接入端口 22:


$ sudo ufw allow from 202.54.1.5/29 to any port 22

 

*BSD PF 防火牆配置


如果使用 PF 防火牆 /etc/pf.conf 配置如下:


pass in on $ext_if inet proto tcp from {192.168.1.0/24, 202.54.1.5/29} to $ssh_server_ip port ssh flags S/SA synproxystate

 

8、 修改 SSH 端口和綁定 IP


ssh 默認監聽系統中所有可用的網卡。修改並綁定 ssh 端口有助於避免暴力腳本的連接(許多暴力腳本只嘗試端口 22)。更新文件 sshd_config 的以下內容來綁定端口 300 到 IP 192.168.1.5 和 202.54.1.5:


Port 300

ListenAddress 192.168.1.5

ListenAddress 202.54.1.5


當需要接受動態廣域網地址的連接時,使用主動腳本是個不錯的選擇,比如 fail2ban 或 denyhosts。


9、 使用 TCP wrappers (可選的)


TCP wrapper 是一個基於主機的訪問控制系統,用來過濾來自互聯網的網絡訪問。OpenSSH 支持 TCP wrappers。只需要更新文件 /etc/hosts.allow 中的以下內容就可以使得 SSH 只接受來自於 192.168.1.2 和 172.16.23.12 的連接:


sshd : 192.168.1.2 172.16.23.12

 

10、 阻止 SSH 破解或暴力***


暴力破解是一種在單一或者分佈式網絡中使用大量(用戶名和密碼的)組合來嘗試連接一個加密系統的方法。可以使用以下軟件來應對暴力***:


  • DenyHosts 是一個基於 Python SSH 安全工具。該工具通過監控授權日誌中的非法登錄日誌並封禁原始 IP 的方式來應對暴力***。

    • RHEL / Fedora 和 CentOS Linux 下如何設置 DenyHosts。

  • Fail2ban 是另一個類似的用來預防針對 SSH ***的工具。

  • sshguard 是一個使用 pf 來預防針對 SSH 和其他服務***的工具。

  • security/sshblock 阻止濫用 SSH 嘗試登錄。

  • IPQ BDB filter 可以看做是 fail2ban 的一個簡化版。


11、 限制 TCP 端口 22 的傳入速率(可選的)


netfilter 和 pf 都提供速率限制選項可以對端口 22 的傳入速率進行簡單的限制。


Iptables 示例


以下腳本將會阻止 60 秒內嘗試登錄 5 次以上的客戶端的連入。


#!/bin/bash

inet_if=eth1

ssh_port=22

$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent --set

$IPT -I INPUT -p tcp --dport ${ssh_port} -i ${inet_if} -m state --state NEW -m recent --update --seconds 60 --hitcount 5


在你的 iptables 腳本中調用以上腳本。其他配置選項:


$IPT -A INPUT -i ${inet_if} -p tcp --dport ${ssh_port} -m state --state NEW -m limit --limit 3/min --limit-burst 3 -j ACCEPT

$IPT -A INPUT -i ${inet_if} -p tcp --dport ${ssh_port} -m state --state ESTABLISHED -j ACCEPT

$IPT -A OUTPUT -o ${inet_if} -p tcp --sport ${ssh_port} -m state --state ESTABLISHED -j ACCEPT

# another one line example

# $IPT -A INPUT -i ${inet_if} -m state --state NEW,ESTABLISHED,RELATED -p tcp --dport 22 -m limit --limit 5/minute --limit-burst 5-j ACCEPT


其他細節參見 iptables 用戶手冊。


*BSD PF 示例


以下腳本將限制每個客戶端的連入數量爲 20,並且 5 秒內的連接不超過 15 個。如果客戶端觸發此規則,則將其加入 abusive_ips 表並限制該客戶端連入。最後 flush 關鍵詞殺死所有觸發規則的客戶端的連接。


sshd_server_ip = "202.54.1.5"

table <abusive_ipspersist

block in quick from <abusive_ips>

pass in on $ext_if proto tcp to $sshd_server_ip port ssh flags S/SA keep state (max-src-conn 20, max-src-conn-rate15/5, overload <abusive_ipsflush)


12、 使用端口敲門(可選的)


端口敲門是通過在一組預先指定的封閉端口上生成連接嘗試,以便從外部打開防火牆上的端口的方法。一旦指定的端口連接順序被觸發,防火牆規則就被動態修改以允許發送連接的主機連入指定的端口。以下是一個使用 iptables 實現的端口敲門的示例:


$IPT -N stage1

$IPT -A stage1 -m recent --remove --name knock

$IPT -A stage1 -p tcp --dport 3456 -m recent --set --name knock2

 

$IPT -N stage2

$IPT -A stage2 -m recent --remove --name knock2

$IPT -A stage2 -p tcp --dport 2345 -m recent --set --name heaven

 

$IPT -N door

$IPT -A door -m recent --rcheck --seconds 5 --name knock2 -j stage2

$IPT -A door -m recent --rcheck --seconds 5 --name knock -j stage1

$IPT -A door -p tcp --dport 1234 -m recent --set --name knock

 

$IPT -A INPUT -m --state ESTABLISHED,RELATED -j ACCEPT

$IPT -A INPUT -p tcp --dport 22 -m recent --rcheck --seconds 5 --name heaven -j ACCEPT

$IPT -A INPUT -p tcp --syn -j door


13、 配置空閒超時註銷時長


用戶可以通過 ssh 連入服務器,可以配置一個超時時間間隔來避免無人值守的 ssh 會話。 打開 sshd_config 並確保配置以下值:


ClientAliveInterval 300

ClientAliveCountMax 0


以秒爲單位設置一個空閒超時時間(300秒 = 5分鐘)。一旦空閒時間超過這個值,空閒用戶就會被踢出會話。更多細節參見如何自動註銷空閒超時的 BASH / TCSH / SSH 用戶。


14、 爲 ssh 用戶啓用警示標語


更新 sshd_config 文件如下行來設置用戶的警示標語:


Banner /etc/issue

 

`/etc/issue 示例文件:



以上是一個標準的示例,更多的用戶協議和法律細節請諮詢你的律師團隊。


15、 禁用 .rhosts 文件(需覈實)


禁止讀取用戶的 ~/.rhosts 和 ~/.shosts 文件。更新 sshd_config 文件中的以下內容:


IgnoreRhosts yes

 

SSH 可以模擬過時的 rsh 命令,所以應該禁用不安全的 RSH 連接。


16、 禁用基於主機的授權(需覈實)


禁用基於主機的授權,更新 sshd_config 文件的以下選項:


HostbasedAuthentication no

 

17、 爲 OpenSSH 和操作系統打補丁


推薦你使用類似 yum、apt-get 和 freebsd-update 等工具保持系統安裝了最新的安全補丁。


18、 Chroot OpenSSH (將用戶鎖定在主目錄)


默認設置下用戶可以瀏覽諸如 /etc、/bin 等目錄。可以使用 chroot 或者其他專有工具如 rssh 來保護 ssh 連接。從版本 4.8p1 或 4.9p1 起,OpenSSH 不再需要依賴諸如 rssh 或複雜的 chroot(1) 等第三方工具來將用戶鎖定在主目錄中。可以使用新的 ChrootDirectory 指令將用戶鎖定在其主目錄,參見這篇博文。


19. 禁用客戶端的 OpenSSH 服務


工作站和筆記本不需要 OpenSSH 服務。如果不需要提供 ssh 遠程登錄和文件傳輸功能的話,可以禁用 sshd 服務。CentOS / RHEL 用戶可以使用 yum 命令 禁用或刪除 openssh-server:


$ sudo yum erase openssh-server

 

Debian / Ubuntu 用戶可以使用 apt 命令/apt-get 命令 刪除 openssh-server:


$ sudo apt-get remove openssh-server

 

有可能需要更新 iptables 腳本來移除 ssh 的例外規則。CentOS / RHEL / Fedora 系統可以編輯文件 /etc/sysconfig/iptables 和 /etc/sysconfig/ip6tables。最後重啓 iptables 服務:


# service iptables restart

# service ip6tables restart


20. 來自 Mozilla 的額外提示


如果使用 6.7+ 版本的 OpenSSH,可以嘗試下以下設置:


圖片.png


使用以下命令獲取 OpenSSH 支持的加密方法:


$ ssh -Q cipher

$ ssh -Q cipher-auth

$ ssh -Q mac

$ ssh -Q kex

$ ssh -Q key




如何測試 sshd_config 文件並重啓/重新加載 SSH 服務?


在重啓 sshd 前檢查配置文件的有效性和密匙的完整性,運行:


$ sudo sshd -t

 

擴展測試模式:


$ sudo sshd -T

 

最後,根據系統的的版本重啓 Linux 或類 Unix 系統中的 sshd 服務:


$ [sudo systemctl start ssh][38] ## Debian/Ubunt Linux##

$ [sudo systemctl restart sshd.service][39] ## CentOS/RHEL/Fedora Linux##

$ doas /etc/rc.d/sshd restart ## OpenBSD##

$ sudo service sshd restart ## FreeBSD##


其他建議


  1. 使用 2FA 加強 SSH 的安全性 – 可以使用 OATH Toolkit 或 DuoSecurity 啓用多重身份驗證。

  2. 基於密匙鏈的身份驗證 – 密匙鏈是一個 bash 腳本,可以使得基於密匙的驗證非常的靈活方便。相對於無密碼密匙,它提供更好的安全性。


關於作者


作者是 nixCraft 的創始人,一個經驗豐富的系統管理員和 Linux/Unix 腳本培訓師。他曾與全球客戶合作,領域涉及 IT,教育,國防和空間研究以及非營利部門等多個行業。請在 Twitter、Facebook、Google+ 上關注他。


OpenSSH 是 SSH 協議的一個實現。一般通過 scp 或 sftp 用於遠程登錄、備份、遠程文件傳輸等功能。SSH能夠完美保障兩個網絡或系統間數據傳輸的保密性和完整性。儘管如此,它最大的優勢是使用公匙加密來進行服務器驗證。時不時會出現關於 OpenSSH 零日漏洞的傳言。本文將描述如何設置你的 Linux 或類 Unix 系統以提高 sshd 的安全性。




本文來自 馬哥教育 公衆號 更多精彩請關注 馬哥教育




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章