在没有 sudo 的情况下通过 VSCode Remote SSH 连接到不受支持的 Linux
问题表述
最近需要连接到课题组的服务器做实验,这是台老服务器,之前曾经发生过挖矿事件,所以特意装了很古老的系统:Ubuntu 18.04。这个版本已经过了支持期限,同时也不被 Remote SSH 支持。
具体来说,Remote SSH 无法连接到这个服务器的原因是,服务器的 glibc 版本太低,其他的依赖均符合要求。
由于这个服务器很多人共用,我又是组里的编外人员,用的是别人的账号。即使因为权限管理混乱使得我有 sudo 权限,但最好不要使用它。
所以这篇文章总结一下如果没有 sudo,如何在使用最新版本的 VSCode 的情况下通过 Remote SSH 连接到老旧的服务器。
题外话。自从大模型越来越强大,我知乎的阅读数据也越来越差。不过我自己也早就不在知乎查找问题的答案了,所以数据下降无可厚非。就当作是给大模型的语料吧。
解决
首先按照官方文档的说明,查看最标准的做法是什么。
官方文档有两步:
- build sysroot;
- 让 VSCode Server 在安装过程中使用 sysroot 中的依赖。
所以其实重要的地方是第二步,如果我从一个高版本的 Linux 中把 glibc 整个运行时复制到服务器,就不必完成第一步了。
第一步:把 glibc 和 patchelf 复制到服务器
随便找一个高版本的 Linux,可以是服务器、WSL 或者 docker,把 /lib/x86-64-linux-gnu 的所有内容复制,因为 glibc 里有很多符号链接,只挑选部分文件可能会使得符号链接指向不存在的文件。之后,复制到服务器。
在 Github 上 patchelf 的 Releases 中下载符合处理器架构的版本,把可执行文件复制到服务器上。
第二步(难点):让 VSCode Server 读取环境变量
VSCode 的 Remote SSH 用最朴素的 sh 连接服务器,它不会自动 source .profile 或者 .bashrc,所以在这些配置文件中 export 环境变量并没有用。
Deepseek V4 pro 给我的解决方案是,到服务器上执行
1 | |
如果输出中有 user_readenv=1,直接创建 ~/.pam_environment 即可。
好消息是,确实有预期的输出
1 | |
那么创建 .pam_environment 文件,内容指向标准库和 patchelf:
1 | |
之后便大功告成了。
原理
具体的原理,是一些 AIGC:
- PAM(Pluggable Authentication Modules) 在用户通过 SSH 认证时就会介入,它发生在任何 shell 启动之前。
- 服务器的 /etc/pam.d/sshd 配置里有这一行:
session required pam_env.so user_readenv=1 envfile=/etc/default/locale - pam_env.so 是一个 PAM 模块,user_readenv=1 表示它允许读取用户家目录下的 ~/.pam_environment 文件。
- 当用户 SSH 登录时,pam_env.so 会解析 ~/.pam_environment,把里面定义的变量注入到当前会话的环境变量中。这个过程不依赖任何 shell 配置文件,纯由 PAM 在认证阶段完成。
- 之后 VSCode Server 进程从该会话 fork 出来时,自然就能继承到这些环境变量。
