Условная прокси-команда в ~ / .ssh / config?


14

У меня ~/.ssh/configнастроены различные хосты, которые доступны либо через VPN нашей компании, либо через прокси-сервер SSH.

На данный момент у меня просто есть

Host internal-server
    ProxyCommand ssh -W internal.ip:22 external-server

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

Есть ли способ, которым я могу временно прокси-сервер, если внутренний ip не доступен, и подключиться напрямую в противном случае?

Ответы:


8

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

Host *%homeproxy
    ProxyCommand ssh user@proxyhost /bin/netcat -w 1 $(echo %h | cut -d%% -f1) 22

Так что я бы подключился к лайку ssh blah%homeproxy.


Мой гугл-фу подводит меня. Можете ли вы объяснить это больше? Я никогда не видел этот синтаксис *% раньше.
fukawi2

3
В этом %персонаже нет ничего особенного. Вы могли бы использовать что-нибудь на самом деле. Процент используется, поскольку он недопустим в имени хоста или имени пользователя. Команда cutс ProxyCommand использует в %качестве разделителя для извлечения имени хоста.
Зоредаче

1
Это хорошо, однако это означает, что я должен указать полное имя хоста, а не псевдоним ssh.
альт

@mobiusnz На самом деле это просто означает, что вам нужно другое имя для каждого способа подключения. В моем случае, например, если я дома, я использую ssh targetH, что означает цель из дома . Если в локальной сети нацелиться, просто ssh target. Было бы хорошо, если бы в ответе это было прямо сказано.
Рубенс

4

Я использую другой метод, используя Match. В моем случае я хочу использовать локальный прокси, если он запущен, или нет, если это не так. Следующая директива прекрасно справляется с этой задачей:

Match Exec "nc -z 127.0.0.1 1086"
    ProxyCommand nc -X 5 -x 127.0.0.1:1086 %h %p

Он совпадает с каждой попыткой ssh ​​и выполняет быструю проверку, используя, ncчтобы проверить, работает ли мой прокси на 1086 (в этом случае ncзавершается без ошибок). Если это произойдет, он устанавливает ProxyCommand.


2

Десять лет назад я написал прокси-команду для такого сценария. В вашем случае моя прокси-команда может быть использована следующим образом:

Host internal-server
    ProxyCommand ssh-multipath-proxy %h:%p -- ssh -W %h:%p external-server

Несколько предостережений: мне немного стыдно признать, что он не обрабатывает IPv6, и что он будет использовать только один IP-адрес для каждого имени хоста. Кроме того, он не будет передавать баннер клиента на сервер, пока баннер сервера не был отправлен. Но это вряд ли вызовет проблемы.


2

Спасибо за ответ @ till , это меня очень вдохновило.

Я обнаружил, что вы можете принудительно перенаправить ваше соединение с ProxyCommand nc dst dst-port.

Например, B.comесли вы используете

ssh A.com -o ProxyCommand="nc B.com 22"

Но UserKnownHostsFileвсе равно будет записывать какA.com

Таким образом, вы можете добавить домен «авто» к вашему ssh_config

Host auto.internal-server
  Hostname {internal-server ip or domain}
  ProxyCommand bash -c '(timeout 0.1 nc -z %h %p) && nc %h %p || ssh -W %h:%p external-server'

Я заменил nc -w 1 %h %pна (timeout 0.1 nc -z %h %p) && nc %h %p, это будет быстрее, если вы сможете достичь внутреннего сервера менее чем за 100 мс.

Или вы можете заменить на ping, но это может указывать на неверную информацию, если вы используете прокси на основе TCP, например proxychains, или сервер не допускает эхо ICMP.

Host auto.internal-server
  Hostname {internal-server ip or domain}
  ProxyCommand bash -c '(ping %h &>/dev/null) && nc %h %p || ssh -W %h:%p external-server'

Вы можете заменить (timeout 0.1 nc -z %h %p)на что-либо, что определяет, находитесь ли вы на внутреннем сервере.

Если у вас есть несколько IP-адресов кандидатов, даже вы можете использовать это:

Host auto.internal-server
  Hostname {internal-server ip or domain}
  ProxyCommand bash -c 'f(){(timeout 0.1 ping -c 1 $1 &>/dev/null) && nc $1 %p;}; f 1.1.1.1 || f 2.2.2.2 || f 3.3.3.3'

Он попытается подключиться 1.1.1.1, если не удается подключиться 2.2.2.2, а затем 3.3.3.3.


0

Это работает немного более автоматически с небольшой дополнительной задержкой в ​​1 с, если вы не находитесь за брандмауэром и брандмауэр не отклоняет:

Host proxyhost.example.com
ProxyCommand none

Host *.example.com
ProxyCommand sh -c "nc -w 1 %h %p || ssh -W  %h:%p proxyhost.example.com"

0

Я бы обычно создавал еще одну запись примерно так -

Host myVM
    ProxyCommand ssh -W internal.ip:22 external-server
    User ubuntu

Host myVM-np
    User ubuntu

Затем просто вызовите тот, который вы хотите, в зависимости от вашей текущей среды прокси ..

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.