Динамически генерировать записи SSH Host в ~ / .ssh / config

9

Я должен управлять целой кучей хостов через SSH. Однако я могу получить к ним доступ только через определенный шлюз ssh-сервера.

У меня есть следующее в моем ~/.ssh/config:

Host mygateway-www
Hostname www
IdentityFile ~/.ssh/id_rsa
ProxyCommand ssh mygateway nc %h 22

Однако я должен подключиться ко многим из этих машин. Вместо того, чтобы помещать десятки записей в мою ~/.ssh/config, есть ли у меня что-то вроде этого:

Host mygateway-*
Hostname ???WHAT GOES HERE????
IdentityFile ~/.ssh/id_rsa
ProxyCommand ssh mygateway nc %h 22

Я знаю, что вы можете использовать %hв Hostnameаргументе, но это будет имя хоста. Что мне действительно нужно, так это какая-то подстановка строк, например, bash ${VAR%thingie}. Это возможно?

Рори
источник

Ответы:

24

Это можно сделать с помощью следующего файла конфигурации SSH:

Host *
  ServerAliveInterval 120

Host gateway.somewhere.com
  User jdoe

Host gateway+*
  User jdoe
  ProxyCommand ssh -T -a $(echo %h |cut -d+ -f1).somewhere.com nc $(echo %h |cut -d+ -f2) %p 2>/dev/null
  ControlMaster auto
  ControlPath ~/.ssh/ssh-control_%r@%h:%p

Затем вы получаете доступ к своим внутренним хостам следующим образом:

ssh gateway+internalhost01.somewhere.com
ssh gateway+internalhost02.somewhere.com

Имя, которое вы выбираете для правой половины, должно быть разрешено хостом перехода.

Параметр User указывается в том случае, если вам необходимо вручную сопоставить разных пользователей на разных классах хостов. ControlMaster и ControlPath указываются для повторного использования SSH-соединения.

copperlight
источник
6

Вам не нужно указывать имя хоста вручную, так как оно будет получено из командной строки.

Просто попробуйте:

Host *.domain  
  IdentityFile ~/.ssh/id_rsa  
  ProxyCommand ssh mygateway /usr/bin/nc %h 22
Дэн Карли
источник
Проблема с этим подходом заключается в том, что имя хоста является довольно общим (например, db1, www, mail2), тогда как я хочу, чтобы они также имели префикс с проектом, поскольку мне может понадобиться ssh на другую машину с именем 'db2'. Отсюда и префикс в Host
Rory
2
Таким образом, вы действительно хотите перенастроить свой DNS. Самое простое (но самое громоздкое решение) - изменить файл hosts. С другой стороны, вы всегда можете добавить локальный DNS-сервер на свою рабочую станцию ​​с доменом .invalid и использовать предпочитаемые имена хостов.
Мартин М.
+1 предыдущий. Создайте поддомен для каждого проекта. DNS есть, чтобы сделать вашу жизнь проще;)
Дэн Карли
1

Похоже, нет никакого способа сделать это.

Рори
источник
1

У меня была похожая проблема, и в итоге я написал сценарий, который сгенерировал весь шаблон для меня. Я больше не изменяю ~ / ssh / config, я изменяю ~ / ssh / config.in и перезапускаю свой скрипт.

Майкл Хоффман
источник
1
Хотите поделиться своим сценарием? Я думал о том, чтобы сделать это, но кажется, что надежное и общее решение может потребовать много работы, чтобы получить право. Даже если ваше решение еще не так, было бы полезно узнать, что, по вашему мнению, оно делает правильно, и что бы вы сделали по-другому, если бы вам пришлось это делать заново.
иконоборчество
Я думал иметь .ssh/config.dфайл для каждого шаблона, где каждый шаблон будет генерировать одну или несколько записей в финале ~/.ssh/config. Там также будет файл с универсальными переменными, но каждый шаблон может иметь свои собственные переменные, которые будут иметь приоритет над глобальными, перечисленными в верхней части. ~/.ssh/configФайл может быть создан по требованию или по расписанию, она не имеет значения, до тех пор , как вы никогда не делали прямые изменения в нем , что вы хотели сохранить.
иконоборчество
Мой сценарий полностью недокументирован, и я не думаю, что он был бы понятен без документации или примеров, которые у меня нет времени создавать.
Майкл Хоффман
Понятный. Буду признателен за любые отзывы о подходе, который я изложил, особенно, если я упускаю из виду некоторые важные потребности или варианты использования, или какие-то большие (или маленькие) препятствия.
иконоборчество
1
Я думаю, что это хороший подход, возможно, немного менее запутанный, чем подход, который я использовал. Я прочитал несколько объявлений хоста в память, затем несколько объявлений не хоста. Объявления не хостов применяются к каждому хосту в текущей группе, пока не появится другой хост. Я также разрешаю многократно объявлять хосты в файле, в том числе с использованием глобинга. В конце я записываю все, что я строил в памяти.
Майкл Хоффман
1

Игнорируйте указание переопределения имени хоста напрямую через Hostnameобъявление и вместо этого определяйте его во время выполнения. Сделайте это, оценив его как часть ProxyCommand, используя %hдля ссылки на него в команде (также используйте %pвместо порта жесткого кодирования как 22), т.е.

Host mygateway-*
   #Hostname ???WHAT GOES HERE????
   IdentityFile ~/.ssh/id_rsa
   ProxyCommand ssh mygateway nc $(echo %h|sed 's/^mygateway-//') %p

Можно даже иметь более общий раздел, в соответствии с которым вы можете указать любой хост без a, -который будет обрабатываться как есть, или как в другом подходящем разделе (строках), но есть общий -подход для указания любого <gateway>-<target>:

Host *-*
   # Assume LHS of "-" is GW and RHS of "-" is target host
   IdentityFile ~/.ssh/id_rsa
   ProxyCommand ssh $(echo %h|cut -d - -f1) nc $(echo %h|cut -d - -f2-) %p

Кроме того, более новые версии клиента SSH поддерживают [-W host:port]возможность напрямую выполнять ту же функцию, что и nc(netcat). Таким образом, мы можем использовать модифицированные:

Host *-*
   # Assume LHS of "-" is GW and RHS of "-" is target host
   IdentityFile ~/.ssh/id_rsa
   ProxyCommand ssh -W $(echo %h|cut -d - -f2-):%p $(echo %h|cut -d - -f1)

Конечно, если у вас есть ограниченный список хостов, вы всегда можете сделать:

Host host1 host2 host3 hostN
   IdentityFile ~/.ssh/id_rsa
   ProxyCommand ssh mygateway nc %h %p

Надеюсь это поможет!

Таз
источник
0

У меня был клиент с такой же настройкой, и я использовал DSSH для решения своей проблемы.
DSSH среди прочего позволяет вам прозрачно входить в систему удаленных хостов через хост шлюза.

Случаи использования

  • Соберите параметры конфигурации от маршрутизаторов Cisco, которые требуют входа "ena"
  • Войдите на серверы, на которых PermitRootLogin отключен напрямую от имени пользователя root (введя su- и пароль автоматически), сохранив статус выхода.
  • Добавьте пользовательскую логику, такую ​​как расширенная регистрация
  • туннель через несколько соединений, чтобы добраться до целевого сервера
aussielunix
источник
5
Я бы не стал использовать какой-нибудь случайный сторонний ssh-клиент, который использует java, для вещей, которые я могу сделать в ~ / .ssh / config.
Рори
ссылка мертва
иконоборца
Источник программного обеспечения можно найти на Github: github.com/digmia/dssh
Гость