从Permission denied到成功克隆:手把手调试Gitea Docker版SSH直通的完整排错指南

当你在Docker环境中部署Gitea并尝试配置SSH直通时,可能会遇到各种令人沮丧的错误。本文将带你一步步诊断和解决这些常见问题,从最初的"Permission denied"到最终成功克隆仓库。

1. 理解SSH直通的基本原理

Gitea的SSH直通功能允许用户通过宿主机的SSH端口直接访问容器内的Git仓库,而无需额外指定端口号。这种机制的核心在于:

  • 请求转发:当用户通过SSH连接到宿主机时,请求会被转发到Gitea容器
  • 密钥验证:系统会检查authorized_keys文件中的公钥
  • 脚本执行:匹配的公钥会触发转发脚本,将请求发送到容器

这种架构虽然优雅,但在配置过程中容易出现多个环节的故障点。下面我们将按照实际排错流程,从外到内逐步分析。

2. 诊断连接被拒绝问题

当你看到类似Connection refused的错误时,说明SSH连接在最初阶段就失败了。这通常意味着:

$ ssh -T git@your-server
ssh: connect to host your-server port 22: Connection refused

2.1 检查SSH服务状态

首先确认宿主机上的SSH服务是否正常运行:

# 检查SSH服务状态
sudo systemctl status sshd

# 如果没有运行,启动服务
sudo systemctl start sshd

# 设置开机自启
sudo systemctl enable sshd

2.2 验证端口监听情况

使用以下命令检查22端口是否被监听:

sudo netstat -tuln | grep :22

如果没有输出,说明SSH服务没有正确监听端口。在WSL环境中,可能需要额外安装OpenSSH服务器:

sudo apt update && sudo apt install openssh-server

3. 解决Permission denied错误

当SSH服务正常运行但认证失败时,你会看到类似这样的错误:

bash: line 1: /usr/local/bin/gitea: Permission denied

3.1 检查转发脚本权限

这个错误通常是因为转发脚本没有执行权限。检查脚本的权限设置:

ls -l /usr/local/bin/gitea

正确的权限应该是可执行:

-rwxr-xr-x 1 root root 109 Feb 7 14:47 /usr/local/bin/gitea

如果权限不正确,使用以下命令修复:

sudo chmod +x /usr/local/bin/gitea

3.2 验证脚本所有权

确保脚本的所有权设置正确,特别是当你在git用户下操作时:

sudo chown git:git /usr/local/bin/gitea

4. 调试authorized_keys文件问题

authorized_keys文件的格式错误是另一个常见故障点。正确的文件应该包含:

  1. Gitea主机密钥(原样添加)
  2. 用户公钥(以command=前缀自动添加)

4.1 检查文件内容格式

使用以下命令查看文件内容:

cat /home/git/.ssh/authorized_keys

正确的格式示例:

ssh-rsa <Gitea Host Key>
command="/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>

4.2 修复文件权限问题

确保.ssh目录和authorized_keys文件有正确的权限:

chmod 700 /home/git/.ssh
chmod 600 /home/git/.ssh/authorized_keys
chown -R git:git /home/git/.ssh

5. 容器端口映射配置

Docker的端口映射配置对SSH直通至关重要。检查你的docker-compose.yml文件:

ports:
  - "3000:3000"  # Web界面
  - "127.0.0.1:2222:22"  # SSH端口(仅限本地访问)

关键点:

  • SSH端口应该限制为本地回环地址(127.0.0.1)
  • 确保容器内部的SSH端口是22(默认值)
  • 宿主机的映射端口(如2222)需要与转发脚本中的端口一致

6. 用户和权限一致性检查

Docker容器内外用户权限不一致会导致各种问题。确保:

  1. 容器内外使用相同的UID/GID
  2. 挂载的目录有正确的所有权

检查git用户的UID/GID:

id git

然后在docker-compose.yml中设置对应的值:

environment:
  - USER_UID=1002
  - USER_GID=1002

7. 完整的排错流程图

为了帮助你快速定位问题,以下是SSH直通的排错流程:

  1. 连接被拒绝

    • 检查SSH服务是否运行
    • 验证22端口是否监听
  2. Permission denied

    • 检查转发脚本权限
    • 验证脚本所有权
  3. 认证失败

    • 检查authorized_keys格式
    • 验证文件权限
  4. 端口映射问题

    • 确认Docker端口配置
    • 检查转发脚本中的端口号
  5. 权限不一致

    • 核对UID/GID
    • 检查挂载目录所有权

8. 验证SSH直通是否成功

完成所有配置后,使用以下命令测试:

ssh -T git@your-server

成功的结果应该显示:

Hi there, <username>! You've successfully authenticated...

然后尝试克隆一个仓库:

git clone git@your-server:username/repo.git

如果一切正常,你应该能看到仓库被成功克隆。如果在任何步骤遇到问题,可以按照上述排错流程逐步检查。记住,大多数SSH直通问题都源于权限设置或配置不一致,仔细检查每个环节的细节是解决问题的关键。

更多推荐