OpenSSH 服務器的 20 個最佳實踐

jopen 12年前發布 | 31K 次閱讀 OpenSSH 安全相關

OpenSSH 是 SSH 協議的開源實現。 OpenSSH 可進行遠程登錄、備份、通過 scp 或 sftp 進行遠程文件傳輸等等。 SSH 最完美的確保兩個網絡和系統之間交換數據的機密性和完整性。其主要的優點是通過使用公共密鑰加密進行服務器身份驗證。然而,不時有傳聞關于 OpenSSH 零日漏洞。這里我們列出一些重要的事情,你需要作出調整來提高 OpenSSH 服務器的安全性。

默認配置文件和端口

  • /etc/ssh/sshd_config - OpenSSH 服務器配置文件
  • /etc/ssh/ssh_config - OpenSSH 客戶端配置文件
  • ~/.ssh/ - 用戶獨立的 ssh 配置目錄
  • ~/.ssh/authorized_keys or ~/.ssh/authorized_keys - 公鑰 (RSA or DSA)
  • /etc/nologin - 如果該文件存在,則只允許 root 帳號登錄
  • /etc/hosts.allow and /etc/hosts.deny : 訪問控制定義
  • SSH 默認端口 : TCP 22
OpenSSH 服務器的 20 個最佳實踐

連接中的 SSH 會話

#1: 禁用 OpenSSH 服務

一些工作站或者是筆記本是無需 OpenSSH 服務的,你不需要提供遠程登錄和文件傳輸,那么就禁用 SSHD 服務吧。CentOS/RHEL/Fedora Linux 用戶可通過 yum 命令來禁用并刪除 openssh-server 服務:

# chkconfig sshd off
# yum erase openssh-server
Debian / Ubuntu Linux 用戶可通過 apt-get 命令來處理:
# apt-get remove openssh-server
你還需要更新 iptables 腳本來移除 ssh 例外規則,在 CentOS / RHEL / Fedora 下可編輯 /etc/sysconfig/iptables 和 /etc/sysconfig/ip6tables. 搞定后重啟 iptables 服務即可:
# service iptables restart
# service ip6tables restart

#2: 只使用 SSH Protocol 2

SSH 協議版本 1 有很多漏洞和安全問題,應該避免使用 SSH-1,可通過在 sshd_config 文件中配置如下信息來啟用 SSH-2:

Protocol 2

#3: 限制用戶訪問 SSH

默認所有系統用戶都可以通過 SSH 登錄,只需要用密碼或者公鑰即可。有時候你創建某個用戶只是為了使用郵件或者是 FTP,但是這些用戶也可以通過 ssh 登錄,登錄后就可以訪問很多的系統工具,包括編譯器和腳本語言,可打開網絡端口以及做很多其他的事情。我們可以通過 sshd_config 文件中的 AllowUsers 和 DenyUsers 來設置可訪問 SSH 服務的用戶名單。

下面配置只允許 root, vivek 和 jerry 三個帳號使用 SSH 服務

AllowUsers root vivek jerry

你也可以設置哪些用戶不能訪問 SSH:

DenyUsers saroj anjali foo

你也可以 配置 Linux PAM 來允許或者拒絕通過 sshd 服務器登錄,你也可以對一個分組進行設置是否可以訪問 ssh (詳情

#4: 配置空閑登出的超時間隔

用戶通過 ssh 登錄到服務器后,如果長時間沒有任何動作的話,可通過設置空閑超時時間來讓登錄的用戶自動登出,以避免一些不必要的 ssh 會話連接。打開 sshd_config 文件查看并編輯如下配置:

ClientAliveInterval 300 
ClientAliveCountMax 0

這里我們設置了 300 秒(5分鐘),一旦用戶在 5 分鐘內沒有動作則會自動被踢出。請看 如何自動登出 BASH / TCSH / SSH  以了解更多無活動狀態自動登出的詳情。

#5: 禁用 .rhosts 文件

不讀取用戶命令下的 ~/.rhosts 和 ~/.shosts 文件,只需在 sshd_config  中使用如下設置:

IgnoreRhosts yes

SSH 可模擬過時的 rsh 命令的行為,需要禁用通過 RSH 的非安全登錄。

#6: 禁用基于主機的認證

在 sshd_config 中使用如下配置:

HostbasedAuthentication no

#7: 禁止 root 帳號通過 SSH 登錄

沒必要讓 root 帳號可通過 ssh 登錄,可通過正常用戶登錄后然后執行 su 或者 sudo 來執行 root 權限的操作,可在 sshd_config 中使用如下配置來禁用 root 帳號登錄:

PermitRootLogin no

關于這個問題,Bob 給出了很棒的說明

Saying "don't login as root" is h******t. It stems from the days when people sniffed the first packets of sessions so logging in as yourself and su-ing decreased the chance an attacker would see the root pw, and decreast the chance you got spoofed as to your telnet host target, You'd get your password spoofed but not root's pw. Gimme a break. this is 2005 - We have ssh, used properly it's secure. used improperly none of this 1989 will make a damn bit of difference. -Bob

#8: 啟用警告的 Banner

可以在 sshd_config 中通過如下配置來啟用通過 ssh 登錄后的警告信息:

Banner /etc/issue

下面是 /etc/issue 文件的示例內容:

----------------------------------------------------------------------------------------------
歡迎訪問 open 服務器,請不要亂來!!!
----------------------------------------------------------------------------------------------

#8: 防火墻處理 SSH 端口 # 22

你需要在防火墻規則中打開 22 端口,除非你的服務器只允許通過局域網訪問:

Netfilter (Iptables) 配置

編輯 /etc/sysconfig/iptables (紅帽系列 Linux) 以允許來自 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 and friends specific file):

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

用實際的 IPv6 范圍替換其中的 ipv6network::/ipv6mask

*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

#9: 修改 SSH 端口和限制 IP 綁定

默認 SSH 綁定到所有網卡的所有 IP,端口號是 22,建議只綁定到需要的網卡 IP ,并修改默認的端口。可通過 ssh_config 配置文件中使用如下配置信息將端口修改為 300:

Port 300 
ListenAddress 192.168.1.5 
ListenAddress 202.54.1.5

還有一個更好的方法是使用積極主動的腳本,諸如 fail2ban 或者是 denyhosts

#10: 使用強的 SSH 密碼

使用強而復雜的密碼是多么重要的一件事。蠻力攻擊之所以有效,是因為你使用基于字典的密碼。你可以強制要求用戶不能使用基于字典的密碼,并通過使用 john the ripper tool 來找出已有的弱密碼,下面是一個隨機密碼生成器的示例:(放在你的 ~/.bashrc):

genpasswd() {
    local l=$1
        [ "$l" == "" ] && l=20
        tr -dc A-Za-z0-9_ < /dev/urandom | head -c ${l} | xargs
}
運行: genpasswd 16
輸出:uw8CnDVMwC6vOKgW

#11: 使用基于公鑰的認證

使用公/私鑰配對,并對私鑰提供密碼保護,詳情請看使用基于 RSADSA key 的認證。絕對不要使用密碼短語免費密鑰(密碼鍵更少)登錄。

#12: 使用 Keychain 認證

keychain 是一個特別的 bash 腳本,用于方便靈活的生成基于密鑰認證,提供多種安全措施,詳情請看 keychain software.

#13: Chroot SSHD (將用戶鎖定在他的主目錄下)

默認用戶允許瀏覽服務器上的目錄,如 /etc、/bin 等,我們可使用 chroot 或者是 special tools such as rssh 來保護 ssh。而 OpenSSH 4.8p1 和 4.9p1 讓你不再依賴第三方的工具(如rssh和組合 chroot)來將用戶鎖定在他的主目錄下,詳情請看 blog post 關于如何使用 ChrootDirectory 指令。

#14: 使用 TCP Wrappers

TCP Wrapper 是一個基于主機地址的網絡 ACL 系統,用來過濾網絡地址訪問互聯網。OpenSSH 支持 TCP Wrappers。只需要更新你的 /etc/hosts.allow 文件只允許通過 192.168.1.2 172.16.23.12 訪問 sshd:

sshd : 192.168.1.2 172.16.23.12

詳情請看 FAQ about setting and using TCP wrappers

#15: 禁用空密碼

你應該禁止帳號使用空密碼進行遠程登錄,在 sshd_config 使用如下配置即可:

PermitEmptyPasswords no

#16: 阻止 SSH 破解 (蠻力破解攻擊)

蠻力破解是一種試圖通過大量使用單一或分布式計算機網絡來戰勝一個加密方案。為了阻止這種方法,可結合使用如下軟件:

  • DenyHosts 是Python語言寫的一個程序,它會分析SSHD的日志文件,當發現重復的攻擊時就會記錄IP到/etc/hosts.deny文 件,從而達到自動屏蔽IP的功能。
  • 解釋如何在 RHEL、Fedora 和 CentOS 系統下安裝 DenyHosts
  • Fail2ban 是一個 IP 自動屏蔽工具
  • security/sshguard-pf 在 pf 中防止暴力破解
  • security/sshguard-ipfw 在 ipfw 中防止暴力破解
  • security/sshguard-ipfilter 在 ipfilter 中防止暴力破解
  • security/sshblock block abusive SSH login attempts.
  • security/sshit checks for SSH/FTP bruteforce and blocks given IPs.
  • BlockHosts Automatic blocking of abusive IP hosts.
  • Blacklist Get rid of those bruteforce attempts.
  • Brute Force Detection A modular shell script for parsing application logs and checking for authentication failures. It does this using a rules system where application specific options are stored including regular expressions for each unique auth format.
  • IPQ BDB filter May be considered as a fail2ban lite.

#17: 限制 22 端口連接的速率

netfilter 和 pf 都提供了連接速率限制選項

Iptables 示例

下面配置禁止在一分鐘內 22 端口超過 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 -j DROP

另外的配置選項:

$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 的 man 頁。

*BSD PF 示例

以下將限制的最大連接數到20,每個源速率限制連接數,在一個5秒的跨度15。如果有人打破我們的規則將它們添加到我們的阻止的ip表和阻止他們做任何進一步的連接。

sshd_server_ip="202.54.1.5"
table  persist
block in quick from  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  flush)

#18: 使用端口碰撞技術(Port Knocking)

端口碰撞技術 是一個方法的外部開放端口防火墻通過生成一個連接請求在一組預先指定關閉端口。一旦一個正確的順序連接嘗試接收,防火墻規則是動態修改為允許主機將連接嘗試連接在特定端口(s)。

使用 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 doo

兩個軟件:

  • fwknop 是一個結合端口碰撞和被動操作系統識別技術的實現
  • Multiple-port knocking 僅限于 Netfilter/IPtables 的實現

#19: 使用日志分析器

可通過 logwatch or logcheck 來閱讀日志,這些工具可以讓你輕松的瀏覽日志。通過指定時間來給出日志的報告。首先要確保在 sshd_config 中將日志級別 LogLevel 設置為 INFO 或者 DEBUG:

LogLevel INFO

#20: 對 OpenSSH 和操作系統打補丁

推薦你使用諸如 yum, apt-get, freebsd-update 工具來保持系統的即時獲取最新的安全補丁。

其他選項

為了隱藏 openssh 版本,你可更新源碼然后再次編譯 openssh ,并確保在 sshd_config 中使用如下配置:

#  Turn on privilege separation
UsePrivilegeSeparation yes
# Prevent the use of insecure home directory and key file permissions
StrictModes yes
# Turn on  reverse name checking
VerifyReverseMapping yes
# Do you need port forwarding?
AllowTcpForwarding no
X11Forwarding no
#  Specifies whether password authentication is allowed.  The default is yes.
PasswordAuthentication no

在重啟 openssh-server 之前先用如下命令驗證配置是否正確:

# /usr/sbin/sshd -t

使用 two-factor 或者 three-factor (or more) 認證來加強 OpenSSH 的安全。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!