每次在自己的 VPS 上,用 Vim 查看 /var/log/auth.log 日志,总能看到一行行登陆失败信息:都是攻击者企图暴力破解密码、尝试末遂的错误信息。

该如何应对这种针对 SSH 服务的攻击呢?总结下我的做法吧。

 

修改 sshd 配置

说明:

  • Linux 下,sshd 配置文件一般是 /etc/ssh/sshd.config
  • 修改过 sshd 配置文件后,需要重启 sshd 服务。

主要配置以下几点: 

  • 禁用空密码

    对应选项为 PermitEmptyPasswords,不过一般默认值就是 no,应该不需要修改了。

  • 禁用 root 登陆

    只允许以普通用户登陆。需要以 root 身份操作时,再用 su 切换)。

    原因有二:首先,root 权限太大,万一攻击者以 root 身份攻击得手,后果不堪设想;其次,root 是 Linux 系统中确定会存在的用户名。而暴力破解 SSH 密码必须要指定用户名和密码。禁止 root 用户登录,攻击者不知道真正的 SSH 用户名,攻击难度自然加大了。

    至少,从我自己的 VPS 来看,许多针对 SSH 的攻击记录确实是以 root 用户来登录的。

    修改方法:将 PermitRootLogin 置为 no 即可。修改前,请确保你有可登陆的普通用户。

    不少 Linux 用户为了方便,经常给普通用户 sudo 的权限,以允许普通用户也能执行很多原本只有 root 才能执行的操作。如果攻击者得到了普通用户的口令、同时该普通用户又有 sudo 权限,这也会带来不小的风险。鱼与熊掌不可兼得,sudo 的方便性与风险并存。如何取舍,就看 SA 的选择了。

  • 修改默认端口

    SSH 默认端口是 22,可以通过 PortListenAddress 选项来修改。示例如下:

    # 作用:将 SSH 登陆端口修改为 220 和 221,可以任选一个登陆
    Port 220
    ListenAddress 0.0.0.0:221

    当然,不能从默认端口登陆,难免会带来一些不便。

 

设置 iptables 防火墙

  • 手工批量拉黑

    具体步骤如下:

    1. 统计分析攻击者 IP 和每个 IP 的攻击次数。
      grep -Irw "Failed" /var/log/auth.log | grep -IoE "[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}" | sort | uniq -c | sort -rn
      7950 112.175.88.171
      3310 123.157.150.53
      1242 222.186.34.215
      1236 117.34.91.170
       845 1.93.29.149
       807 123.157.150.108
       712 60.169.77.246
       578 202.96.36.167
       558 120.37.142.187
       360 220.177.198.43

      关于上面的命令,简要说明一点:在 uniq -c 计数前,需要先 sort,把相同的 IP 连续存放,这样才能正确地统计结果。man uniq,也可以看到相关说明:

      Note: 'uniq' does not detect repeated lines unless they are adjacent. You may want to sort the input first, or use 'sort -u' without 'uniq'.
    2. 将攻击次数超过一定数目(比如 3 次)的 IP 全部拉入黑名单。
      # 作用:将来源 IP 是 112.175.88.171 或 123.157.150.53、目的端口是 22 的 TCP 包全部丢掉
      iptables -I INPUT -p tcp -s 112.175.88.171,123.157.150.53 --dport 22 -j DROP
      # 作用:将来源 IP 是 112.175.88.171 或 123.157.150.53、目的端口是 220 或 221 的 TCP 包全部丢掉
      iptables -I INPUT -p tcp -s 117.21.226.160 -m multiport --dports 22,3333 -j DROP

      需要注意的是,如果用 iptables 同时指定多个源/目的端口,需要用 -m multiport 指定,最多可以同时指定 15 个。更多细节,可以 man iptables 查看,这里不再赘述。

  • 自动拉黑

    上面的方法略显繁琐,幸好有更加聪明的方法。该方法出自 依云

    # 作用:对于外来数据,如果是 TCP 协议,目标端口号是 22,网络接口是 eth0,状态是新连接,那么把它加到最近列表中
    iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --set
    # 作用:如果有人从一个 IP 60 秒内连接尝试四次 SSH 登录的话,那么它就会被加入黑名单,后续连接将会被丢弃
    iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP

    简单地说,如果有人从一个 IP 一分钟内连接尝试四次 SSH 登录的话,那么它就会被加入黑名单,后续连接将会被丢弃。

 

人为因素控制

人为因素其实是最重要、同时也最容易被忽略的因素了。个人建议:

  • SSH 密码设置得复杂些
  • 妥善保管密码
  • Linux 用户可以用公钥验证代替密码验证,更安全也更省事。同时,定期检查存放公钥的文件 ~/.ssh/authorized_keys 里是否放有陌生人的公钥。

 

参考链接:

Leave a Reply

Your email address will not be published. Required fields are marked *