优雅地使用VSCode连接chroot环境

本文最后更新于:2023年10月15日

很多时候使用chroot是为了在与主机隔离的环境中进行开发,而VSCode并没有支持chroot环境。于是参考一个 Issue [1],我发现了一种较为优雅的使用VSCode连接chroot环境的方法。

总体来说,先使用schroot开启一个session,再配置ssh server进行chroot,从而使用VSCode的Romte SSH插件连接到chroot环境。

schroot 配置

schroot可以用来简化chroot的操作,比如在chroot前自动进行挂载路径、拷贝文件等操作,也可以方便地在不同chroot环境中切换。

Archlinux下schroot的配置文件在 /etc/schroot,其中 schroot.conf是主配置文件,chroot.d下放置各个chroot环境的配置,setup.d 下放置的了chroot启动时应执行的脚本,剩下的每个文件夹是一个”profile”,包含copyfilesfstabnssdatabases 三个文件,有时还有 config 文件。

/etc/schroot/
├── arch32/
├── buildd/
├── chroot.d/
├── default/
├── desktop/
├── minimal/
├── sbuild/
├── schroot.conf
└── setup.d/
/etc/schroot/default/
├── copyfiles
├── fstab
└── nssdatabases

要配置schroot,应在 chroot.d 中新建一个文件,参考该目录下自带的示例,我的配置文件如下。

[bookworm]
description=Debian Bookworm
aliases=deb
type=directory
directory=/srv/chroot/bookworm
users=zy,zydeb
root-users=zy,zydeb
profile=my_profile
personality=linux
  • directory 是chroot目录,这目录下一般应该是一个Linux发行版的根目录,可以用 debootstrap 创建。
  • users, root-users 是主机上的用户,此处创建一个了额外的用户,是为了后面配置ssh。
  • profile 就是上面说到的 profile,可以根据需要选择一个或自己编写。

现在就能进入chroot环境了。

schroot -c bookworm -u root -d /root

可以先用root用户登录进行一些配置,如更换镜像源、安装软件包、添加用户等。

一般会添加主机上存在的用户,方便普通用户直接登录。配置好后,就能以普通用户身份登录了。

schroot -c bookworm

值得一提的是,不指定时,默认使用当前用户名和当前目录。所以当 chroot 环境中不存在同名用户或同名目录时,可能会看到警告甚至不能 chroot。

schroot session

schroot 有一个 “session“ 功能,按 schroot 手册页[2]的说法,这可以从程序或脚本运行任意数量的命令,并在命令间保持状态,而且每次进入chroot都创建了一个 session,只是在退出时 session 关闭了而已。

其实创建 session 的过程实际是创建了一个“挂载点”(是否还有其他操作并不清楚)。如果使用 schroot 进入 chroot 环境且不要退出,可以发现它在 /run/schroot/mount 下挂载了一些目录。以下是 mount 命令的输出(进行了一些删减)。

/dev/nvme0n1p5 on /run/schroot/mount/bookworm-50f49361-5cbd-420b-bb55-e6355dfeb1c4 type btrfs
proc on /run/schroot/mount/bookworm-50f49361-5cbd-420b-bb55-e6355dfeb1c4/proc type proc
sys on /run/schroot/mount/bookworm-50f49361-5cbd-420b-bb55-e6355dfeb1c4/sys type sysfs
dev on /run/schroot/mount/bookworm-50f49361-5cbd-420b-bb55-e6355dfeb1c4/dev type devtmpfs
devpts on /run/schroot/mount/bookworm-50f49361-5cbd-420b-bb55-e6355dfeb1c4/dev/pts type devpts
tmpfs on /run/schroot/mount/bookworm-50f49361-5cbd-420b-bb55-e6355dfeb1c4/tmp type tmpfs

其中 bookworm-50f49361-5cbd-420b-bb55-e6355dfeb1c4 是 schroot 随机生成的 session id,总是以配置的“chroot 名字”开头。当然,这也可以手动指定。

在退出 chroot 环境后,上面的挂载就被自动取消了。

而 session 功能,就是进行挂载后,可以多次进入 chroot 环境,退出后也不会取消挂载点,直到手动关闭 session,或者重启。

于是就可以启动 session,从而得到一个固定的“挂载点”,以便后续 ssh 连接。

schroot -c bookworm -b -n session_id

进入、关闭和恢复 session:

schroot -r -c session_id
schroot -e -c session_id
schroot --recover-session -c session_id

在重启后挂载点会丢失,需要恢复 session (重新启动一个同名 session 似乎也可以,不清楚有无区别)。

ssh server 配置

/etc/ssh/sshd_config 末尾增加规则。

Match User zydeb
    ChrootDirectory /run/schroot/mount/session_id
    Subsystem sftp internal-sftp

参考的 Issue [1] 中使用了 ForceCommand

原本他的用法会报错,他说报错可以忽略,但我使用总会断开连接,于是改成下面这样。

Match User zydeb
   ForceCommand /usr/bin/schroot -u zydeb -r -c session_id -- $SSH_ORIGINAL_COMMAND
   Subsystem sftp internal-sftp

此外,Issue 中还有配置 authorzed_keys 文件来执行命令的方法,但 sftp 和 scp 可能没法使用。

其中 Subsystem sftp internal-sftp,是为了能让 sftp 和 scp 正常运行,因为 Archlinux 和 Debian 中 sftp-server 的位置不同。

最后

最后使用 VSCode 的 Remote SSH 连接 zydeb@localhost 即可。

可以将其写进 .ssh/config 方便连接。

Host zydeb
    HostName localhost
    User zydeb

参考


优雅地使用VSCode连接chroot环境
http://toneoesa.github.io/20231014/52d5df4677b9/
作者
ZY
发布于
2023年10月14日
许可协议