暴露在公网中的服务器如果不限制SSH登录会引来大量暴力尝试密码的攻击,可以使用如下命令查看尝试登录的IP和次数:

1
cat /var/log/secure | awk '/Failed/{print $(NF-3)}' | sort | uniq -c | awk '{print $2" = "$1;}'

随手截了一段我刚买的服务器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
123.207.2.166 = 6  
170.79.153.149 = 6
177.200.194.37 = 9
181.196.82.186 = 6
181.211.179.110 = 6
182.100.67.4 = 5502
182.45.99.211 = 6
183.128.48.94 = 6
183.155.130.103 = 6
183.157.67.23 = 1
183.179.172.245 = 6
186.130.13.198 = 24
186.178.14.84 = 6
190.37.156.44 = 6
190.51.7.4 = 30
35.154.73.111 = 7
36.225.54.246 = 6
39.155.136.34 = 6
47.202.19.153 = 9
94.177.186.16 = 17

fail2ban

fail2ban是一个著名的入侵保护的开源框架,它可以监视系统日志,然后根据匹配到的错误信息(如有人多次尝试SSH、SMTP密码)自动触发不同的防御动作(一般为调用防火墙屏蔽)。

安装

首先安装EPEL源:

1
yum install -y epel-release

由于CentOS7默认防火墙是firewalld,我们安装firewalld版本的fail2ban:
1
yum -y install fail2ban-firewalld fail2ban-systemd

配置

新建并编辑配置文件:

1
vim /etc/fail2ban/jail.local

此处以SSH Jail为例,如需其他规则如邮件、MySQL等可自行搜索。
1
2
3
4
5
6
7
8
9
10
11
12
13
[DEFAULT]
bantime = 86400
findtime = 300
maxretry = 3
[sshd]

enabled = true
port = 8888
banaction = firewallcmd-new

[sshd-ddos]
enabled = true
port = 8888

其中bantime是被封IP禁止访问的时间,单位是秒。
findtime是检测时间,在此时间内超过规定的次数会激活fail2ban,单位是秒。
maxretry是允许错误登录的最大次数。

启动fail2ban并设置开机启动:

1
2
systemctl enable fail2ban
systemctl start fail2ban

常用命令

查看SSH服务监护状态,能看到当前被禁IP。

1
fail2ban-client status sshd

输出如下:
1
2
3
4
5
6
7
8
9
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 125
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 2
|- Total banned: 2
`- Banned IP list: 182.100.67.4 163.177.240.2

在SSH监护服务白名单中添加/删除IP:

1
2
fail2ban-client set sshd addignoreip 1.2.3.4
fail2ban-client set sshd delignoreip 1.2.3.4

查看fail2ban日志

1
tail /var/log/fail2ban.log

输出如下:
1
2
3
4
5
6
7
8
9
10
2017-05-05 12:54:46,757 fail2ban.actions        [4073]: NOTICE  [sshd] 182.100.67.4 already banned
2017-05-05 12:54:49,327 fail2ban.filter [4073]: INFO [sshd] Found 182.100.67.4
2017-05-05 12:54:52,043 fail2ban.filter [4073]: INFO [sshd] Found 182.100.67.4
2017-05-05 12:54:52,764 fail2ban.actions [4073]: NOTICE [sshd] 182.100.67.4 already banned
2017-05-05 12:54:54,508 fail2ban.filter [4073]: INFO [sshd] Found 182.100.67.4
2017-05-05 12:59:58,164 fail2ban.filter [4073]: INFO [sshd] Found 163.177.240.2
2017-05-05 13:00:00,069 fail2ban.filter [4073]: INFO [sshd] Found 163.177.240.2
2017-05-05 13:00:02,064 fail2ban.filter [4073]: INFO [sshd] Found 163.177.240.2
2017-05-05 13:00:02,116 fail2ban.actions [4073]: NOTICE [sshd] Ban 163.177.240.2
2017-05-05 13:00:03,853 fail2ban.filter [4073]: INFO [sshd] Found 163.177.240.2

DenyHosts

和fail2ban不同,DenyHosts主要靠分析sshd的日志文件(/var/log/secure),来记录重复的IP到/etc/hosts.deny文件,从而达到自动屏IP的功能,而fail2ban则是通过监控各种系统服务来完成。

由于以下原因,不再推荐使用DenyHosts。

  • DenyHosts 有尚未解决的安全问题Debian Bug report logs - #692229
  • DenyHosts 至今已有9年未更新
  • 已经有了能完全替代DenyHosts的产品:fail2ban

总结

虽然有各种各样的防护工具,但是最好的做法依然是不依赖它们。

至少应该做到以下几点:

  • 不允许root登录;
  • 不允许SSH通过密码登录;
  • 修改常用服务的默认端口(如22端口);
  • 合理配置防火墙;