天天看點

OpenSSH 伺服器的 20 個最佳實踐

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 服務:

1

# chkconfig sshd off

2

# yum erase openssh-server

Debian / Ubuntu Linux 使用者可通過 apt-get 指令來處理:

1

# apt-get remove openssh-server

你還需要更新 iptables 腳本來移除 ssh 例外規則,在 CentOS / RHEL / Fedora 下可編輯 /etc/sysconfig/iptables 和 /etc/sysconfig/ip6tables. 搞定後重新開機 iptables 服務即可:

1

# service iptables restart

2

# service ip6tables restart<code></code>

#2: 隻使用 SSH Protocol 2

SSH 協定版本 1 有很多漏洞和安全問題,應該避免使用 SSH-1,可通過在 sshd_config 檔案中配置如下資訊來啟用 SSH-2:

1

Protocol 2

#3: 限制使用者通路 SSH

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

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

1

AllowUsers root vivek jerry

你也可以設定哪些使用者不能通路 SSH:

1

DenyUsers saroj anjali foo

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

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

使用者通過 ssh 登入到伺服器後,如果長時間沒有任何動作的話,可通過設定空閑逾時時間來讓登入的使用者自動登出,以避免一些不必要的 ssh 會話連接配接。打開 sshd_config 檔案檢視并編輯如下配置:

1

ClientAliveInterval 300

2

ClientAliveCountMax 0

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

#5: 禁用 .rhosts 檔案

不讀取使用者指令下的 ~/.rhosts 和 ~/.shosts 檔案,隻需在 sshd_config  中使用如下設定:

1

IgnoreRhosts

yes

SSH 可模拟過時的 rsh 指令的行為,需要禁用通過 RSH 的非安全登入。

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

在 sshd_config 中使用如下配置:

1

HostbasedAuthentication no

#7: 禁止 root 帳号通過 SSH 登入

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

1

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 登入後的警告資訊:

1

Banner /etc/issue

下面是 /etc/issue 檔案的示例内容:

---------------------------------------------------------------------------------------------- 歡迎通路 oschina 伺服器,請不要亂來!!! ----------------------------------------------------------------------------------------------      

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

你需要在防火牆規則中打開 22 端口,除非你的伺服器隻允許通過區域網路通路:

Netfilter (Iptables) 配置

編輯 /etc/sysconfig/iptables (紅帽系列 Linux) 以允許來自 192.168.1.0/24 和 202.54.1.5/29 兩個網段的連接配接:

1

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

2

-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):

1

-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 配置如下:

1

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:

1

Port 300

2

ListenAddress 192.168.1.5

3

ListenAddress 202.54.1.5

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

#10: 使用強的 SSH 密碼

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

1

genpasswd() {

2

local

l=$1

3

[

"$l"

==

""

] && l=20

4

tr

-

dc

A-Za-z0-9_ < /dev/urandom |

head

-c ${l} |

xargs

5

}

運作:

genpasswd 16

輸出:uw8CnDVMwC6vOKgW

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

使用公/私鑰配對,并對私鑰提供密碼保護,詳情請看使用基于 RSA 和 DSA 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:

1

sshd : 192.168.1.2 172.16.23.12

詳情請看 FAQ about setting and using TCP wrappers

#15: 禁用空密碼

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

1

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 個連接配接:

1

#!/bin/bash

2

inet_if=eth1

3

ssh_port=22

4

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

set

5

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

另外的配置選項:

1

$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

2

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

3

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

4

# another one line example

5

# $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表和阻止他們做任何進一步的連接配接。

1

sshd_server_ip=

"202.54.1.5"

2

table <abusive_ips> persist

3

block

in

quick from <abusive_ips>

4

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)

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

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

使用 iptables 配置端口碰撞的示例:

01

$IPT -N stage1

02

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

03

$IPT -A stage1 -p tcp --dport 3456 -m recent --

set

--name knock2

04

05

$IPT -N stage2

06

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

07

$IPT -A stage2 -p tcp --dport 2345 -m recent --

set

--name heaven

08

09

$IPT -N door

10

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

11

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

12

$IPT -A door -p tcp --dport 1234 -m recent --

set

--name knock

13

14

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

15

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

16

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

兩個軟體:

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

#19: 使用日志分析器

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

1

LogLevel INFO

#20: 對 OpenSSH 和作業系統打更新檔

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

其他選項

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

01

#  Turn on privilege separation

02

UsePrivilegeSeparation

yes

03

# Prevent the use of insecure home directory and key file permissions

04

StrictModes

yes

05

# Turn on  reverse name checking

06

VerifyReverseMapping

yes

07

# Do you need port forwarding?

08

AllowTcpForwarding no

09

X11Forwarding no

10

#  Specifies whether password authentication is allowed.  The default is yes.

11

PasswordAuthentication no

在重新開機 openssh-server 之前先用如下指令驗證配置是否正确:

1

# /usr/sbin/sshd -t

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