使用 Fail2Ban 保护 Gitea

使用 Fail2Ban 保护 Gitea

Fail2Ban 是一个入侵检测系统框架,其工作原理是检查客户端登录日志,自动标记多次登录尝试失败的客户端 IP,并且在一段时间内阻止其访问。对与互联网上公开的服务器来说,这种防御手段可以在一定程度上缓解服务器压力。管理员在设置 Fail2Ban 时需谨慎处理,任何错误的配置将导致服务器无法访问。

准备工作

输出日志到文件

Gitea 日志中的一部分是 CLI、SSH 或 HTTP 客户端的登录授权结果,其中包含了远程客户端 IP 地址。这部分日志默认情况下只输出到控制台(配置为 MODE = console),调整日志输出模式为 MODE = file 之后,日志将输出到文件,便于 Fail2Ban 扫描该内容。

[log]
MODE      = file
LEVEL     = info
#ROOT_PATH = /path/to/log

日志默认存放于 gitea 程序的相对路径 log/gitea.log,如果设定了 ROOT_PATH 作为日志存放目录,那么日志位于 ${ROOT_PATH}/gitea.log。要查找准确的日志存放路径,还可以通过“管理后台 - 应用配置 - 日志配置”,查找 filename 字符串。

日志模式

当用户的身份验证失败时,Gitea 日志中会记录此类信息:

2018/04/26 18:15:54 [I] Failed authentication attempt for user from xxx.xxx.xxx.xxx
2020/10/15 16:08:44 [E] invalid credentials from xxx.xxx.xxx.xxx

安装 Fail2Ban

Debian / Ubuntu / Raspberry Pi OS

apt install fail2ban -y

Fedora / CentOS

# CentOS 7 需要安装 EPEL
sudo yum install epel-release
sudo yum install fail2ban -y

Synology DSM

给群晖配置 Fail2Ban 稍微有些麻烦。 已有的解决方案是采用 docker compose ,详情参考:

https://github.com/sosandroid/docker-fail2ban-synology

编辑规则

Filter

根据前面的日志,添加新的 filter 到 filter.d/gitea.conf

# /etc/fail2ban/filter.d/gitea.conf
[Definition]
failregex =  .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>
ignoreregex =

这条规则使用正则表达式从日志中过滤出包含下列字符串的客户端 IP。

  • Failed authentication attempt
  • invalid credentials
  • Attempted access of unknown user

Jail

然后,添加 jail 规则到 jail.d/gitea.conf,下面是示范:

# /etc/fail2ban/jail.d/gitea.conf
[gitea]
enabled = true                  # 功能开关
filter = gitea                  # 使用过滤器 gitea
logpath = /path/to/gitea.log    # 日志路径
maxretry = 10                   # 触发防御机制的最大尝试次数
findtime = 3600                 # 发现同一目标的时间间隔(秒)
bantime = 900                   # 封锁时间(秒)
action = iptables-allports      # 采取行动,禁止对方访问所有端口

上述规则规定客户端在 1 小时内,如果登录失败的次数达到 10 次,则通过 iptables 锁定该客户端 IP 地址 15 分钟。

另外,如果你的 Gitea 服务器运行在 Docker 容器中,并且直接将容器端口暴露到外部网络,你还需要添加 chain="FORWARD" 到 jail 规则以适应转发后的数据包。如果你在容器的宿主机上使用 Nginx 反向代理连接到 Gitea 时,则无需这样配置。

# /etc/fail2ban/jail.d/gitea.conf
[gitea]
...
action = iptables-allports[chain="FORWARD"]

最后,运行 sudo systemctl reload fail2ban 重载配置文件。

使用 fail2ban-client status gitea 检查 Fail2Ban 运行状态。

$ sudo fail2ban-client status gitea
Status for the jail: gitea
|- Filter
|  |- Currently failed: 24
|  |- Total failed:     49
|  `- File list:        /home/ferris/docker/gitea/data/data/log/gitea.log
`- Actions
   |- Currently banned: 0
   |- Total banned:     1
   `- Banned IP list:

测试 Fail2Ban

在浏览器中使用错误的用户名或密码反复登录 Gitea。如果浏览器报告无法访问目标地址,表示你的 IP 地址已被防火墙禁封。

解封 IP:

sudo fail2ban-client set gitea unbanip XX.XX.XX.XX

常见问题

反向代理

如果你使用 Nginx 反向代理到 Gitea 实例,你还需要设置 Nginx 的 HTTP 头部值 X-Real-IP 将真实的客户端 IP 地址传递给 Gitea。否则 Gitea 程序会将客户端地址错误解析为反向代理服务器的地址,例如回环地址 127.0.0.1

proxy_set_header X-Real-IP $remote_addr;

额外注意,在 Gitea 的配置文件 app.ini 中存在下列默认值:

REVERSE_PROXY_LIMIT = 1
REVERSE_PROXY_TRUSTED_PROXIES = 127.0.0.0/8,::1/128
  • REVERSE_PROXY_LIMIT 限制反向代理服务器的层数,设置为 0 表示不使用这些标头。
  • REVERSE_PROXY_TRUSTED_PROXIES 表示受信任的反向代理服务器网络地址。经过该网络地址转发来的流量,Gitea 会尝试扫描 X-Real-IP 头部得到真实客户端地址。(参考 configuration cheat sheet
posted @ 2022-12-23 18:00  Gitea  阅读(424)  评论(0编辑  收藏  举报