Вопрос или проблема
Я хочу передать некоторые переменные окружения по ssh. Я изменил файл sshd_config на сервере, добавив файл в /etc/ssh/sshd_config.d, содержащий:
# Важно: это НЕ конфликтует с PermitUserEnvironment=No
AcceptEnv NOTIF* LANG LC_*
И перезапустил sshd. Запустив ssh -o SendEnv=NOTIF* localhost printenv
, переменные не были установлены на удаленной стороне.
В /etc/ssh/sshd_config уже была запись, содержащая AcceptEnv LANG LC_*
. Закомментирование этой строки и перезапуск не повлияли на поведение.
$ export NOTIFY_WHAT="SERVICE"
$ export NOTIFY_SHORTDATETIME="CRIT"
$ export NOTIFY_HOSTNAME="web.example.com"
$ export NOTIFY_HOSTOUTPUT="host is up"
$ export NOTIFY_HOSTSTATE="OK"
$ export NOTIFY_NOTIFICATIONTYPE="PROBLEM"
$ export NOTIFY_SERVICEDESC="cmk-test"
$ export NOTIFY_SERVICEOUTPUT="oh no its broken!"
$ export NOTIFY_SERVICESTATE="CRIT"
$ ssh -o SendEnv=NOTIF* localhost printenv
SHELL=/bin/bash
LANGUAGE=en_US.UTF-8
SSH_AUTH_SOCK=/tmp/ssh-XXXXIxNz4o/agent.8579
PWD=/home/symcbean
LOGNAME=symcbean
MOTD_SHOWN=pam
HOME=/home/symcbean
LANG=C.UTF-8
SSH_CONNECTION=127.0.0.1 35340 127.0.0.1 22
USER=symcbean
SHLVL=0
SSH_CLIENT=127.0.0.1 35340 22
LC_ALL=C
PATH=/usr/local/bin:/usr/bin:/bin:/usr/games
_=/usr/bin/printenv
Таким образом, это не работает, но, что странно, модифицированное значение LANG отправляется:
$ export LANG=en_GB.UTF-8
$ ssh -o SendEnv=NOTIF* localhost printenv
SHELL=/bin/bash
LANGUAGE=en_US.UTF-8
SSH_AUTH_SOCK=/tmp/ssh-XXXXIxNz4o/agent.8579
PWD=/home/symcbean
LOGNAME=symcbean
MOTD_SHOWN=pam
HOME=/home/symcbean
LANG=en_GB.UTF-8
SSH_CONNECTION=127.0.0.1 35340 127.0.0.1 22
USER=symcbean
SHLVL=0
SSH_CLIENT=127.0.0.1 35340 22
LC_ALL=C
PATH=/usr/local/bin:/usr/bin:/bin:/usr/games
_=/usr/bin/printenv
(хотя я подключаюсь через localhost, клиент и сервер работают в отдельных контейнерах WSL. Клиент — 1:8.9p1-3ubuntu0.7, Сервер — openssh-server 1:9.2p1-2+deb12u3).
Чтобы не было двусмысленности:
$ ssh -o SendEnv=NOTIF* localhost 'find /etc/ssh -type f -exec grep -H AcceptEnv {} \;'
grep: /etc/ssh/ssh_host_ed25519_key: Доступ запрещен
grep: /etc/ssh/ssh_host_rsa_key: Доступ запрещен
grep: /etc/ssh/ssh_host_ecdsa_key: Доступ запрещен
/etc/ssh/sshd_config.d/allowcheckmk:AcceptEnv NOTIF* LANG LC_*
/etc/ssh/sshd_config:# AcceptEnv LANG LC_*
ОБНОВЛЕНИЕ
С помощью -vv
я вижу, что клиент, похоже, отправляет данные — они не принимаются / отбрасываются на удаленной стороне…
debug1: Sending environment.
debug1: channel 2: setting env NOTIFY_SERVICESTATE = "CRIT"
debug2: channel 2: request env confirm 0
debug1: channel 2: setting env NOTIFY_HOSTSTATE = "OK"
debug2: channel 2: request env confirm 0
debug1: channel 2: setting env NOTIFY_WHAT = "SERVICE"
debug2: channel 2: request env confirm 0
...
Чтобы передать переменные окружения от клиента к серверу, вам нужно:
- использовать
SendEnv
на стороне клиента - использовать
AcceptEnv
на стороне сервера
(Как вы отметили, есть связанная, но отдельная директива PermitUserEnvironment
: это добавляет в окружение из других источников.)
Подводные камни включают:
- конфигурация
sshd_config
не считывается (полностью) или не перезагружается после изменений AcceptEnv
(илиInclude
) неожиданно появляется после директивыMatch
Вы можете проверить, что сервер установлен правильно, используя режим тестирования конфигурации:
# sshd -T | grep -i acceptenv
acceptenv NOTIF*
(конфигурация анализируется без учета регистра)
Если вы добавите -dd
для установки уровня отладки 2, вы также увидите детали, связанные с Include
:
debug2: /etc/ssh/sshd_config line 124: new include /etc/ssh/sshd_config.d/*.conf
debug2: /etc/ssh/sshd_config line 124: including /etc/ssh/sshd_config.d/000_local.conf
И в вашем случае, возможно:
debug2: /etc/ssh/sshd_config line 124: no match for /etc/ssh/sshd_config.d/*.conf
Режим тестирования -T
считывает текущие конфигурационные файлы, убедитесь, что вы перезагрузили службу, если в конфигурации были изменения.
(Если вы действительно используете директивы Match
для этого, вы можете протестировать условия, используя -C ...
вместе с -T
— смотрите мануал sshd для получения подробностей.)
Вы можете увидеть весь процесс, запустив однократный процесс sshd
с уровнем отладки 2:
/sbin/sshd -dd -oPort=2222
# из другого терминала:
ssh -oPort=2222 "-oSendEnv=NOTIF*" localhost
(этот процесс отладки сервера завершится, когда клиент отключится)
В выводе сервера после подключения вы увидите “debug2: Setting env 0: ...
“, а в выводе клиента после успешной авторизации будут показаны изменения окружения, которые были внесены.
Существует предельный лимит на количество разрешенных переменных (на момент openssh-9.7p1 это жестко закодировано как 128).
Насколько я знаю, только переменная TERM
является особым случаем, так как её необходимо отправлять по протоколу. Чтобы объяснить изменения LANG
, возможно, pam_env
и системные сценарии rc приведут вас к этому.
Ответ или решение
Для успешной передачи переменных окружения через SSH вам необходимо убедиться, что на стороне клиента используется директива SendEnv
, а на стороне сервера — AcceptEnv
. Хотя вы уже внесли изменения в конфигурационный файл sshd_config
на сервере и добавили запись в /etc/ssh/sshd_config.d
, переменные блока NOTIF*
не принимаются, что может быть вызвано несколькими причинами.
Проверьте конфигурацию сервера
-
Перезагрузка демона SSH: Убедитесь, что после внесения изменений вы перезагрузили службу SSH. Например:
sudo systemctl restart sshd
-
Проверка параметров конфигурации: Используйте команду для проверки конфигурации SSH на сервере:
sudo sshd -T | grep -i acceptenv
Это поможет убедиться, что ваша конфигурация считывается корректно и переменные действительно разрешены для передачи.
-
Проверка наличия секций Match: Убедитесь, что ваши настройки
AcceptEnv
не находятся внутри секцииMatch
, так как это может привести к их игнорированию. Командыsshd -T
предоставят информацию о том, какие конфигурационные файлы включены.
Проверка с детализированным выводом
- Запустите
sshd
с отладкой: Вы можете запустить сервер SSH в режиме отладки, чтобы увидеть, как он обрабатывает ваши подключения:/sbin/sshd -dd -oPort=2222
Затем, из другого терминала, выполните команду подключения:
ssh -oPort=2222 -oSendEnv=NOTIF* localhost
В выводе сервера вы должны увидеть строки, которые подтверждают установку переменных окружения.
Проверка клиента
-
Проверьте на клиенте: Убедитесь, что клиент правильно настроен на отправку переменных. Убедитесь, что переменные действительно экспортированы перед выполнением команды SSH:
export NOTIFY_WHAT="SERVICE" export NOTIFY_SHORTDATETIME="CRIT" # ... остальные переменные
-
Используйте подробный вывод: При выполнении команды SSH с флагом
-vv
, посмотрите на вывод, чтобы подтвердить, что переменные окружения отправляются:ssh -vv -o SendEnv=NOTIF* localhost printenv
Ограничения
Обратите внимание на ограничения, установленные для количества передаваемых переменных. Как минимум, их не должно быть больше 128.
Итог
Если после выполнения всех проверок проблема остается, возможно, стоит пересмотреть настройки вашего окружения или конфигурации. Иногда эффекты переменных окружения могут быть вызваны сторонними факторами, например, конфигурациями PAM или скриптами окружения, загружаемыми во время входа в систему.
Если вы продолжаете испытывать проблемы, стоит также проверить журналы сервера SSH на наличие возможных сообщений об ошибках или предупреждений, которые могут помочь определить источник проблемы.