创建 gitea 后如何配置才能使用 gitssh

如题,安装商店的 gitea 以后发现容器的 22端口映射为 2222 端口,使用 git@地址git clone的时候提示要输入密码,注,已经将 2222 端口映射到公网 ip 上,已经在 giea 中添加了相应主机的密钥

建议参考 Gitea 官方文档

由于 SSH 在容器内运行,因此,如果需要 SSH 支持,则需要将 SSH 从主机传递到容器。一种选择是在非标准端口上运行容器 SSH(或将主机端口移至非标准端口)。另一个可能更直接的选择是将 SSH 连接从主机转发到容器。下面将说明此设置。

本指南假定您已经在名为 git 的主机上创建了一个用户,该用户与容器值 USER_UID/USER_GID 共享相同的 UID/GID。这些值可以在 docker-compose.yml 中设置为环境变量:

environment:  - USER_UID=1000  - USER_GID=1000

接下来将主机的 /home/git/.ssh 装入容器。否则,SSH 身份验证将无法在容器内运行。

volumes:  - /home/git/.ssh/:/data/git/.ssh

现在,需要在主机上创建 SSH 密钥对。该密钥对将用于向主机验证主机上的 git 用户。

sudo -u git ssh-keygen -t rsa -b 4096 -C "Gitea Host Key"

在下一步中,需要在主机上创建一个名为 /usr/local/bin/gitea 的文件(具有可执行权限)。该文件将发出从主机到容器的 SSH 转发。将以下内容添加到 /usr/local/bin/gitea

ssh -p 2222 -o StrictHostKeyChecking=no git@127.0.0.1 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@"

为了使转发正常工作,需要将容器(22)的 SSH 端口映射到 docker-compose.yml 中的主机端口 2222。由于此端口不需要暴露给外界,因此可以将其映射到主机的 localhost

ports:  # [...]  - "127.0.0.1:2222:22"

另外,主机上的 /home/git/.ssh/authorized_keys 需要修改。它需要以与 Gitea 容器内的 authorized_keys 相同的方式进行操作。因此,将您在上面创建的密钥(“Gitea 主机密钥”)的公共密钥添加到 ~/git/.ssh/authorized_keys。这可以通过 echo "$(cat /home/git/.ssh/id_rsa.pub)" >> /home/git/.ssh/authorized_keys 完成。重要提示:来自 git 用户的公钥需要“按原样”添加,而通过 Gitea 网络界面添加的所有其他公钥将以 command="/app [...] 作为前缀。

该文件应该看起来像:

# SSH pubkey from git userssh-rsa <Gitea Host Key># other keys from userscommand="/usr/local/bin/gitea --config=/data/gitea/conf/app.ini serv key-1",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty <user pubkey>

这是详细的说明,当发出 SSH 请求时会发生什么:

  1. 使用 git 用户向主机发出 SSH 请求,例如 git clone git@domain:user/repo.git
  2. /home/git/.ssh/authorized_keys 中,该命令执行 /usr/local/bin/gitea 脚本。
  3. /usr/local/bin/gitea 将 SSH 请求转发到端口 2222,该端口已映射到容器的 SSH 端口(22)。
  4. 由于 /home/git/.ssh/authorized_keys 中存在 git 用户的公钥,因此身份验证主机 → 容器成功,并且 SSH 请求转发到在 docker 容器中运行的 Gitea。

如果在 Gitea Web 界面中添加了新的 SSH 密钥,它将以与现有密钥相同的方式附加到 .ssh/authorized_keys 中。

注意

SSH 容器直通仅在以下情况下有效

  • 在容器中使用 opensshd
  • 如果未将 AuthorizedKeysCommandSSH_CREATE_AUTHORIZED_KEYS_FILE = false 结合使用以禁用授权文件密钥生成
  • LOCAL_ROOT_URL 不变