在使用 Gitea 内建 sshd 服务器时,如何配置 Fail2ban?

目前我用 Docker Compose 搭建了 Gitea 服务器,由于使用容器部署,所以决定使用 Gitea 内建的 sshd 服务器来支持 git ssh 访问,并且将端口映射到宿主机 22 端口(对外开放)。

然后这几天检查日志发现 git sshd 正在被爆破,所以想装个 Fail2ban 来缓解这个问题,不过在根据官方文档配置完成后,我发现 Fail2ban 没办法检测登录失败,因为 Gitea 的内建 sshd 服务器似乎只会把日志输出到 stdout,而不会打印到 gitea.log 文件,所以想请教一下如何解决这个日志的问题?

还有个问题,能否强制关闭 Gitea 内建 sshd 服务器的密码登录?或者说其实它已经关闭了?

在查阅了这个 Issue 后,我大概了解了原因,其实 Gitea 并没有使用内建 SSH 服务器,实际使用的是 OpenSSH 的 sshd 服务器,看来现在得找出 sshd 的日志路径了。

关于Fail2ban,官方文档里存在这个介绍:设置 Fail2ban - Docs
看起来写的很清楚,我没试过,你可以试试。

我已经按照官方文档的步骤配置了,官方文档是以使用 Gitea 内建 SSH 服务器为基础提供的配置指引,但是通过 Docker Root 方式(非 Rootless)进行部署的话,会强制使用 OpenSSH 服务端而不是内建 SSH 服务端,OpenSSH 服务端又只能通过 Linux 的日志框架来接收日志,但日志框架不好在 Docker 内运行,所以没办法收集认证失败的日志。

目前我已经看到有关 Issue 提供了一个间接解决问题的方案,我等有空了试试看。

你提到的”通过 Docker Root 方式(非 Rootless)进行部署的话,会强制使用 OpenSSH 服务端而不是内建 SSH 服务端“,这句话的表述不正确。所谓”内建“的ssh,就是OpenSSH。宿主linux本身使用的就是OpenSSH。Gitea的Docker镜像用了alphine linux,Alphine Linux用的也是OpenSSH。
使用Docker部署Gitea,SSH有两种打开方式,一种是通过容器内的SSH把端口映射到宿主机上,外部直接通过这个端口访问。如果避开了标准的22号端口,比如使用222,那么git提交的时候就不能使用标准的命令方式,而得使用ssh scp的那种路径模式,感觉有点不爽。另外我看到过官方文档里也提过有一种转发模式,没细看,但觉得可以行得通。具体操作就是让宿主机的sshd收到git请求后,根据authorized_keys文件设定的内容,把git请求转发到宿主的localhost的222(该端口映射到容器的22)。这一段,在https://docs.gitea.io/zh-cn/installation/install-with-docker/#ssh-容器直通 里说的很清楚。在Fail2ban章节也说了它的日志怎么生成,生成位置。你可以在这里设定成你容器挂载的来自宿主的数据目录,然后在宿主的Fail2ban上指定该位置、action。

回到你第一楼的问题:

因为 Gitea 的内建 sshd 服务器似乎只会把日志输出到 stdout,而不会打印到 gitea.log 文件

官方文档已经告诉你怎么输出到file:

你需要将 Gitea 的日志输出模式从默认的 console 更改为 file
对应的Gitea的配置项在app.ini中是:

[log]
MODE = console # 把console改成file
LEVEL = info
ROUTER = console # 改成file
ROOT_PATH = /data/gitea/log # 改成你挂载的路径下的文件。正常情况下,/data本来就应该是个挂载的目录

你试试?

关于日志,官方文档的描述在这里:Logging Configuration - Docs

这是 Gitea 的内建 SSH 服务器源码:

具体的探讨我打算等白天再继续,你可以先看一下。

谢谢指正。
根据你的提醒,在文档中看到了app.ini中关于built-in SSH server的描述位置:

  • START_SSH_SERVER: false: When enabled, use the built-in SSH server.
  • BUILTIN_SSH_SERVER_USER: %(RUN_USER)s: Username to use for the built-in SSH Server.

我的安装是基于Gitea的Docker镜像安装的,在系统进程中只看到这个:

s6-supervise openssh

这确实让我认为Gitea并没有自建ssh。
自建的ssh的日志应该可以通过日志选项开启并指定路径。
如果是OpenSSH的日志,一般会在/var/log/secure或者/var/log/message下。
不过我看了下我的容器里的配置,sshd日志缺省并不输出到文件,启动命令也是直接将日志重定向到标准输出了。但是sshd的登录日志,在docker logs里都有:

docker logs -f gitea

Accepted publickey for git from 39.xx.xx.xx port 37472 ssh2: RSA SHA256:UUUULUIULULUsUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
Received disconnect from 39.xx.xx.xx port 37472:11: disconnected by user
Disconnected from user git 39.xx.xx.xx port 37472

要么就修改sshd_config将日志输出到外部文件,要么就跑一个进程运行

docker logs -f gitea >> /var/log/gitea_ssh.log

嗯,关于 docker logs 重定向的方法,由于使用了 compose 部署,所以可能缺少足够的灵活性。

目前打算将镜像迁移到 Rootless 版本,然后启用gitea内建ssh服务器。