侧边栏壁纸
博主头像
CYC的个人博客博主等级

学习使人进步

  • 累计撰写 115 篇文章
  • 累计创建 14 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

Fail2ban防止SSH暴力破解||防止nginx被恶意扫描的方法

我是一条酸菜鱼
2025-04-28 / 0 评论 / 0 点赞 / 214 阅读 / 15059 字

Fail2ban防止SSH暴力破解||防止nginx被恶意扫描的方法

为了防止SSH暴力破解,可以采取以下几种有效的方法:

设置复杂密码

设置复杂的密码是防止暴力破解的基本方法。建议密码长度至少为16位,并且包含大小写字母、数字和特殊字符。定期更换密码也是一个好习惯,推荐每个月更换一次1

修改SSH默认端口

默认情况下,SSH服务使用22端口。可以通过修改SSH配置文件来更改默认端口,从而增加攻击者的破解难度。修改方法如下:

# 编辑SSH配置文件

vim /etc/ssh/sshd_config


# 修改端口号,例如将端口号改为2222

Port 2222


# 重启SSH服务

systemctl restart sshd

修改端口后,可以使用端口扫描工具检查端口是否已更改1

使用非root用户登录

为了增加安全性,可以禁止root用户直接登录,创建一个普通用户并赋予其超级用户权限。具体步骤如下:

# 创建新用户

useradd -s /bin/bash test


# 设置用户密码

echo "password" | passwd --stdin test


# 修改/etc/passwd文件,将新用户的UID和GID改为0

vim /etc/passwd

# 将test用户的UID和GID改为0

test:x:0:0::/home/test:/bin/bash

这样可以有效防止攻击者通过暴力破解root用户密码1

使用密钥认证

使用密钥认证可以避免每次登录都需要输入密码,从而提高安全性。具体步骤如下:

# 在客户端生成公钥和私钥

ssh-keygen -t rsa -b 4096


# 将公钥复制到服务器

ssh-copy-id user@server_ip


# 使用密钥登录服务器

ssh user@server_ip

这样可以避免密码被暴力破解

更改sshd_config 配置

限制身份验证最大尝试次数

限制用户失败认证的最大次数是一个缓解暴力攻击的好方法。将MaxAuthTries设置为比较小的数字(x),将会在用户x次失败尝试后强制断开会话。

MaxAuthTries 3

配置Fail2ban

Fail2ban是一款安全保护工具,可以监控系统日志并自动屏蔽多次尝试失败的IP地址。安装和配置Fail2ban的方法如下:

# 安装Fail2ban

yum install epel-release -y

yum install fail2ban -y


# 编辑Fail2ban配置文件sshd端口从ssh更改为YOUR_SSH_PORT

vim /etc/fail2ban/jail.conf

# 配置SSH防护

[ssh-iptables]

enabled = true

port = 2222

filter = sshd

action = iptables[name=SSH, port=ssh,port=2222,protocol=tcp]

logpath = /var/log/secure

ignoreip = 127.0.0.1/8 ::1 xxx.xxx.xxx.xxx

maxretry = 3

findtime = 300

bantime = 3600

代码解释:

• enabled:是否启用该服务的监控。

• filter:使用的日志过滤规则文件。

• action:封禁动作,这里使用 iptables 封禁 IP。

• logpath:日志文件路径。

• ignoreip :白名单ip

• maxretry:允许的最大失败次数,超过此次数后封禁 IP。

• bantime:封禁时间(秒),这里设置为 3600 秒(1 小时)。86400(24小时)-1表示永久封锁

• findtime:检测的时间窗口(秒),这里设置为 600 秒(10 分钟)。86400(24小时)


# 重启Fail2ban服务

systemctl restart fail2ban.service

systemctl enable fail2ban.service
#查看规则生效情况
iptables -L -n -v

配置完成后,Fail2ban会自动屏蔽多次尝试失败的IP地址

通过以上几种方法,可以有效防止SSH暴力破解,增强系统的安全性

问题说明:

默认情况下,Fail2ban 仅通过 TCP 阻止。至少在我的设置中,我注意到当机器人回来尝试通过 UDP 的被阻止端口时,会出现“已被禁止”的消息。

要解决此问题,请告诉 Fail2ban 在所有协议上阻止端口,而不仅仅是 TCP。您需要在 /etc/fail2ban/jail.conf 和您在 /etc/fail2ban/action.d/ 中使用的每个作的 [Init] 部分进行此更改。

更改此项:

# Default protocol
protocol = tcp

自:

# Default protocol
protocol = all

接下来,我禁用了 ICMP 回显请求,因此被阻止的 IP 无法命中服务器:

  1. vim /etc/sysctl.conf

  2. 添加以下两行:

    net.ipv4.icmp_echo_ignore_all = 1  
    net.ipv4.icmp_echo_ignore_broadcasts = 1
    
  3. 退出并保存文件。

  4. 运行 sysctl -p 以使更改生效。

之后,运行 fail2ban-client reload,您应该不会再看到这些“已被禁止”的消息,除非您被一个 IP 发送垃圾邮件,该 IP 在阻止生效之前进行了几次访问尝试。

此外,重要的是在每个监狱中使用 iptables-allports作来阻止每个罪犯的所有端口,而不是他们试图访问的端口。否则,他们可能会触发另一个 Jail,并最终在日志中显示为 “already baned”

这则是另外一种生效方案

 action_ = %(default/action_)s[name=%(__name__)s-tcp, protocol="tcp"]
           %(default/action_)s[name=%(__name__)s-udp, protocol="udp"]

2.jali.local配置详解

代码语言:shell

[DEFAULT]
#此参数为加白的网段、IP,可以是域名、网段或单个IP,空格隔开。
ignoreip = 127.0.0.1/8 ::1

#设置被封锁的时间间隔,如下表示10分钟,可以是秒(s)、分钟(m)、小时(h)、天(d),不带单位则默认为s,-1表示永久封锁。
bantime  = 10m

#检测的间隔时间,在间隔时间内,当>=maxtretry设置的失败次数,则触发限制,禁止访问。
findtime  = 10m

#findtime时间内的最大失败次数
maxretry = 5

二、SSH安全防护

1.启用sshd模块

回到jali.local配置文件,找到[sshd]模块,并添加一行启用此模块:

[sshd]
enabled = true
port    = 22                 #ssh端口
logpath = /var/log/auth.log  #日志路径
backend = %(sshd_backend)s   #后台管理程序,默认由systemd接管,无需修改

enabled = true 表示启用此模块。同时上面提到的[DEFAULT]配置可以理解为全局选项,对所有服务模块生效,当然也可以在具体的服务模块下添加参数,局部变量优先级大于全局变量,比如:

[sshd]
enabled = true
port    = 22
logpath = /var/log/auth.log
backend = %(sshd_backend)s
ignoreip = 127.0.0.1/8 ::1 10.10.0.0/16 172.16.0.0/16
bantime = 60m
findtime = 1m
maxretry = 3

以上配置表示,一分钟内如果ssh登陆失败3次,则封锁访问的IP,同时排除本地回环地址和一些内网网段。

fail2ban-client status
fail2ban-client status sshd #展示具体模块的详细细节
#查看规则生效情况
iptables -L -n -v
4.手动解除限制

使用unban解除封锁的IP

fail2ban-client unban 192.168.1.16
fail2ban-client unban --all  #解除所有

二、Nginx防止来自恶意的请求扫描

1.vim /etc/fail2ban/jail.conf 添加nginx防护规则

[nginx-http-auth]
enabled = true
port = 80,443
filter = nginx-http-auth
action = iptables-multiport[name=NGINX_HTTPAUTH, port="80,443"]
logpath = /data/nginx/nginx-server/logs/error.log
maxretry = 3
bantime = 86400

[nginx-botsearch]
enabled = true
port = 80,443
filter = nginx-botsearch
action = iptables-multiport[name=NGINX_BOTSER, port="80,443"]
logpath = /data/nginx/nginx-server/logs/access.log
maxretry = 2
findtime = 60
bantime = 86400



[nginx-bad-request]
enabled = true
port = 80,443
filter = nginx-bad-request
action = iptables-multiport[name=NGINX_BADREQ, port="80,443"]
logpath = /data/nginx/nginx-server/logs/access.log
maxretry = 2
findtime = 60
bantime = 86400


[nginx-forbidden]
enabled = true
port = 80,443
filter = nginx-forbidden
action = iptables-multiport[name=NGINX_FORBIDDEN, port="80,443"]
#action =docker-nginx[name=NGINX_FORBIDDEN]
logpath = /data/nginx/nginx-server/logs/access.log
maxretry = 2
findtime = 60
bantime = 86400

说明:

filter为拦截器名称

action为拦截器规则 iptables-multiport 代表多条匹配

maxretry=2 出现两次触发拦截

#action =docker-nginx[name=NGINX_FORBIDDEN] 专为docker容器网络配置

findtime = 60 找出60秒以内的

bantime = 86400 封禁24小时

2.新增nginx对应拦截器

cd /etc/fail2ban/filter.d/

新增400拦截器 vim nginx-bad-request.conf

# Fail2Ban filter for Nginx 400 Bad Request errors
# 匹配 Nginx access log 中状态码为 400 的请求

[Definition]

# 匹配示例:
# 192.168.1.1 - - [30/Apr/2026:10:00:00 +0800] "GET /invalid%path HTTP/1.1" 400 150 "-" "Mozilla/5.0"
# 192.168.1.1 - - [30/Apr/2026:10:00:00 +0800] "\x00\x01\x02" 400 150 "-" "-"

failregex = ^<HOST> -.*"(GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH)" .*" (400) .*$
            ^<HOST> -.*"\\x.*" (400) .*$
            ^<HOST> -.*"".*400 .*$
            ^<HOST> -.* "(GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH).*" 400 .*$

ignoreregex = 

# 日期格式匹配
datepattern = {^LN-BEG}
              %%d/%%b/%%Y:%%H:%%M:%%S %%z
              %%Y-%%m-%%dT%%H:%%M:%%S%%z
  

新增403拦截器 vim nginx-forbidden.conf

# /etc/fail2ban/filter.d/nginx-forbidden.conf

[Definition]
# 匹配包含 403 状态码的行
# <HOST> 是 Fail2ban 内置变量,自动提取 IP
failregex =^<HOST> -.*"(GET|POST|HEAD|PUT|DELETE|OPTIONS|PATCH).*" 403 .+$

# 忽略正则(可选):排除某些特定的合法 403 请求,如监控探针
# ignoreregex = 

[Init]
# 日期模式,通常不需要修改,除非你的日志时间格式非常规
#datepattern = {^LN-BEG}
datepattern =^<HOST> \S+ \S+ \[{DATE}\}

3.新增docker容器网络的action配置(根据实际情况新增)

该方法适用dockernginx容器

如果用了DockerNginx容器做反向代理,特别说明docker网络要采用网桥模式

cd /etc/fail2ban/action.d/

vim docker-nginx.conf

[Definition]
actionstart = 
actionstop = 
actioncheck = 
# 封禁:插入 DOCKER-USER 链头部
actionban = iptables -I DOCKER-USER -s <ip> -j DROP
# 解封:从 DOCKER-USER 链删除
actionunban = iptables -D DOCKER-USER -s <ip> -j DROP

[Init]
name = default

3.重启fail2ban服务

systemctl restart fail2ban  || fail2ban-client reload

4.验证fail2ban规则情况

fail2ban-client status 

5.fail2ban验证日志规则匹配情况

fail2ban-regex /data/nginx/nginx-server/logs/access.log /etc/fail2ban/filter.d/nginx-bad-request.conf --print-all-matched --print-all-missed

0

评论区