合租房中建家(二):普通账户复用与VSCode使能
之前的文章中我已经介绍过如果在共用的普通 Linux 账户下配置个人专用的开发环境以尽量避免他人的干扰,这篇文章中将介绍一些更优的做法来进一步改进使用体验。
更好地复用普通账户
此前我介绍了通过在自己的目录中启动新 SHELL 的方式来避免家目录中的 .bashrc
等文件的干扰的方法,但这种方式并不能一定隔绝这些文件的影响,因为 SSH 登录到服务器时总是会先进入 Bash 环境,只要我们的 SHELL 是 Bash 间接启动的,那就难免会受到 Bash 启动文件的影响。
如果账户从一开始就被确定为共用账户,那么我们可以在一开始就将这些文件的影响最小化。
首先,删除 ~/.bashrc
、~/.bash_profile
、~/.bash_login
,然后修改或创建 ~/.profile
文件为以下内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
if [ "$LC_WHO" == "gyh" ]; then
# 将家目录设置到我自己的目录
export HOME=$HOME/gyh
# 直接进入到我自己的 SHELL
exec ~/path/to/my/zsh
# exec 可以让 Bash 直接运行后面的程序,而不是启动一个子进程等待它结束,因此该行命令不会返回。
return
fi
cat <<- EOF
==================== !!! 注意 !!! ====================
==================== !!! 注意 !!! ====================
==================== !!! 注意 !!! ====================
为了尽量消除因共用普通账户而给大家带来的干扰,请所有人遵守以下使用规则:
1. 请在 ~ 中以自己姓名创建独立目录,并将自己的所有文件都放入其中
2. .bashrc 已禁用,请不要在 ~ 中创建 .bashrc .bash_profile
.bash_login 等文件,更不要在里面写入只适用于自己的配置内容
3. 如果你仍然需要 .bashrc 等环境初始化机制,请考虑通过在自己的目录
中启动新的 SHELL 来替代实现
例如: HOME=\$HOME/gyh /bin/bash
4. 你可以通过修改 ~/.profile 来在使用 SSH 连接到服务器时直接使用
自己的家目录和 SHELL
请在你的 ~/.ssh/config 中设置 "SetEnv LC_WHO=xxx",然后参考
~/.profile 中的既有内容,在其中添加你自己的情况处理代码
5. 千万不要删除别人的目录!
千万不要删除别人的目录!
千万不要删除别人的目录!
(如果你不想被打的话)
EOF
if ! [[ -z "$LC_WHO" ]]; then
echo "警告:未处理 LC_WHO=$LC_WHO ,请在 ~/.profile 中添加相关的处理代码"
fi
这样,所有人在登录时都会看到这个提示。
然后,修改自己的 ~/.ssh/config
文件,在服务器的配置中添加 SetEnv LC_WHO=gyh
:
1
2
3
Host PublicServer
User PublicUser
SetEnv LC_WHO=gyh
这样在登录时:
- SSH 客户端会将
LC_WHO=gyh
环境变量传递给 SSH 服务器; - 服务器会先设置
LC_WHO
环境变量,然后启动 SHELL(即 Bash); - Bash 查找并执行启动文件,最终会运行
~/.profile
; ~/.profile
中检查了LC_WHO
环境变量,命中了gyh
if 分支;- if 分支里将
HOME
设为自己的目录,然后使用exec
进入新 SHELL; - 由于
exec
会将原来的 Bash 进程会被替换掉,最终就实现了直接登入自己 SHELL 的效果。
使用这种方式能实现非常好的复用效果,它的实际体验几乎就和拥有一个独立的普通账户一样。
但是这一方式有好几个约束:
- OpenSSH 从 7.8 版本才开始支持
SetEnv
,你的客户端和服务器都必须比这更新; - 服务器上的
/etc/sshd_config
的AcceptEnv
选项里必须允许LC_WHO
环境变量。
一般情况下(比如 ubuntu22.04 里),sshd 的 AcceptEnv
默认会被设为 LANG LC_*
,因此可以传递这个变量。但是有些安全性比较严格的发行版,比如 RHEL,严格限定了 AcceptEnv
的内容,这时你就需要在服务器上修改 /etc/sshd_config
了。
确切来说,我们这里只是需要一种在 ~/.profile
中识别 SSH 客户端的办法,除了 SetEnv
还可以有其它方式:
通过 SSH 客户端的 IP 地址来识别,即环境变量
$SSH_CONNECTION
;$SSH_CONNECTION
在很早的 OpenSSH 版本中就已经存在了,因此这种方式适用性最好。但因为 IP 地址很可能不固定,所以这种方式并不是很好的选择。通过
$SSH_USER_AUTH
来获取登录所使用的公钥,然后根据公钥来区分不同用户;这种方式要求每个用户都用自己的私钥登入这个公共账户,而不是大家一起用一个私钥,这稍微有点麻烦,但问题不大。可是这种方式也需要在服务器上修改
/etc/sshd_config
配置AuthorizedKeysCommand yes
,这个配置项在一些发行版上默认是关闭的。
直白来讲,我私以为最好的方式还是为每个用户分配一个普通账户,就像 Unix 最初被设计的那样。对于系统管理员而言,如果需要管理和计费,则应该改用 Unix 用户组来管理,而不是以账户作为管理单元(毕竟用户组设计出来不就是来干这个事的吗?!),普通用户应该被允许创建同组下的其它用户(这可以通过给定制的
adduser
命令添加-s
选项来实现),如果有必要,可以设个小组长等等。
使能 VSCode 远程开发
TODO