OpenSSH 是 SSH 协议的实现。建议将 OpenSSH 用于远程登录、进行备份、通过 scp 或 sftp 进行远程文件传输等等。SSH 非常适合保持两个网络和系统之间交换的数据的机密性和完整性。但是,主要优点是通过使用公钥加密技术进行服务器身份验证。时不时有关于 OpenSSH 零日漏洞的谣言。本页介绍如何保护在 Linux 或类 Unix 系统上运行的 OpenSSH 服务器以提高 sshd 安全性。
OpenSSH 服务器支持各种身份验证。建议使用基于公钥的身份验证。首先,在本地台式机/笔记本电脑上使用以下 ssh-keygen 命令创建密钥对:
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 密钥的登录是否适合您:
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 vivek@rhel7-aws-server

有关 ssh 公钥身份验证的更多信息,请搜索本站相关内容。
在禁用 root 用户登录之前,请确保普通用户可以以 root 身份登录。例如,允许 vivek 用户使用 sudo 命令以 root 身份登录。
允许组 sudo 的成员执行任何命令。将用户 vivek 添加到 sudo 组:
使用 id 命令验证组成员身份
sudo adduser vivek sudo
id vivek
允许组轮中的人员在 CentOS/RHEL 和 Fedora Linux 服务器上运行所有命令。使用 usermod 命令将名为 vivek 的用户添加到滚轮组:
sudo usermod -aG wheel vivek
id vivek
对其进行测试并确保用户 vivek 可以以 root 身份登录或以 root 身份运行命令:
确认后,通过向 sshd_config 添加以下行来禁用 root 登录:
sudo -i
sudo /etc/init.d/sshd status
sudo systemctl status httpd
PermitRootLogin no
ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no
必须禁用所有基于密码的登录。只允许基于公钥的登录。在sshd_config文件中添加以下内容:
AuthenticationMethods publickey
PubkeyAuthentication yes
CentOS 6.x/RHEL 6.x 上的旧版 SSHD 用户应使用以下设置:
PubkeyAuthentication yes
默认情况下,所有系统用户都可以使用其密码或公钥通过 SSH 登录。有时您创建 UNIX/Linux 用户帐户用于 FTP 或电子邮件目的。但是,这些用户可以使用 ssh 登录系统。他们将完全访问系统工具,包括编译器和脚本语言,例如 Perl、Python,它们可以打开网络端口并做许多其他花哨的事情。只允许 root、vivek 和 jerry 用户通过 SSH 使用系统,sshd_config添加以下内容:
AllowUsers vivek jerry
或者,您可以允许所有用户通过 SSH 登录,但仅拒绝少数用户,sshd_config如下行:
DenyUsers root saroj anjali foo
您还可以配置 Linux PAM 允许或拒绝通过 sshd 服务器登录。您可以允许组名称列表访问或拒绝访问 ssh。
您需要明确禁止使用空密码的帐户进行远程登录,请使用以下行更新sshd_config:
PermitEmptyPasswords no
为您的密钥使用强用户密码和密码的重要性怎么强调都不为过。暴力攻击之所以有效,是因为用户转到基于字典的密码。您可以强制用户避免使用密码来防止字典攻击,并使用 john the ripper 工具找出现有的弱密码。这是一个示例随机密码生成器(放入您的 ~/.bashrc 中):
genpasswd() {
local l=$1
[ "$l" == "" ] && l=20
tr -dc A-Za-z0-9_ < /dev/urandom | head -c ${l} | xargs
}
运行它:
输出:$ genpasswd 16
uw8CnDVMwC6vOKgW
您需要通过更新 iptables/ufw/firewall-cmd 或 pf 防火墙配置来防火墙 ssh TCP 端口 #22。通常,OpenSSH 服务器只能接受来自 LAN 或其他远程 WAN 站点的连接。
更新 /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 双堆叠 sshd,请编辑 /etc/sysconfig/ip6tables(Redhat 和朋友的特定文件),输入:
-A RH-Firewall-1-INPUT -s ipv6network::/ipv6mask -m tcp -p tcp --dport 22 -j ACCEPT
将 ipv6network::/ipv6mask 替换为实际的 IPv6 范围。
UFW 是 uncomplicated firewall 的首字母缩写词。它用于管理 Linux 防火墙,旨在为用户提供易于使用的界面。使用以下命令仅接受 202.54.1.5/29 中的端口 22:
有关更多信息,请阅读“iptables规则设置实例 ”。
sudo ufw allow from 202.54.1.5/29 to any port 22
如果您使用的是 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
默认情况下,SSH 侦听系统上所有可用接口和 IP 地址。限制 ssh 端口绑定并更改 ssh 端口(许多野蛮人强制脚本只尝试连接到 TCP 端口 # 22)。要绑定到 192.168.1.5 和 202.54.1.5 IP 和端口 300,请在sshd_config中添加或更正以下行:
Port 300
ListenAddress 192.168.1.5
ListenAddress 202.54.1.5
当您想要接受来自动态 WAN IP 地址的连接时,使用主动方法脚本(例如 fail2ban 或 denyhosts)的更好方法。
TCP Wrapper 是一个基于主机的网络 ACL 系统,用于过滤对 Internet 的网络访问。OpenSSH 确实支持 TCP 包装器。只需按如下方式更新您的 /etc/hosts.allow 文件,即可仅允许来自 192.168.1.2 和 172.16.23.12 IP 地址的 SSH:
sshd : 192.168.1.2 172.16.23.12
暴力破解是一种通过使用单个或分布式计算机网络尝试大量可能性(用户和密码的组合)来击败加密方案的方法。要防止针对 SSH 的暴力攻击,请使用以下软件:
netfilter 和 pf 都提供了速率限制选项,用于对端口 # 22 上的传入连接执行简单的限制。
以下示例将丢弃在 60 秒内对端口 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
从您的 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
下面将每个源的最大连接数限制为 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)
端口敲击是一种通过在一组预先指定的关闭端口上生成连接尝试来从外部打开防火墙上的端口的方法。一旦收到正确的连接尝试序列,就会动态修改防火墙规则,以允许发送连接的主机尝试连接到特定端口。使用 iptables 的 ssh 的示例端口敲击示例:
$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
用户可以通过 ssh 登录服务器,您可以设置空闲超时间隔以避免无人值守的 ssh 会话。打开sshd_config并确保配置了以下值:
您正在设置空闲超时间隔(以秒为单位)(300 秒 == 5 分钟)。过了这个时间间隔后,空闲用户将被自动踢出(读取为注销)。
ClientAliveInterval 300
ClientAliveCountMax 0
通过使用以下行
更新sshd_config来设置警告横幅:示例 /etc/issue 文件:
Banner /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.
----------------------------------------------------------------------------------------------
以上为标准示例,请咨询您的法律团队以获取具体的用户协议和法律声明详细信息。
不要读取用户的 ~/.rhosts 和 ~/.shosts 文件。使用以下设置更新sshd_config:
SSH 可以模拟过时的 rsh 命令的行为,只需通过 RSH 禁用不安全访问即可。
IgnoreRhosts yes
要禁用基于主机的身份验证,请使用以下选项更新sshd_config:
HostbasedAuthentication no
建议您使用 yum、apt-get、freebsd-update 等工具来使用最新的安全补丁使系统保持最新状态:
默认情况下,允许用户浏览服务器目录,例如 /etc/、/bin 等。您可以使用基于作系统的 chroot 或使用特殊工具(例如 rssh)来保护 ssh。随着 OpenSSH 4.8p1 或 4.9p1 的发布,您不再需要依赖第三方黑客攻击(例如 rssh 或复杂的 chroot(1) 设置来将用户锁定到他们的主目录。
工作站和笔记本电脑可以在没有 OpenSSH 服务器的情况下工作。如果不提供 SSH 的远程登录和文件传输功能,请禁用并删除 SSHD 服务器。CentOS / RHEL 用户可以使用 yum 命令禁用和删除 openssh-server:
Debian / Ubuntu Linux 用户可以使用 apt 命令/apt-get 命令禁用和删除相同的服务器:
您可能需要更新 iptables 脚本以删除 ssh 例外规则。在 CentOS / RHEL / Fedora 下,编辑文件 /etc/sysconfig/iptables 和 /etc/sysconfig/ip6tables。完成后,重新启动 iptables 服务:
sudo yum erase openssh-server
sudo apt-get remove openssh-server
service iptables restart
service ip6tables restart
如果您使用的是 OpenSSH 版本 6.7+ 或更高版本,请尝试以下设置:
#################[ 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 服务器支持的密码和 alog 列表:
ssh -Q cipher
ssh -Q cipher-auth
ssh -Q mac
ssh -Q kex
ssh -Q key

要在重新启动 sshd 之前检查配置文件的有效性和密钥的健全性是否存在任何错误,请运行:
扩展测试模式:
最后根据您的发行版版本在类似 Linux 或 Unix 的系统上重新启动 sshd:
sudo sshd -t
sudo sshd -T
sudo systemctl start ssh #Debian/Ubuntu
sudo systemctl restart sshd.service #RHEL &co
doas /etc/rc.d/sshd restart #OpenBSD
sudo service sshd restart #FreeBSD
ssh-audit 是用于 SSH 服务器和客户端审计的工具。请参阅我的页面,了解在您的 Linux 或 Unix 盒子上安装和配置 ssh-audit。
如果您有此处未提及的技术或方便的软件,请在下面的评论中分享,以帮助您的读者确保他们基于 OpenSSH 的服务器的安全。其他建议:
man 8 sshd
man 1 ssh
man 1 ssh-add
man 1 ssh-agent
man 5 sshd_config
