Як ssh'ing, як я можу встановити змінну середовища на сервері, яка змінюється з сеансу на сеанс?


92

Як я sshпереходжу на сервер, як я можу передати змінну середовища від клієнта до сервера? Ця змінна середовище змінюється між різними викликами ssh, тому я не хочу перезаписувати $HOME/.ssh2/environmentкожного разу, коли я роблю ssh-виклик. Як я можу це зробити?


2
Ви ставите запитання, чи має бути більш чітка специфіка.
Ігнасіо Васкес-Абрамс

3
Питання для мене було досить чітким. Однак на sshсторінці man, я не бачу іншого способу зробити це, крім встановлення змінної вручну після входу в систему на сервері, якщо ви не змінили ~ / .ssh2 / environment.
garyjohn

Це щоразу інша змінна? Або інше значення?
Денніс Вільямсон


1
Інакше, оскільки це вже більш популярне. Неважливо, що вона старша.
kenorb

Відповіді:


110

Звичайно, ви можете встановити змінну середовища всередині команди, проте вам доведеться бути обережними при цитуванні: пам’ятайте, що ваша оболонка буде аналізувати ваш локальний командний рядок, і тоді віддалена оболонка матиме перехід на рядок отримує.

Якщо ви хочете, щоб змінна отримала таке саме значення на сервері, яке є у клієнта, спробуйте вибрати SendEnvваріант:

ssh -o SendEnv = MYVAR server.example.com mycommand

Для цього потрібна підтримка сервера. У OpenSSH ім'я змінної має бути дозволено в /etc/sshd_config.

Якщо сервер дозволяє лише певні імена змінних, ви можете обійти це; наприклад , загальна настройка дозволяє LC_*через, і ви можете зробити наступне:

ssh -o SendEnv = LC_MYVAR server.example.com 'MYVAR = $ LC_MYVAR; зняти LC_MYVAR; експорт MYVAR; моя команда '

Якщо навіть LC_*це не варіант, ви можете передавати інформацію у TERMзмінну оточення, яка завжди копіюється (проте може бути обмеження довжини). Вам все одно доведеться переконатися, що віддалена оболонка не обмежує TERMзмінну для позначення відомого типу терміналу. Передайте -tопцію для ssh, якщо ви не запускаєте віддалений інтерактивний оболонку.

env TERM = "додаткова інформація: $ TERM" ssh -t server.example.com 'MYVAR = $ {TERM%: *}; TERM = $ {TERM ## *:}; експорт MYVAR; моя команда '

Інша можливість полягає у визначенні змінної безпосередньо в команді:

ssh -t server.example.com 'export MYVAR = "додаткова інформація"; моя команда '

Таким чином, якщо передається локальна змінна:

ssh -t server.example.com 'export MYVAR =' "'$ LOCALVAR'" '; моя команда '

Однак остерігайтеся цитування питань: значення змінної буде інтерпольовано безпосередньо в фрагмент оболонки, виконаний на віддаленій стороні. Останній приклад вище припускає, що $LOCALVARне містить жодних цитат ( ').


2
Велике спасибі, я був у люті, що дурні змінні LC_ * експортуються на ssh, і ваша відповідь спрямовувала мене куди шукати. Мені просто потрібно відключити це в ~ / .ssh / config
akostadinov

1
Я знаходжусь у положенні оригінального плаката, але змінна, яку я хотіла переслати, - TERM, тому я трохи спантеличена вашою відповіддю. Чи було відключено це автоматичне переадресація TERM за останніми версіями OpenSSH?
Суббота

1
@Doub За замовчуванням відмовляється від усіх змінних середовища на стороні сервера, з AcceptEnvдирективами, sshd_configяк бажає адміністратор. Але TERMобробляється спеціально, наскільки я знаю, немає можливості фільтрувати його на стороні сервера (він встановлюється в середовищі оболонки незалежно від налаштувань конфігурації). Ви впевнені , що не існує профіль сценарію перекриваючи його (наприклад , /etc/profileчи ~/.profileабо ~/.bashrc)?
Жиль

2
@Gilles: Я перевірив її ще раз, і якщо я прямо не додам TERM до своєї директиви AcceptEnv, термін не передається. Я не відкриваю оболонку, але виконую команду безпосередньо, наприклад: "ssh -o SendEnv = TERM shell.example.com env". Це друкує всю змінну середовища, і TERM з'являється лише в тому випадку, якщо він знаходиться в SendEnv на клієнті та AcceptEnv на сервері. Якщо я запускаю "ssh -o SendEnv = TERM shell.example.com echo \ $ {TERM}" без тегів AcceptEnv або SendEnv, він друкує "німий", що я не впевнений, звідки він походить (env навіть не перерахуйте термін у цьому випадку).
Сум,

7
@Doub О, я бачу. TERMпередається лише в тому випадку, якщо клієнт вимагає від сервера виділити tty. Якщо на віддаленій стороні немає терміналу, передавати його буде марно TERM. Коли ви вказуєте команду, якщо ви хочете мати термінал на віддаленій стороні, вам потрібна -tопція (або RequestTTYвхід ~/.ssh/config) командного рядка .
Жиль

12

Якщо ви можете адмініструвати цільовий хост, ви можете налаштувати sshd, щоб дозволити передачу змінних вашого локального середовища разом із цільовим хостом.

На сторінці людини sshd_config:

 PermitUserEnvironment
     Specifies whether ~/.ssh/environment and environment= options in
     ~/.ssh/authorized_keys are processed by sshd.  The default is
     "no".  Enabling environment processing may enable users to bypass
     access restrictions in some configurations using mechanisms such
     as LD_PRELOAD.

Конфігурація sshd зазвичай живе в /etc/ssh/sshd_config


7
Дуже корисно знати, що за замовчуванням це встановлено на "ні"!
ятанізм

6

Отже, у вашого клієнта у вас є певна змінна середовище, і ви хочете, щоб вона була доступна віддаленій команді? Я не думаю, що є спосіб, щоб ssh магічно передати це, але, ймовірно, ти можеш зробити щось подібне. Замість використання скажіть:

ssh remote.host my_command

Ви можете зробити це:

ssh remote.host env ENV_VAR=$ENV_VAR my_command

"мабуть"? Я хотів би прочитати це, перш ніж насправді спробувати цю відповідь. Не працювало для мене.
tishma

1
Хочете детальніше розглянути будь-які отримані помилки тощо?
піото

1
@pioto Можливо, цитую, наприклад, якщо в ENV_VAR є пробіли
Martin C. Martin

На Mac ви повинні мати опцію -t для інтерактивної версії, інакше вона виглядає застряглою. Отже, це може спрацювати: $ ssh -t remote.host env ENV_VAR = $ ENV_VAR my_command
muenalan

3

@ відповідь порожнього набору (яка не працювала для мене) призвела до цієї відповіді:

Ви можете додати цю команду до свого ~/.ssh/authorized_keysфайлу:

command="/usr/bin/env VARIABLE=<something> $SHELL" ssh-rsa <key>

export VARIABLE=<something>негайно виходив, і з'єднання SSH було закрите (вимкнення мене із сервера), тоді як /usr/bin/env ... $SHELLбуде запущена ваша оболонка за замовчуванням із зміненим середовищем.


Це просто зависає при вході в мене. Коли я його виймаю, SSH повертається до нормального стану, і я отримую свою звичайну оболонку входу.
Нік Солодкий

@NickSweeting Ви спробували, можливо, замінити $SHELLфактичну оболонку? Також переконайтесь, що / usr / bin / env існує на сервері. Однак рішення не є ідеальним: я помітив, що він звисає, коли я хотів використовувати scpабо вбудовану команду.
madprog

Так, це було перше, що я спробував. На жаль, він ніколи не змусив його працювати, а згодом увімкнув PermitUserEnvironment yesта використовував environment="..."замість цього command="...".
Nick Sweeting

Це добре працює для мене.
Містер Тао

2

На вашому локальному клієнті, у своєму, ~/.ssh/configви можете додати SetEnv, наприклад

Host myhost
  SetEnv FOO=bar

Примітка: Перевірте man ssh_config.

Потім на сервері переконайтеся, що дозволите клієнту передавати певні змінні середовища у ваш /etc/ssh/sshd_configконфігураційний файл:

AcceptEnv LANG LC_* FOO BAR*

Примітка: Перевірте man sshd_config.


1

Ви можете спробувати викликати користувальницьку команду, якщо припустимо, що у вас не встановлено пароль для входу в ssh. На сервері відредагуйте ваш запис ~ / .ssh / санкціонований_кейс, який відповідає ключу від вашого клієнта:

command="export VARIABLE=<something>" ssh-rsa <key>

Подивіться на це посилання в розділі Примусові команди для більш детальної інформації.


1
Я спробував це, але це не працює. Він виконує команду та виходить, тому інтерактивного сеансу немає. Це нормальна поведінка? Якщо це так, це може бути корисно, якщо все, що ви хочете зробити, це дозволити певному ключу запустити певну команду, але якщо ви хочете передати інформацію, яка використовується в сеансі (як зазначено в питанні), то для цієї мети це марно. . Немає сеансу.
іконоборство

1

Я робив власну збірку OpenSSH для пристрою із судомами в домашньому каталозі та / і т. Д. (Cram FS доступний лише для читання), тому ~ / .ssh / середовище не працюватиме не без відновлення всього FS, і це було розгорнуте поле пристрої (вбудовані системи. Отже, використання CRAMFS). Ви можете вказати у sshd_config розташування файлу authroized_keys, але чомусь оточення = працює лише для змінних середовищ у ~ / .ssh / authroized_keys. Редагувати / etc / profile не було варіантом, і мені довелося завантажувати ssh у нестандартний каталог. У session.c після child_set_env (... "MAIL" ...) просто додайте потрібні вам змінні середовища (це я знаю хак, я знаю ...), але просто потрібно, щоб хтось потребував жорстких кодувань для сеансу, якщо ви компілюючи з джерела, ви можете це зробити. TGI-ФЛОСИ


0

лише одна проста команда:

ssh -t your_host_or_ip 'export some_var_name=whatever_you_want; bash'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.