需同时配置服务端AcceptEnv和客户端SendEnv才能传递环境变量,仅对SSH-2生效;服务端需明确列出允许接收的变量(如LANG、LC_*等),客户端需对应声明发送;配置后须重载sshd且变量名大小写必须严格匹配。

要让 Linux 上的 SSH 服务允许客户端传递并使用环境变量,需同时配置服务端和客户端,且仅对 SSH-2 协议生效。关键不是“开启转发”,而是明确声明哪些变量可被接收和设入登录会话。
✅ 服务端配置:允许接收特定环境变量
OpenSSH 服务端(sshd)默认拒绝所有客户端传来的环境变量。需在 /etc/ssh/sshd_config 中启用并限定范围:
# 允许客户端发送以下环境变量(支持通配符) AcceptEnv LANG LC_* PATH TERM TZ # 或更精确写法(推荐) AcceptEnv LANG LC_COLLATE LC_CTYPE LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME AcceptEnv PATH TERM TZ
⚠️ 注意事项:
-
AcceptEnv后面的变量名必须与客户端实际发送的一致(区分大小写); -
LC_*是通配符写法,匹配所有以LC_开头的变量(如LC_ALL、LC_TIME); - 不建议写
AcceptEnv *—— 安全风险高,可能被用于绕过限制; - 修改后需重载服务:
sudo systemctl reload sshd(或sudo service ssh reload)。
✅ 客户端配置:主动发送指定环境变量
客户端默认不发送任何环境变量。需在本地 ~/.ssh/config 或命令行中显式声明:
方法一:全局或主机级配置(推荐)
编辑 ~/.ssh/config:
Host myserver
HostName 192.168.1.100
User alice
SendEnv LANG LC_* TERM TZ方法二:命令行临时发送
ssh -o "SendEnv=LANG,LC_ALL,TERM" user@host
? 变量名必须与服务端 AcceptEnv 列表中的完全匹配(例如服务端写了 LC_*,客户端发 LC_ALL 就有效;若服务端只写了 LC_CTYPE,发 LC_ALL 就会被丢弃)。
✅ 验证是否生效
登录后在远程 shell 中检查:
echo $LANG env | grep "^LC_"
也可用以下命令测试变量是否被正确注入:
ssh user@host 'printenv | grep -E "^(LANG|LC_|TERM|TZ)"'
如果输出为空,说明未成功传递 —— 请依次排查:
- 服务端
sshd_config是否包含对应AcceptEnv且已重载; - 客户端是否设置了
SendEnv且拼写一致; - 连接是否使用 SSH-2(OpenSSH 默认就是,基本无需担心);
- 用户 shell 初始化脚本(如
~/.bashrc)是否覆盖了传入的变量(少见但可能)。
❌ 常见误区
- 认为
PermitUserEnvironment yes是必需的 → 错。该选项用于读取~/.ssh/environment文件,与SendEnv/AcceptEnv无关,且已废弃多年,不推荐启用; - 把
SettableEnvironmentVars(Tectia SSH)和 OpenSSH 混用 → OpenSSH 不识别该指令; - 忘记变量名大小写(如
lang≠LANG); - 在
AcceptEnv中写PATH却未在客户端SendEnv中声明 → 不会自动传递。
不复杂但容易忽略细节。


















