Назад | Перейти на главную страницу

Условная ProxyCommand в ~ / .ssh / config?

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

На данный момент у меня только есть

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

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

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

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

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

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

Я использую другой метод, используя 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.

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

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

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

Спасибо Ответ @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 "socat 2>/dev/null - tcp4:%h:%p,connect-timeout=0.1 || exec ssh -W  %h:%p proxyhost.example.com"

Обычно я бы создавал другую запись примерно так -

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

Host myVM-np
    User ubuntu

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

С Match и Exec вы можете проверить, доступен ли порт SSH, и использовать ProxyCommand, если нет. Смотрите мой пример здесь: https://stackoverflow.com/questions/40746463/how-to-automatically-switch-ssh-config-based-on-local-subnet/62924483#62924483