Docker 容器 SSH 连接宿主机问题解决指南

Docker 容器 SSH 连接宿主机问题解决指南

问题场景

从 Docker 容器(openclaw)SSH 连接到宿主机及其他服务器时,遇到需要密码认证的问题。


一、问题汇总

问题 1:宿主机 authorized_keys 缺少公钥

项目 详情
现象 SSH 连接时提示输入密码
原因 容器的公钥未添加到服务器的 authorized_keys
解决 将容器公钥添加到宿主的 ~/.ssh/authorized_keys

问题 2:未指定私钥文件

项目 详情
现象 ssh user@host 直接提示密码
原因 未使用 -i 参数指定私钥文件
解决 ssh -i ~/.ssh/私钥 user@host

问题 3:私钥权限不正确

项目 详情
现象 SSH 忽略私钥,回退到密码认证
原因 私钥文件权限过于开放(644),SSH 拒绝使用
正确权限 私钥必须是 600,目录必须是 700

问题 4:Docker 挂载后权限重置

项目 详情
现象 重启容器后 SSH 需要密码
原因 从镜像创建容器时,文件权限被重置
解决 确保宿主机挂载目录的权限正确

二、架构说明

1
2
3
4
5
6
7
8
9
10
11
┌─────────────────────────────────────────────────────────────────┐
│ SSH 认证流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Docker 容器 宿主机/其他服务器 │
│ ┌─────────────┐ ┌───────────────┐ │
│ │ 私钥 │────── SSH 请求 ────────▶│ authorized_ │ │
│ │ id_rsa_claw│ -i 指定密钥 │ keys │ │
│ │ (权限600) │ │ (包含公钥) │ │
│ └─────────────┘ └───────────────┘ │
└─────────────────────────────────────────────────────────────────┘

关键点

  • 私钥保存在容器内(或挂载的宿主机目录)
  • 公钥保存在目标服务器的 authorized_keys
  • 连接时必须用 -i 指定私钥文件

三、docker-compose 配置

当前使用的挂载配置:

1
2
volumes:
- /home/bsuperstation/workdir/openclaw/openclaw_ssh:/home/node/.ssh

这意味着:

  • 容器内的 /home/node/.ssh 实际指向宿主机目录
  • 宿主机目录权限会直接影响容器内权限

四、完整解决步骤

步骤 1:生成密钥对(如果还没有)

1
2
# 在容器内或宿主机上生成
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_claw -N ""

步骤 2:将公钥添加到目标服务器

方法 A:使用 ssh-copy-id(需要密码)

1
ssh-copy-id -p 端口 -i ~/.ssh/id_rsa_claw.pub 用户名@服务器IP

方法 B:手动添加

1
2
3
4
5
6
# 查看公钥
cat ~/.ssh/id_rsa_claw.pub

# 登录目标服务器,执行
echo "公钥内容" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

步骤 3:确保私钥权限正确

1
2
3
4
5
6
7
# 宿主机上
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa*
chmod 600 ~/.ssh/authorized_keys

# 容器内(如果挂载目录权限正确会自动保持)
chmod 600 /home/node/.ssh/id_rsa_claw

步骤 4:使用私钥连接

1
2
3
4
5
# 连接到宿主机(端口 52957)
ssh -p 52957 -i /home/node/.ssh/id_rsa_claw bsuperstation@108.238.244.225

# 连接到其他服务器(默认端口 22)
ssh -i /home/node/.ssh/id_rsa_claw wtrobotic@192.168.1.180

步骤 5:配置 SSH config(可选,永久生效)

在容器内创建 ~/.ssh/config

1
2
3
4
5
6
7
8
9
10
Host bsuper
HostName 108.238.244.225
Port 52957
User bsuperstation
IdentityFile /home/node/.ssh/id_rsa_claw

Host robot
HostName 192.168.1.180
User wtrobotic
IdentityFile /home/node/.ssh/id_rsa_claw

之后可以简化为:

1
2
ssh bsuper
ssh robot

五、调试命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. 检查私钥权限
ls -la ~/.ssh/id_rsa*

# 2. 查看 authorized_keys 内容
cat ~/.ssh/authorized_keys

# 3. 检查公钥是否在 authorized_keys 中
grep -F "$(cat ~/.ssh/id_rsa_claw.pub)" ~/.ssh/authorized_keys && echo "已存在" || echo "不存在"

# 4. 详细模式测试连接
ssh -v -i ~/.ssh/id_rsa_claw 用户名@服务器IP

# 5. 确保权限正确
chmod 700 ~/.ssh
chmod 600 ~/.ssh/*

六、常见问题速查

问题 原因 解决
提示 password 私钥权限不对 chmod 600 私钥文件
提示 password 未指定 -i ssh -i 私钥 user@host
提示 password 公钥不在 authorized_keys 添加公钥到服务器
Permission denied (publickey) 公钥不匹配 确认公钥是否正确添加
Bad permissions 私钥太开放 必须 600 权限

七、当前环境状态

已配置的密钥

密钥 位置 用途
id_rsa_claw ~/.ssh/id_rsa_claw 连接宿主机和其他服务器
id_rsa ~/.ssh/id_rsa 备用密钥

authorized_keys 包含的公钥

  • 原有的 key (lianbin@wireless)
  • id_rsa_claw.pub
  • id_rsa.pub

测试结果

1
2
3
4
5
# 容器 → 宿主机
✅ ssh -p 52957 -i /home/node/.ssh/id_rsa_claw bsuperstation@108.238.244.225

# 容器 → 192.168.1.180
✅ ssh -i /home/node/.ssh/id_rsa_claw wtrobotic@192.168.1.180

八、预防措施

  1. 保持宿主机私钥权限正确

    1
    2
    chmod 600 /home/bsuperstation/workdir/openclaw/openclaw_ssh/.ssh/id_rsa*
    chmod 700 /home/bsuperstation/workdir/openclaw/openclaw_ssh/.ssh
  2. 重启容器后验证

    • 容器重启后检查权限:ls -la /home/node/.ssh/
    • 如权限不对,手动修复或重新挂载
  3. 使用 SSH config

    • 配置默认使用的密钥,避免忘记 -i 参数