Умовний ProxyCommand в ~ / .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.


Мій google-fu не вдається. Чи можете ви пояснити це більше? Я ніколи раніше не бачив цього синтаксису *%.
fukawi2

3
У %персонажі немає нічого особливого . Ви могли реально користуватися чим завгодно. Відсотки використовуються, оскільки вони не дійсні в імені хоста чи імені користувача. cutКоманда джгутів в ProxyCommand використовує в %якості роздільника , щоб витягнути ім'я хоста.
Зоредаче

1
Це добре, однак це означає, що мені потрібно прописати повне ім'я хоста, а не псевдонім ssh.
alt

@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

Це працює трохи більш автоматично з невеликою додатковою затримкою 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"

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.