SSH 是几乎每台服务器都会开启的服务,加强 SSH 服务的安全对于整个系统的安全性提升有着极大的帮助。我们可以通过修改 sshd 的默认配置,使用自动屏蔽恶意 IP 的软件包 fail2ban,配置防火墙规则等手段来提升其安全性。

更改 sshd 的默认配置

修改 /etc/ssh/sshd_config 文件:

# 禁用旧版本的有漏洞的 SSH 协议
# (旧版本的 sshd 默认允许新旧版本(2,1)的协议,新版本的 sshd 默认只接受新版本(2)的协议)
Protocol 2

# 禁止使用密码登入(默认允许)
# 注意:需先配置好有 root 权限的用户的公私钥对登入后再禁止密码登入,
#       避免自己无法登入服务器,或使用低权限用户登入服务器后无法取得 root 权限。
PasswordAuthentication no

# 禁止空密码账户登入(默认禁止)
PermitEmptyPasswords no

# 禁止 root 账户通过密码登入(默认允许)
# (root 账户仍可以通过公私钥对登入,如果配置了的话)
PermitRootLogin without-password
# (新版本的 sshd 也支持使用更符合直觉的名字 prohibit-password)
#PermitRootLogin prohibit-password
# 或:禁止 root 账户通过 SSH 登入(默认允许)
#PermitRootLogin no

# 只允许白名单内的用户登入(默认允许所有用户登入)
AllowUsers alice bob@corporation
# 或禁止黑名单内的用户通过 SSH 登入(默认允许所有用户登入)
DenyUsers alice bob@corporation

sshd_config 文件的格式语义可以参考 sshd_config(5): OpenSSH SSH daemon config file - Linux man page

修改 SSH 的默认端口

SSH 的默认端口是 22,也因此有大量的自动化扫描及破解工具针对 22 端口进行已知漏洞利用或者密码暴力猜解。如果可能的话,令 SSH 监听在一高位端口上,可以大大减少被自动化脚本攻击的机会。

服务端配置

  • 设置 SSH 的监听端口,只需修改 /etc/ssh/sshd_config 中的 Port 即可,如:

    Port 20022
    
  • 如果服务器启用了 SELinux,则还需进行额外配置。

    首先,确认 SELinux 是否启用:

    sestatus 2> /dev/null | grep -E -q 'SELinux status:\s+enabled' && echo yes || echo no
    

    输出 yes 即表示启用了 SELinux,那么就需要再对 SELinux 进行配置:

    semanage port -a -t ssh_port_t -p tcp 20022
    

    注意把 20022 替换为实际配置的端口。

    semanage 命令不可用,则需安装 policycoreutils-python 包:

    yum install -y policycoreutils-python
    

    安装完成后,再执行之前的 semanage 命令。

  • 如果服务器启用了 firewalld 防火墙,则还需要配置该防火墙。

    首先,确认服务器是否启用了 firewalld:

    systemctl is-active --quiet firewalld && echo yes || echo no
    

    输出 yes 即表示启用了 firewalld,那么需要配置该防火墙:

    firewall-cmd --permanent --add-port=20022/tcp
    firewall-cmd --reload
    

    注意把 20022 替换为实际配置的端口。

  • 如果系统采用 systemd 的 .socket 服务文件来管理 SSH 服务,则修改相应的 .socket 文件即可,具体可以参考 systemd 环境下配置 sshd 监听端口

客户端配置

更换了 SSH 的默认端口后,连接 SSH 时加上端口参数即可:

ssh -p 60022 example.com

也可以编辑 ~/.ssh/config 文件,在其中加上 Port 参数,这样在连接 SSH 时,可以继续使用在更换端口前的命令。

# ~/.ssh/config

Host example.com
	Port 60022

优点

  • 配置简便,修改单行配置并重启服务即可;
  • 有效减少各种针对 SSH 的扫描。

缺点

  • 使连接 SSH 变得略微麻烦;
  • 有些时候,我们需要保持 SSH 监听在 22 端口上,那么这种方法就不适用了。

配置 Fail2ban

Fail2ban 可以根据默认或者自定义的配置来自动屏蔽针对 SSH, HTTP 等各服务的暴力密码猜解或者 DDOS 攻击等。通过配置 Fail2ban 可以大大降低暴力破解对服务器造成的威胁。

配置参考

优点

  • 配置较为简便,安装并添加一个配置文件即可;
  • 不会对正常用户造成任何影响。

缺点

  • 默认配置无法覆盖所有针对 SSH 的攻击。

配置 iptables 规则来限制短时间内产生大量新连接

有些针对 SSH 的攻击并不会被 Fail2ban 的规则匹配到,如下图中记录的访问 SSH 的日志:

sshd: Received disconnect from xxx.xxx.xxx.xxx: 11: Bye Bye [preauth]

针对这种攻击,我们可以限制新连接产生的速率来降低其威胁,如以下 iptables 规则限制每 10 分钟只允许来自同一 IP 的 10 个新连接。

iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --set

iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --update --seconds 600 --hitcount 10 -j DROP

注意,

  • 以上代码中的 22 需换为 SSH 实际监听的端口, eth0 需换为实际的网卡名称。

  • --seconds 600--hitcount 10 可以根据实际需要进行配置。

  • iptables 规则每次重启都会被重置,需要在每次启动时重新应用。

优点

  • 针对各种攻击都有效。

缺点

  • 无论是合法流量还是攻击流量都会受此规则限制,即无论是成功的 SSH 连接还是失败的 SSH 连接,都受此规则约束,因此通过该规则所做的限制不能过于保守,否则易对合法用户造成影响。

参考

扩展阅读