Skip to main content

ubuntu 防止SSH暴力登录攻击

最近观察服务器的认证日志,发现有些国外的 IP 地址,多次尝试破解服务器的密码进行登录。于是希望能将多次尝试 SSH 登录失败的 IP 阻止掉。

查看日志文件:

sudo tail -f /var/log/auth.log

看到很多如下的日志:

来统计一下有多少人在暴力破解 root 密码

sudo grep "Failed password for root" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -nr | more
   3579 111.198.159.85
   1185 111.229.204.86
    457 121.89.198.64
    109 112.85.236.98
    106 36.94.17.242
     99 45.141.84.126
     89 129.28.163.90
     83 111.231.87.10
     77 64.225.53.232
     77 122.155.202.93
     72 64.225.126.22
     72 113.57.170.50
     72 103.117.120.47
     71 45.232.244.5
     71 138.197.149.97
     70 134.175.154.93
     67 159.65.100.44
     67 120.131.13.186
     67 104.248.205.67
     64 152.32.222.192
     61 150.136.40.83
     59 188.170.13.225
     59 178.128.14.102

如果已经禁用了 root 登录,则看一下暴力猜用户名的统计信息

sudo grep "Failed password for invalid user" /var/log/auth.log | awk '{print $13}' | sort | uniq -c | sort -nr | more
   1812 111.198.159.85
    645 111.229.204.86
    275 45.141.84.126
     85 36.94.17.242
     85 112.85.236.98
     56 111.231.87.10
     55 172.103.3.143
     52 211.253.26.117
     51 129.28.163.90
     50 134.175.154.93

为了防范于未然,我们可以做些配置,让服务器更加安全。

下面的三个方法,可以完全使用,也可以部分使用。一般建议使用其中的第一条跟第三条。

  1. 修改 SSH 端口,禁止 root 登陆

修改 /etc/ssh/sshd_config 文件

sudo vim /etc/ssh/sshd_config
 
Port 1234 # 一个别人猜不到的端口号
PermitRootLogin no
 
sudo service sshd restart
  1. 禁用密码登陆,使用 RSA 私钥登录

如果服务器只允许使用私钥登录的,但是如果想在别的电脑上临时 SSH 上来,又没带私钥文件的情况下,就很麻烦。所以还是保留密码验证登录。不管怎样,这一条还是先列出来

# 在客户端生成密钥
ssh-keygen -t rsa
 
# 把公钥拷贝至服务器
ssh-copy-id -i .ssh/id_rsa.pub server
 
# 也可以手动将.shh/id_rsa.pub拷贝至服务器用户目录的.ssh中,记得修改访问权限
# $ scp .shh/id_rsa.pub server:~/.ssh
 
# 在服务器中
cd ./.ssh/
 
mv id_rsa.pub authorized_keys
 
chmod 400 authorized_keys
 
vim /etc/ssh/sshd_config
 
RSAAuthentication yes #RSA认证
PubkeyAuthentication yes #开启公钥验证
AuthorizedKeysFile .ssh/authorized_keys #验证文件路径
PasswordAuthentication no #禁止密码认证
PermitEmptyPasswords no #禁止空密码
UsePAM no #禁用PAM
 
 
# 最后保存,重启
sudo service sshd restart
  1. 安装 denyhosts

denyhostsPython 语言写的一个程序,它会分析 sshd 的日志文件,当发现重复的失败登录时就会记录 IP/etc/hosts.deny 文件,从而达到自动屏 IP 的功能。现今 denyhosts 在各个发行版软件仓库里都有。

注意在 ubuntu 16.04 系统上,如果通过远程的 SSH 登录到服务器上执行安装命令的话,会由于默认情况下 RESET_ON_SUCCESS = yes #如果一个ip登陆成功后,失败的登陆计数是否重置为0 这部分,默认情况下是关闭的。而如果恰好我们又出现自己输入的错误密码错误累计次数超过 5 次的情况(即使后面有成功登录的记录也不行),会导致我们自己当前登录的地址也被阻止的情况。这种情况发生之后,会导致我们自己无法控制服务器(这个阻塞是在 iptables 层阻塞的,如果要恢复,在 iptables 中删除已经添加的记录才可以)。解决办法就是换一个新的 IP 地址登录服务器,然后修改 RESET_ON_SUCCESS 这个参数,并重启 denyhosts 服务。如果是阿里云或者腾讯云的服务器,可以尝试从他们网站上提供的网页版本的 Shell 进行操作。

对于 ubuntu 16.04 系统,建议使用如下方式进行安装:

#创建执行脚本
touch ~/install.sh
 
#创建执行安装命令,整个过程不中断连续执行,如果不使用脚本,执行到这里,可能SSH就已经被阻断了
#安装完成后,denyhosts的服务就已经开始运行了,此时可能已经设置了iptables了
echo "sudo apt-get install denyhosts" >> ~/install.sh 
 
#创建修改配置文件的命令
echo "sudo sed -i 's/^#RESET_ON_SUCCESS/RESET_ON_SUCCESS/g' /etc/denyhosts.conf" >> ~/install.sh
 
#创建重启服务的命令
echo "sudo service denyhosts restart" >> ~/install.sh
 
#执行我们刚刚的安装脚本
sudo bash ~/install.sh

默认配置就能很好的工作,如要个性化设置可以修改 /etc/denyhosts.conf

sudo vim /etc/denyhosts.conf
 
SECURE_LOG = /var/log/auth.log #ssh 日志文件,它是根据这个文件来判断的。
HOSTS_DENY = /etc/hosts.deny #控制用户登陆的文件
PURGE_DENY = #过多久后清除已经禁止的,空表示永远不解禁
BLOCK_SERVICE = sshd #禁止的服务名,如还要添加其他服务,只需添加逗号跟上相应的服务即可
DENY_THRESHOLD_INVALID = 5 #允许无效用户失败的次数
DENY_THRESHOLD_VALID = 10 #允许普通用户登陆失败的次数
DENY_THRESHOLD_ROOT = 1 #允许root登陆失败的次数
DENY_THRESHOLD_RESTRICTED = 1
WORK_DIR = /var/lib/denyhosts #运行目录
SUSPICIOUS_LOGIN_REPORT_ALLOWED_HOSTS=YES
HOSTNAME_LOOKUP=YES #是否进行域名反解析
LOCK_FILE = /var/run/denyhosts.pid #程序的进程ID
ADMIN_EMAIL = root@localhost #管理员邮件地址,它会给管理员发邮件
SMTP_HOST = localhost
SMTP_PORT = 25
SMTP_FROM = DenyHosts <nobody@localhost>
SMTP_SUBJECT = DenyHosts Report
AGE_RESET_VALID=5d #用户的登录失败计数会在多久以后重置为0,(h表示小时,d表示天,m表示月,w表示周,y表示年)
AGE_RESET_ROOT=25d
AGE_RESET_RESTRICTED=25d
AGE_RESET_INVALID=10d
RESET_ON_SUCCESS = yes #如果一个ip登陆成功后,失败的登陆计数是否重置为0
DAEMON_LOG = /var/log/denyhosts #自己的日志文件
DAEMON_SLEEP = 30s #当以后台方式运行时,每读一次日志文件的时间间隔。
DAEMON_PURGE = 1h #当以后台方式运行时,清除机制在 HOSTS_DENY 中终止旧条目的时间间隔,这个会影响PURGE_DENY的间隔。

查看 /etc/hosts.deny 发现里面已经有 3 条记录。

sudo cat /etc/hosts.deny | wc -l
3

目前 ubuntu 16.04 系统源里的 denyhosts 存在一个 BUG ,就是系统重启之后, iptables 中的拦截设置没有恢复。具体的讨论以及描述,参考 Iptables not persistent,代码应该已经增加了,目前还没合并到主分支。

参考链接