情况

云服务器经常会收到很多扫描攻击,猜测密码的过程可能是你的ssh密码,也有可能是你的邮箱密码。

# 实时查看日志
[root@blog ~]# tail -f /var/log/auth.log

可以看到,服务器已经被178.62.***.***攻击了,正在通过不同的端口尝试密码

Dec 11 03:39:10 localhost sshd[970688]: fatal: Timeout before authentication for 178.62.***.*** port 55382
Dec 11 03:39:10 localhost sshd[970690]: fatal: Timeout before authentication for 178.62.***.*** port 55402
Dec 11 03:39:10 localhost sshd[970692]: fatal: Timeout before authentication for 178.62.***.*** port 55422
Dec 11 03:39:11 localhost sshd[970694]: fatal: Timeout before authentication for 178.62.***.*** port 55444
Dec 11 03:39:11 localhost sshd[970696]: fatal: Timeout before authentication for 178.62.***.*** port 55464
Dec 11 03:39:11 localhost sshd[970698]: fatal: Timeout before authentication for 178.62.***.*** port 55484
Dec 11 03:39:11 localhost sshd[970700]: fatal: Timeout before authentication for 178.62.***.*** port 55504
Dec 11 03:39:11 localhost sshd[970704]: fatal: Timeout before authentication for 178.62.***.*** port 55544
Dec 11 03:39:11 localhost sshd[970706]: fatal: Timeout before authentication for 178.62.***.*** port 55564
Dec 11 03:39:11 localhost sshd[970702]: fatal: Timeout before authentication for 178.62.***.*** port 55524
Dec 11 03:39:11 localhost sshd[970708]: fatal: Timeout before authentication for 178.62.***.*** port 55586
Dec 11 03:39:11 localhost sshd[970710]: fatal: Timeout before authentication for 178.62.***.*** port 55606
Dec 11 03:39:11 localhost sshd[970712]: fatal: Timeout before authentication for 178.62.***.*** port 55628
Dec 11 03:39:11 localhost sshd[970714]: fatal: Timeout before authentication for 178.62.***.*** port 55648
Dec 11 03:39:11 localhost sshd[970716]: fatal: Timeout before authentication for 178.62.***.*** port 55668
Dec 11 03:39:12 localhost sshd[970718]: fatal: Timeout before authentication for 178.62.***.*** port 55688
Dec 11 03:39:12 localhost sshd[970720]: fatal: Timeout before authentication for 178.62.***.*** port 55728
Dec 11 03:39:12 localhost sshd[970722]: fatal: Timeout before authentication for 178.62.***.*** port 55748

当有大量的电脑发起登录请求时,不断地猜测密码不仅会有猜出密码的风险,甚至会大量消耗CPU资源。

处理

做为一名优秀的管理员,这种问题不应该等到机器瘫痪了再来,该出手时就出手。

简单处理

如果经常是同一个IP来爆破,可以使用防火墙加入黑名单中。

永久配置:--permanent
--add-source=网段地址
--add-service=协议

# 例子
# 拒绝网段或单个IP访问
firewall-cmd --permanent --zone=block --add-source=172.34.0.0/24
firewall-cmd --permanent --zone=block --add-source=172.34.4.207
firewall-cmd --permanent --zone=block --add-service=http
firewall-cmd --permanent --zone=block --add-service=ftp
# 重载生效
firewall-cmd --reload

# 删除不需要的
firewall-cmd --permanent --zone=block --remove-source=172.34.4.207

或者把IP访问/etc/hosts.deny文件中,你再用此ip登录就不行了。

nano /etc/hosts.deny 

# 以如下的形式添加内容
sshd:213.136.88.159
sshd:207.154.196.169
sshd:167.172.188.48
sshd:45.133.1.78
sshd:206.81.23.148
……

faill2ban

使用fail2ban来自动化处理异常登录请求。安装它使用以下命令:

# ubuntu
sudo apt-get install fail2ban

常用的配置选项:

root@ubuntu:~# fail2ban-client --help
Usage: /usr/bin/fail2ban-client [OPTIONS] <COMMAND>
Option:
    -c <DIR>                设置配置目录,服务端在启动时将从该目录下搜索并加载配置文件。
    -s <FILE>               设置服务端套接字文件路径。
    -p <FILE>               设置服务端启动时应该创建的进程文件路径。
    -d                      转储配置,用于调试,使用该选项则会将配置信息显示到屏幕上。
    -i                      以交互的方式操作Fail2ban。
    -v                      较详细的显示操作信息。
    -q                      较少的显示操作信息。
    -x                      设置服务端在启动前将删除套接字文件。
    -b                      设置服务端将在后台运行。
    -f                      设置服务端将在前台运行。
    -h, --help              显示帮助信息。
    -V, --version           显示版本信息。

Command:
    start                                    启动服务端和所有监禁(jail)。
    reload                                   重载所有配置。
    reload <JAIL>                            重载指定的监禁(jail)配置。
    stop                                     停止服务端和所有监禁(jail),当Fail2ban服务交
                                             由"systemctl"托管时,使用该命令将会导致服务端重启。
    status                                   获取当前监禁(jail)的运行状态。
    ping                                     测试服务端的活跃状态。
    help                                     return this output
    version                                  显示服务端的版本。

应用实例

配置文件路径:

[root@blog ~]# vim /etc/fail2ban/jail.local.conf

修改配置文件

# 拷贝默认配置
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

# 只关注sshd这部分,其它的原理类似,自成一个板块
[sshd]
enabled = true                # 是否开启动
filter  = sshd                # 过滤sshd协议
port    = 22                  # 监控端口22,根据自己服务器修改ssh端口 
action = %(action_mwl)s       # 执行动作
logpath = /var/log/secure     # 监控日志来源
maxretry    = 5               # 最大尝试次数
bantime     = 18000           # 禁止IP地址的持续时间(“ m”代表分钟)。如果键入的值不带“ m”或“ h”(代表小时),则将其视为秒。值-1将永久禁止IP地址。要非常小心,不要将自己永久锁定在自己的面前。
findtime        = 1800        # “尝试失败次数过多”的值。

启动运行

# 设置开机自启动
sudo systemctl enable fail2ban
# 启动
sudo systemctl start fail2ban
# 查看运行状态
sudo systemctl status fail2ban

frp特殊处理

背景

我们一般会使用 fail2ban 来保护暴露到公网的提供密码登入的 ssh 连线等。
但使用 frp 穿透后所有的从外网访问都会变成 127.0.0.1 进入的,原本能用 fail2ban 保护的如 ssh 服务将无法使用。
因此 fail2ban 应该放到 frps 伺服器上。但 frps 的日志并不会对失败进行辨别,无论你访问哪个服务,frp 日志只会有连线和断开两种日志。

不完美的解决途径

正常情况下,我们不会频繁地连线和断开,只有被扫描时才容易出现。
因此新增自定义 filter,并设定一段时间内连线超过阈值后进入监狱。
新增配置文件 /etc/fail2ban/filter.d/frps.conf

[Definition]
failregex = ^.*\[.*SSH.*\] get a user connection \[<HOST>:[0-9]*\]
ignoreregex =

编辑配置文件 /etc/fail2ban/jail.local 新增

[frp]
enabled = true
findtime = 10m
maxretry = 100
bantime = 1d
filter = frps
logpath = /data/frp/log/frps.log
protocol = all
chain = all
port = all
action = iptables-allports[name=frp,protocol=tcp]

重启 fail2ban 服务

sudo fail2ban-client reload