當前位置:
首頁 > 知識 > 20 個 OpenSSH 最佳安全實踐

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##




其他建議






  1. 使用 2FA 加強 SSH 的安全性

     – 可以使用 

    OATH Toolkit

     或 

    DuoSecurity

     啟用多重身份驗證。



  2. 基於密匙鏈的身份驗證

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




關於作者




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

Twitter

Facebook

Google+

 上關注他。





●本文編號450,以後想閱讀這篇文章直接輸入

450

即可



●輸入m獲取到文章目錄

推薦↓↓↓



黑客技術與網路安全


更多推薦

18個技術類公眾微信


涵蓋:程序人生、演算法與數據結構、黑客技術與網路安全、大數據技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Linux學習 的精彩文章:

微軟擁抱 Linux,Win10 商店上架 Debian和Kali

TAG:Linux學習 |