20 個 OpenSSH 最佳安全實踐
英文:Vivek Gite,翻譯:Linux中國/shipsw
linux.cn/article-9394-1.html
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 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
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
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,可以嘗試下以下設置:
使用以下命令獲取 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 腳本,可以使得基於密匙的驗證非常的靈活方便。相對於無密碼密匙,它提供更好的安全性。
關於作者
作者是 nixCraft 的創始人,一個經驗豐富的系統管理員和 Linux/Unix 腳本培訓師。他曾與全球客戶合作,領域涉及 IT,教育,國防和空間研究以及非營利部門等多個行業。請在
、
、
Google+
上關注他。
●本文編號450,以後想閱讀這篇文章直接輸入
450
即可●輸入m獲取到文章目錄
推薦↓↓↓
黑客技術與網路安全
更多推薦
《
18個技術類公眾微信
》
涵蓋:程序人生、演算法與數據結構、黑客技術與網路安全、大數據技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。


※微軟擁抱 Linux,Win10 商店上架 Debian和Kali
TAG:Linux學習 |