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
更多有關 ssh 公匙的資訊,參照以下文章:
- 為備份指令碼設定無密碼安全登入
- sshpass:使用指令碼密碼登入 SSH 伺服器
- 如何為一個 Linux/類 Unix 系統設定 SSH 登入密匙
- 如何使用 Ansible 工具上傳 ssh 登入授權公匙
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
更多資訊參見“如何透過禁用 Linux 的 ssh 密碼登入來增強系統安全” 。
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
- 使用 mkpasswd / makepasswd / pwgen 生成隨機密碼
- Linux / UNIX: 生成密碼
- Linux 隨機密碼生成命令
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
更多資訊請參見 “Linux:菜鳥管理員的 25 個 Iptables Netfilter 命令”。
*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 synproxy state
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
在 Linux/Mac OS X 和類 UNIX 系統中參見 TCP wrappers 設定和使用的常見問題。
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_ips> persist
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-rate 15/5, overload <abusive_ips> flush)
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
更多資訊請參見:
Debian / Ubuntu: 使用 Knockd and Iptables 設定埠敲門
13、 配置空閒超時登出時長
使用者可以透過 ssh 連入伺服器,可以配置一個超時時間間隔來避免無人值守的 ssh 會話。 開啟 sshd_config
並確保配置以下值:
ClientAliveInterval 300
ClientAliveCountMax 0
以秒為單位設定一個空閒超時時間(300秒 = 5分鐘)。一旦空閒時間超過這個值,空閒使用者就會被踢出會話。更多細節參見如何自動登出空閒超時的 BASH / TCSH / SSH 使用者。
14、 為 ssh 使用者啟用警示標語
更新 sshd_config
檔案如下行來設定使用者的警示標語:
Banner /etc/issue
`/etc/issue 示例檔案:
----------------------------------------------------------------------------------------------
You are accessing a XYZ Government (XYZG) Information System (IS) that is provided for authorized use only.
By using this IS (which includes any device attached to this IS), you consent to the following conditions:
+ The XYZG routinely intercepts and monitors communications on this IS for purposes including, but not limited to,
penetration testing, COMSEC monitoring, network operations and defense, personnel misconduct (PM),
law enforcement (LE), and counterintelligence (CI) investigations.
+ At any time, the XYZG may inspect and seize data stored on this IS.
+ Communications using, or data stored on, this IS are not private, are subject to routine monitoring,
interception, and search, and may be disclosed or used for any XYZG authorized purpose.
+ This IS includes security measures (e.g., authentication and access controls) to protect XYZG interests--not
for your personal benefit or privacy.
+ Notwithstanding the above, using this IS does not constitute consent to PM, LE or CI investigative searching
or monitoring of the content of privileged communications, or work product, related to personal representation
or services by attorneys, psychotherapists, or clergy, and their assistants. Such communications and work
product are private and confidential. See User Agreement for details.
----------------------------------------------------------------------------------------------
以上是一個標準的示例,更多的使用者協議和法律細節請諮詢你的律師團隊。
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,可以嘗試下以下設定:
#################[ WARNING ]########################
# Do not use any setting blindly. Read sshd_config #
# man page. You must understand cryptography to #
# tweak following settings. Otherwise use defaults #
####################################################
# Supported HostKey algorithms by order of preference.
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
# Specifies the available KEX (Key Exchange) algorithms.
KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
# Specifies the ciphers allowed
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
#Specifies the available MAC (message authentication code) algorithms
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com
# LogLevel VERBOSE logs user's key fingerprint on login. Needed to have a clear audit track of which key was using to log in.
LogLevel VERBOSE
# Log sftp level file access (read/write/etc.) that would not be easily logged otherwise.
Subsystem sftp /usr/lib/ssh/sftp-server -f AUTHPRIV -l INFO
使用以下命令獲取 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##
其他建議
- 使用 2FA 加強 SSH 的安全性 - 可以使用 OATH Toolkit 或 DuoSecurity 啟用多重身份驗證。
- 基於密匙鏈的身份驗證 - 密匙鏈是一個 bash 指令碼,可以使得基於密匙的驗證非常的靈活方便。相對於無密碼密匙,它提供更好的安全性。
更多資訊
- OpenSSH 官方 專案。
- 使用者手冊: sshd(8)、ssh(1)、ssh-add(1)、ssh-agent(1)。
如果知道這裡沒用提及的方便的軟體或者技術,請在下面的評論中分享,以幫助讀者保持 OpenSSH 的安全。
關於作者
作者是 nixCraft 的創始人,一個經驗豐富的系統管理員和 Linux/Unix 指令碼培訓師。他曾與全球客戶合作,領域涉及 IT,教育,國防和空間研究以及非營利部門等多個行業。請在 Twitter、Facebook、Google+ 上關注他。
via: https://www.cyberciti.biz/tips/linux-unix-bsd-openssh-server-best-practices.html
作者:Vivek Gite 譯者:shipsw 校對:wxy
本文由 LCTT 原創編譯,Linux中國 榮譽推出