我正在远程服务器上构建自定义 Debian 环境,并通过 SSH 连接到该服务器。这涉及构建 debootstrap 环境,然后进入该环境以运行自定义安装程序。作为自定义安装过程的一部分,我需要安装程序能够通过 ssh 从 chroot 环境迁移到另一个远程服务器,并重新使用我的 ssh-agent 的 SSH 凭据外部chroot 知道。
我实在想不出该怎么做。原则上,我思考我应该能够使用 socat 将 $SSH_AUTH_SOCK 转发到 chroot 环境中,然后再调用 chroot,如下所示:
socat UNIX-CONNECT:$SSH_AUTH_SOCK UNIX-LISTEN:chroot_root$SSH_AUTH_SOCK,fork &
sudo -E chroot chroot_root /bin/bash
但是当我尝试在 chroot 中使用 ssh 时,socat 的管道就断了,我想这是可以理解的(在某种程度上)。
有什么办法可以解决这个问题吗?我有一个后备方案,即在 chroot 之前设置一个 SSH 主套接字,并将其用于 chroot 中的所有内容,但这将涉及对安装程序进行相当侵入性的重写,因此我真的不太喜欢那个计划。
更新
事实证明,只需创建到套接字的硬链接即可获得我想要的效果。老实说,我没想到这会起作用。
答案1
您可以将 SSH 代理转发到 chroot,但您必须经过几个环节,其中第一是使套接字在 chroot 中可访问,第二是告知 chroot 内的用户。
为了使套接字可用,socat
只要权限设置正确,OP 的建议就可以使用。假设您正在使用脚本启动 chroot,以下代码片段用于socat
在 chroot 中提供代理套接字:
# Set up a SSH AGENT forward socket
if [ -n "$SSH_AUTH_SOCK" ]
then
_dir="$mnt$(dirname $SSH_AUTH_SOCK)"
_owner=$(awk -F':' '{if ($1=="alice") {print $3":"$4}}' $mnt/etc/passwd)
mkdir "$_dir"
chown "$_owner" "$_dir"
socat UNIX-CONNECT:$SSH_AUTH_SOCK \
UNIX-LISTEN:$mnt$SSH_AUTH_SOCK,fork,user=${_owner%:*} &
socat_pid=$!
export SSH_AUTH_SOCK
fi
它建立了用户的uid
和(gid
爱丽丝在示例中),chroot 中的进程应该能够访问代理。然后,它创建该目录,并socat
以与 OP 几乎相同的方式建立一个。添加的是 pirce user=${_owner%:*}
,它在 chroot 中的套接字上设置 uid,以便爱丽丝可以访问它。
然后它会记住socat
PID,以便在 chroot 退出时可以将其拆除。最后它会导出变量SSH_AUTH_SOCK
以使其在 chroot 中可用。
现在,chroot
只能通过以下方式完成:我的猜测是,脚本由拥有代理进程的普通用户root
运行。如果这是准确的,那么还有一件事要做,那就是允许将环境变量传递到脚本中。为此,请编辑(批准的机制是这样做)并添加以下内容:sudo
sudo
/etc sudoers
sudo visudo
Defaults env_keep+=SSH_AUTH_SOCK
/etc/sudoers
如果要在 chroot 中sudo
使用,也需要在 chroot 中进行此更改(即从 切换root
到alice
)。
这是普通用户查看的 chroot 中的代理套接字的示例。
$ ls -l $SSH_AUTH_SOCK
srwxr-xr-x 1 alice root 0 Feb 1 15:06 /tmp/ssh-q1ntaubl6I2z/agent.1443