也就是 gitea/gitea:latest 一定存在。因为 Gitea 标准版部署在 Docker 下的 SSH 无法获取日志,尝试过构建镜像,补全 rsyslog ,配置 openssh ,总之得到一个结论:无法在其容器中获取到 SSH 相关爆破日志。

官网的描述很简单的,只需要改下 app.ini 中的 MODE,一改一个不吱声,gitea.log 不会包含 SSH 相关,请放心做无用功。在 app.ini 中,存在一个 ENABLE_SSH_LOG 仅对 Gitea 内建 SSH 有效,抱歉的是,标准版中的 openssh 不可与内建 SSH 调和。

当配置为 Gitea 自建,也就是 DISABLE_SSH 为 false ,START_SSH_SERVER 为 true 时,SSH 会在 Gitea 后台显示被禁用,同时开启则端口冲突(也许自己做镜像关闭 openssh 或者更换端口后,可以达到内建 ssh 的效果,只是无法简单在 app.ini 中实现),其他情况则直接 502。于是简单说,不支持。

在其 github 存在一个 issue ,回复是“既然日志不是由 Gitea 内建 SSH 提供,为何要求 ENABLE_SSH_LOG 会将日志写入 gitea.log ”。于是,只能剑走偏锋,在看到 potainer 中容器的 log 时,发现其正好可以查阅爆破日志,这也是一开始尝试自建镜像的原因。

问过 GPT,最终选择使用 docker logs -f,同时因为这样产生的日志缺少时间戳,而Fail2ban 需要时间戳,只能追加了--timestamps 补全时间戳并格式化,完整代码如下 gitea_log_monitor.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash

LOG_DIR="/path/to/save/log"
LOG_FILE="$LOG_DIR/gitea.log"
CONTAINER_NAME="gitea"

# 确保日志目录存在
mkdir -p "$LOG_DIR"

while true; do
# 检查 gitea 容器是否在运行
if docker ps --format "{{.Names}}" | grep -q "^$CONTAINER_NAME$"; then
echo "[$(date +"%Y-%m-%d %H:%M:%S")] 监控 $CONTAINER_NAME 容器日志..."
# 获取容器日志并格式化时间戳
docker logs -f --timestamps "$CONTAINER_NAME" | \
awk '{ cmd="date -d "$1" +\"%Y-%m-%d %H:%M:%S\""; cmd | getline ts; close(cmd); print ts, substr($0, index($0,$2)) }' >> "$LOG_FILE"
else
echo "[$(date +"%Y-%m-%d %H:%M:%S")] $CONTAINER_NAME 容器未运行,等待启动..."
fi

sleep 5 # 每 5 秒检查一次容器状态
done

增加一个系统服务:gitea-log-monitor.service ,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
[Unit]
Description=Gitea Log Monitor
After=docker.service
Requires=docker.service

[Service]
ExecStart=/path/to/gitea_log_monitor.sh
Restart=always
User=root

[Install]
WantedBy=multi-user.target

写一个执行脚本:install ,内容如下:

1
2
3
4
5
6
7
#!/bin/bash
chmod +x /path/to/gitea_log_monitor.sh
cp /path/to/gitea-log-monitor.service /etc/systemd/system/gitea-log-monitor.service

systemctl daemon-reload
systemctl enable gitea-log-monitor
systemctl start gitea-log-monitor

以上解决方案描述:系统启动时开启一个脚本轮询 gitea 容器日志并输出至文件,包含了容器未运行的容错处理。

总之,日志文件解决了,Fail2ban 就不是太想赘述了,当然,如果还是使用官网的那些规则,相信一条鱼都抓不到。简单贡献一下匹配规则:gitea.conf

1
2
3
4
5
6
7
8
[Definition]
failregex = ^.*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST> .*
^.* Invalid user .* from <HOST> .*
^.* <HOST> not allowed because not listed in AllowUsers.*
^Disconnected from invalid user .* <HOST> port.*
^Connection closed by invalid user .* <HOST> port.*
^Timeout before authentication for connection from <HOST> .*
ignoreregex =

2. 创建 Jail 配置

创建 Fail2ban Jail 配置,注意对于 Docker 环境中的 SSH,必须使用 FORWARD 链而非 DOCKER-USER 链才能有效工作:

1
2
3
4
5
6
[gitea]
enabled = true
chain = FORWARD
filter = gitea
logpath = /path/to/gitea.log
banaction = iptables-allports[blocktype=DROP]

结果自然是简单,试错是相当的麻烦。这里肯定不是 gitea 的最优解,却是获取容器日志的通解。以上。