Содержание

Практические советы, примеры и туннели SSH / Хабр


Практические примеры SSH, которые выведут на новый уровень ваши навыки удалённого системного администратора. Команды и советы помогут не только использовать SSH, но и более грамотно перемещаться по сети.

Знание нескольких трюков ssh полезно любому системному администратору, сетевому инженеру или специалисту по безопасности.

Практические примеры SSH


  1. SSH socks-прокси
  2. Туннель SSH (переадресация портов)
  3. SSH-туннель на третий хост
  4. Обратный SSH-туннель
  5. Обратный прокси SSH
  6. Установка VPN по SSH
  7. Копирование ключа SSH (ssh-copy-id)
  8. Удалённое выполнение команд (неинтерактивно)
  9. Удалённый перехват пакетов и просмотр в Wireshark
  10. Копирование локальной папки на удалённый сервер по SSH
  11. Удалённые приложения GUI с переадресацией SSH X11
  12. Удалённое копирование файлов с помощью rsync и SSH
  13. SSH через сеть Tor
  14. SSH к инстансу EC2
  15. Редактирование текстовых файлов с помощью VIM через ssh/scp
  16. Монтирование удалённого SSH как локальной папки с SSHFS
  17. Мультиплексирование SSH с помощью ControlPath
  18. Потоковое видео по SSH с помощью VLC и SFTP
  19. Двухфакторная аутентификация
  20. Прыжки по хостам с SSH и -J
  21. Блокировка попыток брутфорса SSH с помощью iptables
  22. SSH Escape для изменения переадресации портов


Разбор командной строки SSH

В следующем примере используются обычные параметры, часто встречающиеся при подключении к удалённому серверу SSH.
localhost:~$ ssh -v -p 22 -C neo@remoteserver

  • -v: вывод отладочной информации особенно полезен при анализе проблем аутентификации. Можно использовать несколько раз для вывода дополнительной информации.
  • - p 22: порт для подключения к удалённому серверу SSH. 22 не обязательно указывать, потому что это значение по умолчанию, но если протокол на каком-то другом порту, то указываем его с помощью параметра -p. Порт прослушивания указывается в файле sshd_config в формате Port 2222.
  • -C: сжатие для соединения. Если у вас медленный канал или вы просматриваете много текста, это может ускорить связь.
  • neo@: строка перед символом @ обозначает имя пользователя для аутентификации на удалённом сервере. Если не указать его, то по умолчанию будет использоваться имя пользователя учётной записи, в которую вы вошли в данный момент (~$ whoami). Пользователя также можно указать параметром -l.
  • remoteserver: имя хоста, к которому подключается ssh, это может быть полное доменное имя, IP-адрес или любой хост в локальном файле hosts. Для подключения к хосту, который поддерживает и IPv4, и IPv6, можно добавить в командную строку параметр -4 или -6 для правильного резолвинга.

Все вышеперечисленные параметры являются необязательными, кроме remoteserver.
Использование файла конфигурации

Хотя многие знакомы с файлом sshd_config, есть ещё файл конфигурации клиента для команды ssh. Значение по умолчанию ~/.ssh/config, но его можно определить как параметр для опции -F.
Host *
     Port 2222

Host remoteserver
     HostName remoteserver.thematrix.io
     User neo
     Port 2112
     IdentityFile /home/test/.ssh/remoteserver.private_key

В приведённом выше примерном файле конфигурации ssh две записи хоста. Первая обозначает все хосты, для всех применяется параметр конфигурации Port 2222. Вторая говорит, что для хоста
remoteserver
следует использовать другое имя пользователя, порт, FQDN и IdentityFile.

Файл конфигурации может сэкономить много времени на ввод символов, позволяя автоматически применять продвинутую конфигурацию при подключении к конкретным хостам.

Копирование файлов по SSH с помощью SCP

SSH-клиент поставляется с двумя другими очень удобными инструментами для копирования файлов по зашифрованному ssh-соединению. Ниже см. пример стандартного использования команд scp и sftp. Обратите внимание, что многие параметры для ssh применяются и в этих командах.
localhost:~$ scp mypic.png neo@remoteserver:/media/data/mypic_2.png

В этом примере файл mypic.png скопирован на remoteserver
в папку /media/data и переименован в mypic_2.png.

Не забывайте о разнице в параметре порта. На этом попадаются многие, кто запускает scp из командной строки. Здесь параметр порта -P, а не -p, как в ssh-клиенте! Вы забудете, но не волнуйтесь, все забывают.

Для тех, кто знаком с консольным ftp, многие из команд похожи в sftp. Вы можете сделать push, put и ls, как сердце пожелает.

sftp neo@remoteserver


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

1. SSH socks-прокси


Функция SSH Proxy под номером 1 по уважительной причине. Она более мощная, чем многие предполагают, и даёт вам доступ к любой системе, к которой имеет доступ удалённый сервер, используя практически любое приложение. Клиент ssh может туннелировать трафик через прокси-сервер SOCKS одной простой командой. Важно понимать, что трафик к удалённым системам будет исходить от удалённого сервера, так будет указано в логах веб-сервера.
localhost:~$ ssh -D 8888 user@remoteserver

localhost:~$ netstat -pan | grep 8888
tcp        0      0 127.0.0.1:8888       0.0.0.0:*               LISTEN      23880/ssh

Здесь мы запускаем socks-прокси на TCP-порту 8888, вторая команда проверяет, что порт активен в режиме прослушивания. 127.0.0.1 указывает, что служба работает только на localhost. Мы можем применить немного другую команду для прослушивания всех интерфейсов, включая ethernet или wifi, это позволит другим приложениям (браузерам и т д.) в нашей сети подключаться к прокси-сервису через ssh socks-прокси.
localhost:~$ ssh -D 0.0.0.0:8888 user@remoteserver

Теперь можем настроить браузер для подключения к socks-прокси. В Firefox выберите Настройки | Основные | Параметры сети. Укажите IP-адрес и порт для подключения.

Обратите внимание на опцию в нижней части формы, чтобы DNS-запросы браузера тоже шли через прокси SOCKS. Если используете прокси-сервер для шифрования веб-трафика в локальной сети, то наверняка захотите выбрать эту опцию, чтобы DNS-запросы туннелировались через SSH-соединение.

Активация socks-прокси в Chrome

Запуск Chrome с определёнными параметрами командной строки активирует socks-прокси, а также туннелирование DNS-запросов из браузера. Доверяй, но проверяй. Используйте tcpdump для проверки, что DNS-запросы больше не видны.
localhost:~$ google-chrome --proxy-server="socks5://192.168.1.10:8888"

Использование других приложений с прокси

Имейте в виду, что многие другие приложения тоже могут использовать socks-прокси. Веб-браузер просто самое популярное из них. У некоторых приложений есть параметры конфигурации для активации прокси-сервера. Другим нужно немного помочь вспомогательной программой. Например, proxychains позволяет запустить через socks-прокси Microsoft RDP и др.
localhost:~$ proxychains rdesktop $RemoteWindowsServer

Параметры конфигурации socks-прокси задаются в файле конфигурации proxychains.
Подсказка: если используете удалённый рабочий стол из Linux на Windows? Попробуйте клиент FreeRDP. Это более современная реализация, чем rdesktop, с гораздо более плавным взаимодействием.

Вариант использования SSH через socks-прокси

Вы сидите в кафе или гостинице — и вынуждены использовать довольно ненадёжный WiFi. С ноутбука локально запускаем ssh-прокси и устанавливаем ssh-туннель в домашнюю сеть на локальный Rasberry Pi. Используя браузер или другие приложения, настроенные для socks-прокси, мы можем получить доступ к любым сетевым службам в нашей домашней сети или выйти в интернет через домашнее подключение. Всё между вашим ноутбуком и домашним сервером (через Wi-Fi и интернет до дома) зашифровано в туннеле SSH.

2. Туннель SSH (переадресация портов)


В простейшей форме SSH-туннель просто открывает порт в вашей локальной системе, который подключается к другому порту на другом конце туннеля.
localhost:~$ ssh  -L 9999:127.0.0.1:80 user@remoteserver

Разберём параметр -L. Его можно представить как локальную сторону прослушивания. Таким образом, в примере выше порт 9999 прослушивается на стороне localhost и переадресуется через порт 80 на remoteserver. Обратите внимание, что 127.0.0.1 относится к localhost на удалённом сервере!

Поднимемся на ступеньку. В следующем примере порты прослушивания связываются с другими узлами локальной сети.

localhost:~$ ssh  -L 0.0.0.0:9999:127.0.0.1:80 user@remoteserver

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

3. SSH-туннель на сторонний хост


Мы можем использовать те же параметры для подключения туннеля с удалённого сервера к другой службе, запущенной на третьей системе.
localhost:~$ ssh  -L 0.0.0.0:9999:10.10.10.10:80 user@remoteserver

В данном примере мы перенаправляем туннель от remoteserver к веб-серверу, работающему на 10.10.10.10. Трафик с remoteserver к 10.10.10.10
уже не в SSH-туннеле
. Веб-сервер на 10.10.10.10 будет считать remoteserver источником веб-запросов.

4. Обратный SSH-туннель


Здесь настроим прослушивающий порт на удалённом сервере, который будет подключаться обратно к локальному порту на нашем localhost (или другой системе).
localhost:~$ ssh -v -R 0.0.0.0:1999:127.0.0.1:902 192.168.1.100 user@remoteserver

В этой SSH-сессии устанавливается соединение с порта 1999 на remoteserver к порту 902 на нашем локальном клиенте.

5. Обратный прокси SSH


В этом случае мы устанавливаем socks-прокси на нашем ssh-соединении, однако прокси слушает на удалённом конце сервера. Подключения к этому удалённому прокси теперь появляются из туннеля как трафик с нашего localhost.
localhost:~$ ssh -v -R 0.0.0.0:1999 192.168.1.100 user@remoteserver

Устранение проблем с удалёнными SSH-туннелями

Если у вас возникли проблемы с работой удалённых опций SSH, проверьте с помощью netstat, к каким ещё интерфейсам подключён порт прослушивания. Хотя мы в примерах указали 0.0.0.0, но если значение GatewayPorts в sshd_config установлено в значение no, то листенер будет привязан только к localhost (127.0.0.1).
Предупреждение безопасности

Обратите внимание, что при открытии туннелей и socks-прокси внутренние сетевые ресурсы могут быть доступны ненадёжным сетям (например, интернету!). Это может быть серьёзной угрозой безопасности, поэтому убедитесь, что вы понимаете, что представляет собой слушатель и к чему у него есть доступ.

6. Установка VPN по SSH


Общий термин среди спецов по методам атаки (пентестеры и проч.) — это «точка опоры в сети». После установления соединения в одной системе эта система становится шлюзом для дальнейшего доступа к сети. Точка опоры, которая позволяет двигаться вширь.

Для такой точки опоры мы можем использовать SSH-прокси и proxychains, однако есть некоторые ограничения. Например, не получится работать напрямую с сокетами, поэтому мы не сможем сканировать порты внутри сети через Nmap SYN.

Используя этот более продвинутый вариант VPN, подключение снижается до уровня 3. Затем мы можем просто направить трафик через туннель, используя стандартную сетевую маршрутизацию.

Метод использует ssh, iptables, tun interfaces и маршрутизацию.

Сначала нужно задать эти параметры в sshd_config. Поскольку мы вносим изменения в интерфейсы и удалённой, и клиентской системы, нам нужны права root с обеих сторон.

PermitRootLogin yes
PermitTunnel yes

Затем установим ssh-соединение, используя параметр, который запрашивает инициализацию tun-устройств.
localhost:~# ssh -v -w any root@remoteserver

Теперь у нас должно быть устройство tun при показе интерфейсов (# ip a). Следующий шаг добавит IP-адреса к туннельным интерфейсам.

Сторона клиента SSH:

localhost:~# ip addr add 10.10.10.2/32 peer 10.10.10.10 dev tun0
localhost:~# ip tun0 up

Сторона сервера SSH:
remoteserver:~# ip addr add 10.10.10.10/32 peer 10.10.10.2 dev tun0
remoteserver:~# ip tun0 up

Теперь у нас прямой маршрут к другому хосту (route -n и ping 10.10.10.10).

Можно маршрутизировать любую подсеть через хост на другой стороне.

localhost:~# route add -net 10.10.10.0 netmask 255.255.255.0 dev tun0

На удалённой стороне необходимо включить ip_forward и iptables.
remoteserver:~# echo 1 > /proc/sys/net/ipv4/ip_forward
remoteserver:~# iptables -t nat -A POSTROUTING -s 10.10.10.2 -o enp7s0 -j MASQUERADE

Бум! VPN через туннель SSH на сетевом уровне 3. Вот это уже победа.

Если возникают какие-то проблемы, используйте tcpdump и ping, чтобы установить причину. Поскольку мы играем на уровне 3, то наши пакеты icmp пойдут через этот туннель.

7. Копирование ключа SSH (ssh-copy-id)


Тут есть несколько способов, но эта команда экономит время, чтобы не копировать файлы вручную. Она просто копирует ~/.ssh/id_rsa.pub (или ключ по умолчанию) с вашей системы в ~/.ssh/authorized_keys на удалённом сервере.
localhost:~$ ssh-copy-id user@remoteserver

8. Удалённое выполнение команд (неинтерактивно)


Команду ssh можно связать с другими командам для обычного удобного интерфейса. Просто добавьте команду, которую хотите запустить на удалённом хосте, в качестве последнего параметра в кавычках.
localhost:~$ ssh remoteserver "cat /var/log/nginx/access.log" | grep badstuff.php

В данном примере grep выполняется на локальной системе после того, как лог скачался по ssh-каналу. Если файл большой, удобнее запустить grep на удалённой стороне, просто заключив обе команды в двойные кавычки.

Другой пример выполняет ту же самую функцию, что и ssh-copy-id из примера 7.

localhost:~$ cat ~/.ssh/id_rsa.pub | ssh remoteserver 'cat >> .ssh/authorized_keys'

9. Удалённый перехват пакетов и просмотр в Wireshark


Я взял один из наших примеров по tcpdump. Используйте его для удалённого перехвата пакетов с выдачей результата непосредственно в GUI локального Wireshark.
:~$ ssh root@remoteserver 'tcpdump -c 1000 -nn -w - not port 22' | wireshark -k -i -

10. Копирование локальной папки на удалённый сервер по SSH


Красивый трюк, который сжимает папку с помощью bzip2 (это параметр -j в команде tar), а затем извлекает поток bzip2 на другой стороне, создавая на удалённом сервере дубликат папки.
localhost:~$ tar -cvj /datafolder | ssh remoteserver "tar -xj -C /datafolder"

11. Удалённые приложения GUI с переадресацией SSH X11


Если на клиенте и удалённом сервере установлены «иксы», то можно удалённо выполнить команду GUI, с окном на вашем локальном рабочем столе. Эта функция существует давным давно, но по-прежнему очень полезна. Запустите удалённый веб-браузер или даже консоль VMWawre Workstation, как я делаю в этом примере.
localhost:~$ ssh -X remoteserver vmware

Требуется строка X11Forwarding yes в файле sshd_config.

12. Удалённое копирование файлов с помощью rsync и SSH


rsync во многом удобнее scp, если требуется периодическое резервное копирование каталога, большого количества файлов или очень больших файлов. Здесь есть функция восстановления после сбоя передачи и копирования только изменённых файлов, что сохраняет трафик и время.

В этом примере используется сжатие gzip (-z) и режим архивирования (-a), который включает рекурсивное копирование.

:~$ rsync -az /home/testuser/data remoteserver:backup/

13. SSH через сеть Tor


Анонимная сеть Tor может туннелировать SSH-трафик с помощью команды torsocks. Следующая команда прокинет ssh-прокси через Tor.
localhost:~$ torsocks ssh myuntracableuser@remoteserver

Torsocks будет использовать для прокси порт 9050 на localhost. Как всегда при использовании Tor необходимо серьёзно проверять, какой трафик туннелируется и другие проблемы операционной безопасности (opsec). Куда идут ваши DNS-запросы?

14. SSH к инстансу EC2


Для подключения к инстансу EC2 необходим закрытый ключ. Скачайте его (расширение .pem) из панели управления Amazon EC2 и измените разрешения (chmod 400 my-ec2-ssh-key.pem). Храните ключ в надёжном месте или поместите его в свою папку ~/.ssh/.
localhost:~$ ssh -i ~/.ssh/my-ec2-key.pem ubuntu@my-ec2-public

Параметр -i просто указывает ssh-клиенту использовать этот ключ. Файл ~/.ssh/config идеально подходит для автоматической настройки использования ключа при подключении к хосту ec2.
Host my-ec2-public
   Hostname ec2???.compute-1.amazonaws.com
   User ubuntu
   IdentityFile ~/.ssh/my-ec2-key.pem

15. Редактирование текстовых файлов с помощью VIM через ssh/scp


Для всех любителей vim этот совет сэкономит немного времени. С помощью vim файлы редактируются по scp одной командой. Этот метод просто создаёт файл локально в /tmp, а затем копирует его обратно, как только мы его сохранили из vim.
localhost:~$ vim scp://user@remoteserver//etc/hosts

Примечание: формат немного отличается от обычного scp. После хоста у нас двойной //. Это ссылка на абсолютный путь. Один слэш будет означать путь относительно домашней папки users.
**warning** (netrw) cannot determine method (format: protocol://[user@]hostname[:port]/[path])

Если увидите такую ошибку, дважды проверьте формат команды. Обычно это означает синтаксическую ошибку.

16. Монтирование удалённого SSH как локальной папки с SSHFS


При помощи sshfs — клиента файловой системы ssh — мы можем подключить локальный каталог к удалённому местоположению со всеми взаимодействиями файлов в зашифрованном сеансе ssh.
localhost:~$ apt install sshfs

На Ubuntu и Debian установим пакет sshfs, а затем просто приимонтируем удалённое расположение к нашей системе.
localhost:~$ sshfs user@remoteserver:/media/data ~/data/

17. Мультиплексирование SSH с помощью ControlPath


По умолчанию при наличии существующего подключения к удалённому серверу с помощью ssh второе подключение с помощью ssh или scp устанавливает новый сеанс с дополнительной аутентификацией. Опция ControlPath позволяет использовать существующий сеанс для всех последующих соединений. Это значительно ускорит процесс: эффект заметен даже в локальной сети, а тем более при подключении к удалённым ресурсам.
Host remoteserver
        HostName remoteserver.example.org
        ControlMaster auto
        ControlPath ~/.ssh/control/%r@%h:%p
        ControlPersist 10m

ControlPath указывает сокет для проверки новыми соединениями на предмет наличия активной сессии ssh. Последняя опция означает, что даже после выхода из консоли существующий сеанс останется открытым 10 минут, так что в течение этого времени вы сможете повторно подключиться по существующему сокету. Для дополнительной информации смотрите справку ssh_config man.

18. Потоковое видео по SSH с помощью VLC и SFTP


Даже давние пользователи ssh и vlc (Video Lan Client) не всегда знают об этой удобной опции, когда очень нужно посмотреть видео по сети. В настройках File | Open Network Stream программы vlc можно ввести местоположение как sftp://. Если требуется пароль, появится запрос.
sftp://remoteserver//media/uploads/myvideo.mkv

19. Двухфакторная аутентификация


Такая же двухфакторная аутентификация, как у вашего банковского счёта или учётной записи Google, применима к сервису SSH.

Конечно, ssh изначально имеет функцию двухфакторной аутентификации, под которой подразумеваются пароль и ключ SSH. Преимущество аппаратного токена или приложения Google Authenticator заключается в том, что это обычно другое физическое устройство.

См. наше 8-минутное руководство по использованию Google Authenticator и SSH.

20. Прыжки по хостам с ssh и -J


Если из-за сегментации сети приходится переходить через несколько хостов ssh, чтобы добраться до конечной сети назначения, вам сэкономит время ярлык -J.
localhost:~$ ssh -J host1,host2,host3 [email protected]

Здесь главное понимать, что это не аналогично команде ssh host1, затем user@host1:~$ ssh host2 и т. д. Параметр -J хитро использует переадресацию, чтобы localhost устанавливал сеанс со следующим хостом в цепочке. Таким образом, в приведённом выше примере наш localhost аутентифицируется на host4. То есть используются наши ключи localhost, а сеанс от localhost до host4 полностью зашифрован.

Для такой возможности в ssh_config укажите опцию конфигурации ProxyJump. Если регулярно приходится переходить через несколько хостов, то автоматизация через конфиг сэкономит массу времени.

21. Блокировка попыток брутфорса SSH с помощью iptables


Любой, кто управлял сервисом SSH и просматривал логи, знает о количестве попыток брутфорса, которые происходят каждый час каждый день. Быстрый способ уменьшить шум в логах — перенести SSH на нестандартный порт. Внесите изменения в файл sshd_config с помощью параметра конфигурации Port##.

С помощью iptables тоже можно легко блокировать попытки подключения к порту по достижении определённого порога. Простой способ сделать это — использовать OSSEC, поскольку он не только блокирует SSH, но выполняет кучу других мер по обнаружению вторжений на базе имени хоста (HIDS).

22. SSH Escape для изменения переадресации портов


И наш последний пример ssh предназначен для изменения переадресации портов на лету в рамках существующего сеанса ssh. Представьте такой сценарий. Вы глубоко в сети; возможно, прыгнули через полдюжины хостов и вам нужен локальный порт на рабочей станции, который перенаправлен на Microsoft SMB старой системы Windows 2003 (кто-нибудь помнит ms08-67?).

Нажав enter, попробуйте ввести в консоли ~C. Это управляющая последовательность в сессии, позволяющая вносить изменения в существующее соединение.

localhost:~$ ~C
ssh> -h
Commands:
      -L[bind_address:]port:host:hostport    Request local forward
      -R[bind_address:]port:host:hostport    Request remote forward
      -D[bind_address:]port                  Request dynamic forward
      -KL[bind_address:]port                 Cancel local forward
      -KR[bind_address:]port                 Cancel remote forward
      -KD[bind_address:]port                 Cancel dynamic forward
ssh> -L 1445:remote-win2k3:445
Forwarding port.

Здесь вы можете увидеть, что мы переадресовали наш локальный порт 1445 на хост Windows 2003, который нашли во внутренней сети. Теперь просто запустите msfconsole, и можно идти дальше (предполагая, что вы планируете использовать этот хост).
Эти примеры, советы и команды ssh должны дать отправную точку; дополнительная информация о каждой из команд и возможностей доступна на справочных страницах (man ssh, man ssh_config, man sshd_config).

Меня всегда очаровывала возможность обращаться к системам и выполнять команды в любой точке мира. Развивая свои навыки по работе с инструментами вроде ssh вы станете более эффективным в любой игре, в какую играете.

SSH-туннели — пробрасываем порт / Хабр

Не всегда есть возможность, да и не всегда надо, строить полноценный туннель с интерфейсной парой адресов. Иногда нам нужно лишь «прокинуть» вполне определённые порты.

Тут важно понимать, что туннель можно организовать как изнутри сети, к ресурсам которой вы хотите получить доступ, на внешний ssh-сервер. Также можно организовать туннель с хоста в Интернете на пограничный ssh-сервер сети, чтобы получить доступ к внутренним ресурсам.

Итак. По-порядку.

Строим туннель из сети в мир.

$ ssh -f -N -R 2222:10.11.12.13:22 [email protected]

теперь введя на хосте 99.88.77.66:

$ ssh -p2222 localhost

мы попадём на хост 10.11.12.13.

Таким-же образом можно получить доступ к любому другому ресурсу, например:

$ ssh -f -N -R 2080:10.11.12.14:80 [email protected]

Введя на хосте 99.88.77.66:

$ w3m -dump http://localhost:2080

получим дамп web-ресурса на 10.11.12.14.

Строим туннель из мира в сеть.

$ ssh -f -N -L 4080:192.168.0.10:80 [email protected]

Аналогично, вводим на своём хосте:

$ w3m -dump http://localhost:4080

и получаем доступ к web-ресурсу узла 192.168.0.10, который находится за хостом 88.77.66.55.

Поддерживаем туннели в поднятом состоянии
Ни для кого не секрет, что связь иногда обрывается, туннели при этом будут отваливаться по таймауту.
Чтобы не утруждать себя дополнительным монотонным вбиванием команды на поднятие туннеля и мониторингом этого процесса, автоматизируем его. Смело вводим:

$ crontab -e

и создаём расписание примерно следующего вида:

TUNCMD1='ssh -f -N -R 2222:10.11.12.13:22 [email protected]'
TUNCMD2='ssh -f -N -R 2080:10.11.12.14:80 [email protected]'

*/5 * * * * pgrep -f "$TUNCMD1" &>/dev/null || $TUNCMD1
*/5 * * * * pgrep -f "$TUNCMD2" &>/dev/null || $TUNCMD2

Сохраняемся. Проверяем по

$ crontab -l

что расписание принято.

Это лишь ещё один момент особой админской магии… Надеюсь, что лишних вопросов не должно водникнуть. С дополнительными опциями ssh можно ознакомиться в

$ man 1 ssh

По практическому опыту — cron-задания на перезапуск абсолютно недостаточно.
Разве что соединение абсолютно стабильно. В реальной жизни встречается в 0% случаев.
Даже соединённые напрямую кабелем две сетевые карты легко могут потерять n-ное количество пакетов и tcp-соединение «упадёт».
Клиент и сервер будут пребывать в святой уверенности, что всё в порядке, просто вторая сторона ничего не передаёт.
Нужен keepalive.
Примерно так:

TCPKeepAlive yes
ServerAliveInterval 300
ServerAliveCountMax 3

Интервал и счётчик — по вкусу.
Добавлять их надо либо в /etc/ssh_config, либо в ~/.ssh/config, либо прямо в команде через опцию -o.
В принципе, судя по man ssh_config, первую из опций можно и опустить. но, на всякий случай, пусть будет.

Учимся использовать SSH туннелирование для безопасного серфинга

Существует три различных типа туннелирования, и все они используются для решения разных задач. Каждая задача предполагает использование SSH-сервера для перенаправления трафика из одного сетевого порта в другой. Трафик передается по зашифрованному SSH-соединению, поэтому его нельзя отследить или изменить в процессе передачи:


Туннелирование можно реализовать с помощью ssh-команды в Linux, Mac OS и операционных системах семейства UNIX. Для пользователей Windows, где нет встроенной ssh-команды, мы предлагаем бесплатный инструмент PuTTY. Он умеет подключаться к SSH-серверам. Он также поддерживает SSH-туннелирование.

«Локальное перенаправление портов» позволяет осуществлять доступ к ресурсам, находящимся внутри локальной сети. Предположим, что нужно попасть на офисный сервер БД, сидя дома. В целях безопасности этот сервер настроен так, чтобы принимать подключения только с ПК, находящихся в локальной сети офиса. Но если у вас есть доступ к SSH-серверу, находящемуся в офисе, и этот SSH-сервер разрешает подключения из-за пределов офисной сети, то к нему можно подключиться из дома. Затем осуществить доступ к БД. Проще защитить от атак один SSH-сервер, чем защищать каждый ресурс локальной сети по отдельности.

Чтобы сделать это, вы устанавливаете SSH-соединение с SSH-сервером и говорите клиенту передать трафик с указанного порта на локальном ПК. Например, с порта 1234 на адрес сервера базы данных и его порт внутри офисной сети. Когда вы пытаетесь получить доступ к БД через порт 1234 на вашем ПК («localhost») трафик автоматически «туннелируется» по SSH-соединению и отправляется на сервер БД.

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

Чтобы использовать локальное перенаправление, подключитесь к SSH-серверу с использованием вспомогательного аргумента -L. Синтаксис для туннелирования трафика будет следующим:

ssh -L local_port:remote_address:remote_port [email protected]

Предположим, что офисный сервер находится по адресу 192.168.1.111. У вас есть доступ к SSH-серверу через адрес ssh.youroffice.com, и имя вашего аккаунта на SSH-сервере — bob. В таком случае необходимая команда будет выглядеть следующим образом:

ssh -L 8888:192.168.1.111:1234 [email protected]

Запустив эту команду, вы попадете на офисный сервер баз данных через порт 8888 на localhost. Если у СУБД есть веб-интерфейс, можно вписать в адресную строку браузера http://localhost:8888. Если у вас инструмент командной строки, которому необходим сетевой адрес базы данных, то направьте его на localhost:8888. Весь трафик, отправленный на порт 8888 на ПК, будет перенаправлен на 192.168.1.111:1234 внутри офисной сети:


Это слегка сбивает с толку, если надо подключиться к серверному приложению, запущенному в той же системе, где и сам SSH-сервер. К примеру, есть SSH-сервер, работающий на порте 22 на офисном ПК. Но у вас также есть сервер баз данных, работающий на порте 1234 в той же системе по тому же адресу. Вам нужно подключиться к БД из дома, но система принимает только SSH-подключение через 22 порт, и сетевой экран не пропускает любые внешние подключения. В таком случае можно запустить следующую команду:

ssh -L 8888:localhost:1234 [email protected]

При попытке подключиться к БД через 8888 порт на вашем ПК, трафик будет передаваться с помощью SSH-подключения. Когда он достигнет системы, в которой работает SSH, SSH-сервер отправит его на порт 1234 на «localhost», принадлежащий тому же ПК, на котором запущен SSH-сервер. То есть, «localhost» в приведённой выше команде означает «localhost» с перспективы удалённого сервера:


Чтобы сделать это в PuTTY на Windows, выберите опцию Connection > SSH > Tunnels. Далее опцию «Local». В поле «Source Port» укажите локальный порт. В поле «Destination» введите целевой адрес и порт в формате удалённый_адрес:удалённый_порт.

Например, если нужно настроить SSH-тоннель, как это сделано выше, то введите 8888 в качестве порта-источника и localhost:1234 в качестве целевого адреса. После этого нажмите «Add» и затем «Open», чтобы открыть SSH-подключение. До подключения SSH туннелирования нужно ввести адрес и порт самого SSH-сервера в разделе «Session»:

«Дистанционное перенаправление портов» — ситуация, противоположная локальному перенаправлению, и используется не так часто. Она позволяет открывать доступ к ресурсам на локальном ПК через SSH-сервер. Предположим, что на локальном ПК настроен веб-сервер. Но ваш ПК защищён сетевым экраном, который не пропускает входящий трафик на сервер.

Если есть доступ к удалённому SSH-серверу, можно подключиться к этому SSH-серверу и использовать дистанционное перенаправление портов. Ваш SSH-клиент укажет серверу перенаправлять трафик с определённого порта – скажем, 1234 – на SSH-сервере на указанный адрес и порт на вашем ПК или внутри локальной сети. Когда кто-то подключается к порту 1234 на SSH-сервере, этот трафик автоматически «туннелируется» по SSH-соединению. Любой, кто подключается к SSH-серверу, сможет получить доступ к серверу, запущенному на вашем ПК. Это достаточно эффективный способ обхода фаерволов.

Чтобы воспользоваться дистанционным туннелированием IP, используйте ssh-команду с аргументом —R. Синтаксис здесь будет практически таким же, как и в случае с локальным перенаправлением:

ssh -R remote_port:local_address:local_port [email protected]

Предположим, что нужно создать серверное приложение, прослушивающее порт 1234 на вашем ПК. Оно доступно через порт 8888 на удалённом SSH-сервере. Адрес SSH-сервера ssh.youroffice.com, а ваше имя пользователя на SSH-сервере bob. Значит, команда будет следующей:

ssh -R 8888:localhost:1234 [email protected]

Затем кто-то может подключиться к SSH-серверу через порт 8888, и это подключение будет туннелировано на серверное приложение, запущенное на порте 1234 ПК, с которого вы подключались:


Чтобы сделать это в PuTTY для Windows, выберите опцию Connection > SSH > Tunnels. Далее – опцию «Remote». В поле «Source Port» укажите удалённый порт. В поле «Destination» введите целевой адрес и порт в формате локальный_адрес:локальный_порт.

Например, если нужно настроить SSH-тоннель, как это сделано выше, то укажите 8888 в качестве порта-источника и localhost:1234 в качестве целевого адреса. После этого нажмите «Add» и затем «Open», чтобы открыть SSH-подключение. До подключения нужно будет ввести адрес и порт самого SSH-сервера в разделе «Session».

После этого пользователи смогут подключаться к порту 8888 на SSH-сервере и их трафик будет передаваться на порт 1234 на вашей локальной системе:


По умолчанию, удалённый SSH-сервер будет слушать только подключения с того же хоста. Другими словами, доступ будет только у людей из той же системы, на которой запущен SSH-сервер. При туннелировании трафика так делается в целях безопасности.

Нужно включить опцию «GatewayPorts» в sshd_config на удалённом SSH-сервере, если хотите изменить эти настройки.

Также существует «динамическое перенаправление портов», которое работает по тому же принципу что прокси или VPN-сервер. SSH-клиент создаёт SOCKS-прокси, который можно настраивать под собственные приложения. Весь трафик, отправляемый через прокси, будет отправляться через SSH-сервер. Принцип здесь схож с локальным перенаправлением – берётся локальный трафик, отправленный на определённый порт на вашем ПК, и перенаправляется через SSH-соединение на удалённый адрес.

Предположим, что вы используете общедоступную Wi-Fi сеть. Но хочется делать это безопасно. Если у вас есть доступ к SSH-серверу из дома, то можно подключиться к нему и использовать динамическое перенаправление. SSH-клиент создаст SOCKS-прокси на вашем ПК. Весь трафик, отправленный на этот прокси, будет отправляться через подключение к SSH-серверу. Никто из тех, кто использует общедоступную Wi-Fi сеть, не сможет отслеживать ваши перемещения в сети или закрывать доступ к сайтам. С перспективы сайтов, которые посещаете, будет казаться, что вы заходите на них с домашнего ПК.

Или же может понадобиться подключиться к медиа-серверу, находящемуся в вашей домашней сети. В целях безопасности, к интернету подключен только ваш SSH-сервер. При этом вы не разрешаете подключаться к медиа-серверу через интернет. В таком случае можно включить динамическое перенаправление портов, настроить SOCKS-прокси в браузере и затем подключаться к серверам, работающим в домашней сети, через браузер, как будто вы сидите дома.

Например, если медиа-сервер находится по адресу 192.168.1.123 в вашей домашней сети, то можно добавить адрес 192.168.1.123 в любое приложение при помощи SOCKS-прокси и получить доступ к медиа-серверу, как будто вы находитесь внутри домашней сети.

Чтобы воспользоваться динамическим перенаправлением, запустите ssh-команду с аргументом —D:

ssh -D local_port [email protected]

Предположим, что у вас есть доступ к SSH-серверу по адресу ssh.yourhome.com, а ваш логин на SSH-сервере – bob. Нужно использовать динамическое перенаправление для того, чтобы открыть SOCKS-прокси по порту 8888 на текущем ПК. Тогда команда для SSH туннелирования будет выглядеть следующим образом:

ssh -D 8888 [email protected]

После этого можно настроить браузер или другое приложение на использование локального IP-адреса (127.0.0.1) и порта 8888. Весь трафик этого приложения будет перенаправляться через туннель:


Чтобы сделать это в PuTTY для Windows, выберите опцию Connection > SSH > Tunnels. Далее – опцию «Dynamic». В поле «Source Port» укажите локальный порт.

Например, если вам нужно настроить SOCKS-прокси на порт 8888, то введите 8888 в качестве порта-источника. После этого нажмите «Add» и затем «Open», чтобы открыть SSH-подключение.

После этого можно настроить приложение на подключение через SOCKS-прокси на вашем локальном ПК (то есть, по IP-адресу 127.0.0.1, который ведёт на ваш локальный ПК) и указать корректный порт для работы:


К примеру, можно настроить браузер Firefox на использование SOCKS-прокси. Это удобно, так как у Firefox могут быть отдельные настройки прокси, и поэтому не обязательно использовать базовые параметры для всей системы. Firefox будет отправлять трафик через SSH туннелирование, а другие приложения будут использовать интернет-подключение в обычном режиме.

Туннель будет оставаться активным и открытым до тех пор, пока открыта сессия SSH-соединения. Когда вы завершите SSH-сессию и отключаетесь от сервера, туннель тоже закроется. Чтобы снова открыть туннель, переподключитесь при помощи соответствующей команды или нужной функции в PuTTY.

Магия SSH / Хабр

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

Оглавление:

1) Local TCP forwarding
2) Remote TCP forwarding
3) TCP forwarding chain через несколько узлов
4) TCP forwarding ssh-соединения
5) SSH VPN Tunnel
6) Коротко о беспарольном доступе
7) Спасибо (ссылки)

1) Local TCP forwarding


Начнем с простого — local TCP forwarding:

Имеем удаленный сервер «host2» с неким приложением, допустим, PostgreSQL server, которое принимает TCP-соединения на порту 5432. При этом вполне логично, что на этом сервере стоит файрвол, который прямых соединений извне на порт 5432 не разрешает, но при этом есть доступ по SSH (по-умолчанию порт 22, рекомендую его изменить). Требуется подключиться с нашего рабочего места «host1» клиентским приложением к серверу PostgreSQL на «host2».

Для этого на «host1» в консоли набираем:

host1# ssh -L 9999:localhost:5432 host2

Теперь на «host1» мы можем соединяться с PostgreSQL сервером через локальный порт 9999:

host1# psql -h localhost -p 9999 -U postgres

Если на «host1» WindowsНапример, в PuTTy это делается так:
Идем по дереву настроек: Connection → SSH → Tunnels.
Далее в поле «Source port» вбиваем 9999, в «Destination» — localhost:5432, и нажимаем Add.
Не забываем после этого сохранить настройки сессии, если требуется.


Как это работает

После успешного подключения к SSH-серверу на «host2», на «host1» SSH-клиент начинает слушать порт 9999. При подключении к порту 9999 на «host1», SSH-сервер на «host2» устанавливает соединение с localhost (коим и является для себя самого «host2») на порт 5432 и передает по этому соединению данные, принятые ssh-клиентом на «host1» на порт 9999.
ВАЖНО! Все указанные на схемах стрелками соединения являются отдельными TCP-соединениями (сессиями).


Настройка SSH-сервера

Port forwarding, как правило, уже включен в настройках sshd по-умолчанию.
/etc/ssh/sshd_config:
AllowTcpForwarding yes


Мы также можем соединяться с приложением не на самом «host2», а на любой доступной ему машине:

Для этого при пробросе портов вместо «localhost» указываем имя хоста, например «host3»:

host1# ssh -L 9999:host3:5432 host2

Тут важно заметить, что «host3» должен быть известен (если это имя, а не IP-адрес) и доступен для машины «host2».

Также можно через «host1» предоставить доступ любому другому узлу (назовем его «host1A») к сервису на «host3»:

Для этого нужно вставить в команду соединения ssh IP-адрес интерфейса, на котором будет поднят локальный порт 9999:

ssh -L 0.0.0.0:9999:host3:5432 host2

В данном примере порт 9999 будет открыт на всех доступных на «host1» IPv4 интерфейсах.

2) Remote TCP forwarding


Но что делать, если, например, «host2» не имеет белого IP-адреса, находится за NAT или вообще все входящие соединения к нему закрыты? Или, например, на «host2» стоит Windows и нет возможности поставить SSH-сервер?

Для этого случая есть Remote TCP forwarding:

Теперь нужно устанавливать ssh-соединение в обратном направлении — от «host2» к «host1». Т.е. наша административная рабочая станция будет SSH-сервером и будет доступна по SSH с «host2», а на «host2» нужно будет выполнить подключение SSH-клиентом:

ssh -R 9999:localhost:5432 host1

Если на «host2» WindowsНапример, в PuTTy это делается так:
Идем по дереву настроек: Connection → SSH → Tunnels.
Далее в поле «Source port» вбиваем 9999, в «Destination» — localhost:5432, а ниже выбираем «Remote», и нажимаем Add.
Не забываем после этого сохранить настройки сессии, если требуется.



Как это работает

После успешного подключения, на «host1» SSH-сервер начинает слушать порт 9999. При подключении к порту 9999 на «host1», SSH-клиент на «host2» устанавливает соединение с localhost (коим и является для себя самого «host2») на порт 5432 и передает по этому соединению данные, принятые ssh-сервером на «host1» на порт 9999.


Также у вас возникнут дополнительные сложности с обеспечением безопасности на «host1», если вы не доверяете узлу «host2». Однако это выходит за рамки данной статьи.

И, конечно, вы каким-то образом (сами или с посторонней помощью) должны инициировать ssh-соединение со стороны «host2» вводом приведенной выше команды, а «host1» должен иметь белый IP-адрес и открытый порт SSH.

После установки ssh-соединения все работает аналогично предыдущей главе.

3) TCP forwarding chain через несколько узлов


В закрытых сетях часто бывает, что нужный нам узел напрямую недоступен. Т.е. мы можем зайти на нужный хост только по цепочке, например host1 → host2 → host3 → host4:
host1# ssh host2
host2# ssh host3
host3# ssh host4
host4# echo hello host4

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

В таком случае мы также можем делать TCP forwarding по цепочке:

Здесь порты 9991, 9992, 9993 выбраны для наглядности, на практике можно использовать один и тот же порт (например, 9999), если он свободен на всех узлах.

Итого нужно выполнить следующую цепочку команд:

host1# ssh -L 9991:localhost:9992 host2
host2# ssh -L 9992:localhost:9993 host3
host3# ssh -L 9993:localhost:5432 host4

Как это работаетПосле успешного выполнения перечисленных выше команд, на узлах выполняется следующее:
  • на «host1»: открывается порт 9991, при подключении к которому данные перенаправляются по ssh-соединению на порт 9992 на «host2»;
  • на «host2»: открывается порт 9992, при подключении к которому данные перенаправляются по ssh-соединению на порт 9993 на «host3»;
  • на «host3»: открывается порт 9993, при подключении к которому данные перенаправляются по ssh-соединению на порт 5432 на «host4»;

Таким образом, при соединении на порт 9991 на «host1», данные перенаправляются по цепочке на «host4» на порт 5432.

ВАЖНО! Все указанные на схемах стрелками соединения являются отдельными TCP-соединениями (сессиями).


4) TCP forwarding ssh-соединения


Иногда бывает нужно соединиться по ssh с сервером, который напрямую недоступен, а доступ возможен только по цепочке ssh-серверов (см. предыдущую главу). Теперь мы обладаем нужными знаниями чтобы сделать следующее:

host1# ssh -L 2222:localhost:2222 host2
host2# ssh -L 2222:host4:22 host3

Таким образом, на порту 2222 на «host1» у нас теперь есть форвардинг на порт SSH (22) на «host4». Можем соединиться:

host1# ssh -p 2222 localhost
host4# echo hello host4

Казалось бы, зачем это нужно? Например, вот зачем:

# копируем файл на host4
host1# scp -P 2222 /local/path/to/some/file localhost:/path/on/host4
# копируем файл с host4
host1# scp -P 2222 localhost:/path/on/host4 /local/path/to/some/file
# делаем еще один замечательный TCP forwarding на host4
host1# ssh -p 2222 -L 9999:localhost:5432 localhost
host1# psql -h localhost -p 9999 -U postgres
# обратите внимание, что порт для команды ssh задается ключем -p в нижнем регистре,
# а для команды scp -P в верхнем регистре

Ну и вообще, здорово что теперь «host4» так близко 🙂

Вывод: можно делать TCP forwarding большого уровня вложенности.

Замечания про RSA fingerprintВ некоторых случаях scp не отработает, пока не зайдете сначала через ssh -p 2222 localhost и не примете RSA fingerprint удаленного сервера.

Если пользуетесь одним и тем же портом (2222) для доступа к разным удаленным серверам, то будут ошибки RSA fingerprint, который остался от предыдущего сервера. Его нужно будет удалить из ~/.ssh/known_hosts.


5) SSH VPN Tunnel


TCP port forwarding — это отличная возможность. Но что если нам нужно больше? Доступ по UDP, доступ к множеству портов и хостов, доступ к динамическим портам? Ответ очевиден — VPN. И всемогущий SSH начиная с версии 4.3 и здесь придет нам на помощь.

Забегая вперед скажу: этот функционал SSH хорошо работает если вам нужно временное решение для каких-то административных задач. Для построения постоянных VPN этот вариант далеко не самый подходящий, т. к. он предполагает TCP-over-TCP, что плохо скажется на скорости соединения.

Еще про TCP forwardingА вот TCP port forwarding с помощью SSH, если его достаточно, во многих случаях выиграет по производительности у VPN, т. к. при TCP port forwarding передаются только данные приложения, а не исходные пакеты целиком вместе с заголовками, см. ссылку: http://blog.backslasher.net/ssh-openvpn-tunneling.html

Настройка SSH-сервера:
PermitTunnel в настройках sshd по-умолчанию выключен, его нужно включить в /etc/ssh/sshd_config:
PermitTunnel yes
или
PermitTunnel point-to-point

ВАЖНО: для поднятия нового сетевого интерфейса туннеля и на ssh-клиенте, и на ssh-сервере необходимы права суперпользователя. Можно долго спорить о том, насколько это небезопасно, но в большинстве случаев на ssh-сервере достаточно настройки:

PermitRootLogin without-password

Таким образом вы запрещаете вход root по паролю, а разрешаете только другими средствами, например, по ключу RSA, что гораздо безопаснее.

Перезапускаем sshd:
sudo service sshd restart # centos
или
/etc/init.d/ssh restart # (debian/ubuntu)

Туннель поднимается при использовании магического ключа -w:

host1# sudo ssh -w 5:5 root@host2

Где 5:5 — номер интерфейса на локальной машине и на удаленной соответственно. Здесь вас может смутить, что ifconfig не выдаст в списке интерфейса «tun5». Это потому что он в состоянии «down», а вот если вызвать «ifconfig -a» или «ifconfig tun5», то интерфейс будет виден:

host1# ifconfig tun5
tun5 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
POINTOPOINT NOARP MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)

Назначаем интерфейсам IP-адреса и поднимаем их:

host1# sudo ifconfig tun5 192.168.150.101/24 pointopoint 192.168.150.102
host2# sudo ifconfig tun5 192.168.150.102/24 pointopoint 192.168.150.101

Если есть файрвол, не забываем разрешить соединения с интерфейса tun5:

host1# # сохраняем исходные правила файрвола
host1# sudo iptables-save > /tmp/iptables.rules.orig
host1# sudo iptables -I INPUT 1 -i tun5 -j ACCEPT
host2# # сохраняем исходные правила файрвола
host2# sudo iptables-save > /tmp/iptables.rules.orig
host2# sudo iptables -I INPUT 1 -i tun5 -j ACCEPT

На host1 это делать необязательно, здесь это сделано лишь для того чтобы ping работал в обе стороны.

Наслаждаемся пингом:

host1# ping 192.168.150.102
host2# ping 192.168.150.101

Если рассмотреть более ранний пример с PostgreSQL, то теперь схема будет такая:

А команда для подключения к серверу PostgreSQL будет выглядеть так:

host1# psql -h 192.168.150.102 -U postgres

Ну а далее можно делать какой-либо из этих узлов шлюзом, если нужно обеспечить доступ не к одному узлу, а к сети. Например:

host2# # разрешаем IP forwarding
host2# sudo sysctl -w net.ipv4.ip_forward=1
host2# # разрешаем IP forwarding с host1
host2# sudo iptables -I FORWARD 1 -s 192.168.150.101 -j ACCEPT
host2# # разрешаем IP forwarding на host1
host2# sudo iptables -I FORWARD 1 -d 192.168.150.101 -j ACCEPT
host2# # маскируем IP адрес host1
host2# sudo iptables -t nat -A POSTROUTING -s 192.168.150.101 -j MASQUERADE

host1# # Предположим, у host2 есть доступ к сети 192.168.2.x, куда нам нужно попасть с host1
host1# # Прописываем host2 как шлюз в сеть 192.168.2.x
host1# sudo ip route add 192.168.2.0/24 via 192.168.150.2
host1# # Наслаждаемся доступом в сеть с host1
host1# ping 192.168.2.1

После окончания работы не забываем вернуть net.ipv4.ip_forward и файрвол в исходное состояние.

host1# sudo iptables-restore < /tmp/iptables.rules.orig
host2# sudo iptables-restore < /tmp/iptables.rules.orig

Под спойлером более интересный случай с временным расшариванием ИнтернетаДопустим, нужно настроить сервер в закрытой сети, где доступ в Интернет запрещен, но тем не менее у вас туда есть лазейка — доступ через один ssh-сервер или цепочку ssh-серверов. Предположим, для настройки сервера вам нужен на нем доступ в Интернет. Тогда проще самостоятельно настроить временный доступ в Интернет на требующем настройки сервере, чем просить это сделать обслуживающий персонал.

Допустим, есть доступ по ssh с вашей рабочей машины host1 на сервер host2, с него — на host3, а уже оттуда — на нужный вам host4. Тогда делаем TCP forwarding для ssh (если с host1 вы сразу можете соединиться с host4, пропустите этот шаг):

host1# ssh -L 2222:localhost:2222 host2
host2# ssh -L 2222:host4:22 host3

Далее, соединяемся с host4 и поднимаем интерфейс tun5:

host1# sudo ssh -p 2222 -w 5:5 root@localhost
host1# # или если host4 доступен сразу: sudo ssh -w 5:5 root@host4
host1# sudo ifconfig tun5 192.168.150.101/24 pointopoint 192.168.150.102
host4# sudo ifconfig tun5 192.168.150.102/24 pointopoint 192.168.150.101

Смотрим таблицу маршрутизации на host4, допустим видим следующее:

host4# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.150.0 0.0.0.0 255.255.255.0 U 0 0 0 tun5
192.168.56.0 0.0.0.0 255.255.255.0 U 1 0 0 eth0
0.0.0.0 192.168.56.254 0.0.0.0 UG 0 0 0 eth0

ВАЖНО! Далее нам скорее всего захочется сделать маршрутом по-умолчанию интерфейс tun5 со шлюзом 192.168.150.101, через который будет доступен Интернет. Поэтому на данном этапе важно точно знать, какие маршруты нужно дописать, чтобы заменить маршрут по-умолчанию. Это важно, поскольку довольно часто маршруты на отдельные сети не прописывают отдельно, а просто задают маршрут по-умолчанию (0.0.0.0/0) со шлюзом, через который и идет весь межсетевой трафик. Более того, вполне вероятно что ваше ssh-соединение с сервером также использует исходный шлюз по-умолчанию.

Для простоты в данном примере предположим, что никаких маршрутов кроме 192.168.56.0/24 серверу для нормального функционирования не нужно и что предыдущий ssh-хост host3 имеет IP-адрес из этой же сети.

Запоминаем и записываем куда-нибудь исходную маршрутную таблицу со шлюзом по-умолчанию:
host4# route -n > routes.orig

Настраиваем наш host1 для работы в качестве шлюза в Интернет для host4:

host1# # разрешаем IP forwarding
host1# sudo sysctl -w net.ipv4.ip_forward=1
host1# # сохраняем исходные правила файрвола
host1# sudo iptables-save > /tmp/iptables.rules.orig
host1# # разрешаем IP forwarding с host4
host1# sudo iptables -I FORWARD 1 -s 192.168.150.102 -j ACCEPT
host1# # разрешаем IP forwarding на host4
host1# sudo iptables -I FORWARD 1 -d 192.168.150.102 -j ACCEPT
host1# # маскируем IP адрес host4
host1# sudo iptables -t nat -A POSTROUTING -s 192.168.150.102 -j MASQUERADE

На всякий случай можно прописать серые сети на шлюз из текущего маршрута по-умолчанию

Если не прописаны:
sudo ip route add 192.168.0.0/16 via 192.168.56.254
sudo ip route add 10.0.0.0/8 via 192.168.56.254
sudo ip route add 172.16.0.0/12 via 192.168.56.254

Изменяем маршрут по-умолчанию на host4 (ОСТОРОЖНО, см. предупреждение выше!):

host4# sudo ip route replace default via 192.168.150.101
host4# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.150.0 0.0.0.0 255.255.255.0 U 0 0 0 tun5
192.168.56.0 0.0.0.0 255.255.255.0 U 1 0 0 eth0
0.0.0.0 192.168.150.101 0.0.0.0 UG 0 0 0 tun5

Если весь Интернет нам не нужен, а только конкретные IP-адреса/маски, то можно маршрут по-умолчанию не менять, а дописать только нужные нам адреса через шлюз на tun5.

Проверяем, что есть Интернет:

host4# ping 8.8.8.8

Отлично. Осталось настроить DNS. Есть множество способов это сделать, проще всего отредактировать файл /etc/resolv.conf и добавить туда строчки:

nameserver 8.8.8.8
nameserver 8.8.4.4

После этого Интернет должен быть полностью доступен:

host4# ping ya.ru

После окончания работы не забываем вернуть все в исходное состояние:

host1# # восстанавливаем правила файрвола на host1
host1# sudo iptables-restore < /tmp/iptables.rules.orig
host1# # не забудьте восстановить также значение net.ipv4.ip_forward

host2# # восстановите маршрут по-умолчанию на host4:
host2# sudo ip route replace default via 192.168.56.254
host2# # и уберите добавленные ранее DNS-сервера из /etc/resolv.conf


6) Коротко о беспарольном доступе


Думаю, все уже знают что авторизация по паролю это не про нас. Но на всякий случай впихну сюда краткую инструкцию по настройке аутентификации по ключу RSA:

1. На клиентских машинах генерируем пользователю свой ключ RSA:

client1# ssh-keygen -t rsa

По-умолчанию приватный ключ сохраняется в ~/.ssh/id_rsa, а открытый — в ~/.ssh/id_rsa.pub. Приватный ключ храните как зеницу ока и никому не давайте, никуда не копируйте.
При создании ключа можно задать пароль (passphrase), которым ключ будет зашифрован.

2. Клиентские открытые ключи нужно сохранить на ssh-сервере в файле ~/.ssh/authorized_keys (~ это домашняя директория того пользователя, которым будете логиниться), каждый на отдельной строке. Для того чтобы это не делать вручную, на каждом клиенте можно воспользоваться командой:

ssh-copy-id user@sshserver

Где user — имя пользователя на сервере, sshserver — имя или IP-адрес ssh-сервера.

Права на файл ~/.ssh/authorized_keysUPD от sabio: В случае ручного создания файла ~/.ssh/authorized_keys на ssh-сервере необходимо задать следующие права:
chmod 0700 ~/.ssh
chmod 0600 ~/.ssh/authorized_keys

3. Проверьте, что можете зайти на сервер по ключу, без ввода пароля (не путать с passphrase):
ssh user@sshserver
Рекомендую не закрывать хотя бы одну активную ssh-сессию с сервером до тех пор, пока окончательно не закончите настройку и не убедитесь что все работает.

4. Отключите на SSH-сервере возможность входа по паролю в файле /etc/ssh/sshd_config:

PasswordAuthentication no

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

PubkeyAuthentication yes

Я обычно также отключаю две следующие опции:

GSSAPIAuthentication no
UseDNS no

В некоторых случаях это позволяет ускорить процесс соединения (например, когда на сервере нет доступа в Интернет).

5. Перезапустите sshd:
service sshd restart
или
/etc/init.d/ssh restart

В случае ошибок полезно бывает смотреть лог /var/log/secure либо использовать опции -v, -vv или -vvv для вывода детального лога соединения:
ssh -vvv user@sshserver

7) Спасибо (ссылки)


help.ubuntu.com/community/SSH_VPN
habrahabr.ru/post/87197
blog.backslasher.net/ssh-openvpn-tunneling.html

SSH-туннели в примерах

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

Рассмотрим создание и настройку по нескольким вариантам.

И так, у нас имеется сервер, назовём его host-1. К нему у нас есть полный доступ только по SSH — но нам необходимо открыть Tomcat, работающий на порту 8082 — к которому нас никак пропустить не могут.

Рассматривать вариант будем с настройкой Windows и Putty.

Открываем SSH-соединение к нужному серверу, логинимся.

Далее — правой кнопкой клацаем на заголовке окна Putty, выбираем Change settings, переходим в SSH > Tunnels.

Указываем такие параметры:

Source port: любой неиспользуемый порт в вашей системе;
Destination port: 127.0.0.1:8082

Жмём Add, потом Apply.

Переходим в настройки браузера, и устанавливаем параметры прокси:

Теперь остаётся в браузере открыть страницу http://localhost:3002 — и попадаем на страницу Tomcat на сервере host-1.

Если туннель не работает — проверьте на сервере, включена ли пересылка пакетов. В файле /etc/ssh/sshd_config найдите и раскоментируйте строку:

AllowTcpForwarding yes

И перезапустие SSHd:

# service sshd restart
Stopping sshd: [ OK ]
Starting sshd: [ OK ]

Ещё один пример — у нас есть тот же внешний сервер, с которого есть нормальный доступ к любым ресурсам в Сети. А вот с рабочего места у нас доступ к http://youtube.com и http://facebook.com закрыт.

Выполняем похожие действия, но с небольшими отличиями. Настройки в Putty:

Source port — оставляем прежний, но вместо Local — выбираем Dynamic. Нажимаем Add, Apply.

Переходим к настройкам браузера:

Обратите внимание, что тип прокси тут не HTTP — а SOCKS.

Наслаждаемся доступом к любимым сайтам.

И более интересный случай.

Имеем прежний host-1. Кроме него — второй сервер, назовём его host-2. Кроме этого — у нас есть машина с Windows, которой необходимо предоставить доступ к ресурсу TeamCity на сервере host-1 на порту 8111. При этом — доступ с Windows-машины у нас есть только к серверу host-2, и только на 22-ой порт.

Для начала — поднимаем туннель между host-1 и host-2. Выполняем на host-1:

$ ssh -f -N -R host-2:8082:localhost:8111 username@host-2

Так мы открываем туннель, который локально (на host-1) смотрит на порт 8111, а с другой стороны — машина host-2, на которой открывается порт 8082, и ждёт входящих соединений. При получении пакетов на порт 8082 (при чём — только по интерфейсу lo0! это важно) — он будет их перенаправлять на машину host-1 порт 8111.

Что касается интерфейса lo0. При установлении SSH-туннеля, даже при указании внешнего IP машины — соединение поднимается только с localhost, т.е. 127.0.0.1.

Посмотрим на host-2:

$ netstat -anp | grep 8082
tcp        0      0 127.0.0.1:8082          0.0.0.0:*               LISTEN      -

Что бы изменить это — необходимо отредактировать файл конфигурации демона sshd/etc/ssh/sshd_config и изменить параметр:

#GatewayPorts no

Но сейчас мы этого делать не будем, это просто заметка.

Продолжим. Переходим к настройке Putty на нашей Windows-машине. Тут всё просто — пользуемся примером 1 из этой статьи, только меняем порт на нужный (в скриншоте, кстати, он и есть). Подключаемся Putty к хосту host-2, настраиваем tunnel. В браузере меняем настройки proxy — и получаем необходимое, указываем адрес http://localhost:3002:

SSH довольно чувствителен к потерям пакетов, поэтому туннели могут часто обрываться.

Что бы избежать этого — можно либо поиграться с параметрами в файле настроек sshd/etc/ssh/sshd_config:

#TCPKeepAlive yes
#ServerAliveInterval
#ServerAliveCountMax

Либо — воспользоваться утилитой autossh:

# yum -y install autossh

Создание SSH-туннелей с помощью PuTTY

В данной статье будет описано как строить SSH–туннели с помощью PuTTY.

1. Локальный проброс порта

Рассмотрим следующую ситуацию. Мы находимся внутри корпоративной сети, у нашего компьютера адрес 192.168.0.2, доступ во внешний мир полностью закрыт (то есть никакого NAT–а, proxy и т.п.). Влиять на политику ограничения доступа у нас возможности нет, но зато есть SSH–доступ на один из серверов с маршрутизируемым IP–адресом, который доступен из Интернета. Внутренний адрес этого сервера, пусть будет для примера 192.168.0.3. Структура сети изображена на рисунке:

PuTTY SSH Tunnels Schema

Предположим, что нам очень нужно подключиться, к примеру, по SSH на некоторый удалённый сервер с IP–адресом 212.212.212.212 где–то далеко в Интернет. Для этого запускаем PuTTY, создаём SSH–подключение к серверу 192.168.0.3 (далее по тексту SSH–сессия 1), идём в пункт Tunnels:

PuTTY SSH Tunnels Config

и указываем, что локальный порт 2222 нашего компьютера должен быть поставлен в соответствие порту 22 на сервере с IP–адресом 212.212.212.212. Далее жмём кнопку «Open», авторизуемся на сервере 192.168.0.3. Затем создаём ещё одно подключение (далее по тексту SSH–сессия 2), но уже на localhost, порт 2222 и жмём кнопку «Open»:

PuTTY SSH Tunnels Connect

В результате SSH–сессия 2 будет туннелироваться (т.е. будет установлена внутри ранее установленной SSH–сессии 1). Для удалённого сервера 212.212.212.212 всё будет выглядеть так, как будто к нему подключается 111.111.111.111:

PuTTY SSH Tunnels Schema Tunnel

2. Удалённый проброс порта

В этом случае подключение внутри SSH–туннеля устанавливается в другую сторону — от удалённого сервера на наш локальный компьютер. Может быть полезно, если требуется открыть доступ к локальным сервисам нашего компьютера. Рассмотрим ту же сеть, что и в пункте 1, но для простоты предположим, что теперь у нас есть NAT:

PuTTY SSH Tunnels Schema Remote

Здесь уже у нас есть возможность подключаться через SSH напрямую к 212.212.212.212 благодаря наличию NAT–а. А вот 212.212.212.212 подключиться на 192.168.0.2 без специальных ухищрений, понятное дело, не сможет, т.к. 192.168.0.2 не подключён к Интернет непосредственно. Предположим, что пользователю, сидящему под X–ами на 212.212.212.212 нужно через remote desktop попасть на наш компьютер 192.168.0.2. Для этого в SSH–сеансе подключения с 192.168.0.2 на 212.212.212.212 нужно изменить настройки в разделе Tunnels следующим образом:

PuTTY SSH Tunnels Conf

В результате после успешной авторизации на 212.212.212.212 можно увидеть следующее:

#lsof -i -nP | grep 3333
sshd  18598   avz   11u  IPv4 592868957   TCP 127.0.0.1:3333 (LISTEN)

То есть sshd ожидает подключений на TCP–порт 3333, которые затем по SSH–туннелю будут перенаправлены на 192.168.0.2 порт 3389. И юзер сидящий за 212.212.212.212 сможет с помощью rdesktop увидеть наш рабочий стол:

PuTTY SSH Tunnels Schema Remote Tunnel

3. Socks–proxy

В этом случае мы можем использовать сервер с SSH–демоном как промежуточный (proxy). Схема сети как в случае #1 (без NAT и штатных прокси):

PuTTY SSH Tunnels Config Socks Schema

Чтобы заставить PuTTY исполнять роль socks–прокси, нужно параметры SSH–сессии с 192.168.0.2 на 192.168.0.3 изменить следующим образом:

PuTTY SSH Tunnels Config Dynamic

В результате после успешной авторизации со стороны клиента можно будет наблюдать следующее:

C:\>netstat -ano | find "1080"
  TCP    127.0.0.1:1080     0.0.0.0:0      LISTENING       2392
C:\>tasklist | find /i "2392"
putty.exe                2392 Console        0             5420 КБ

То есть putty, выполняющийся с PID–ом 2392, начинает слушать порт 1080, ожидая подключений. Далее бёрем любое приложение, умеющее работать с SOCKS–прокси, например Firefox, и указываем ему использовать наш прокси:

PuTTY SSH Tunnels Firefox

Теперь все запросы от браузера будут проходить через сервер 192.168.0.3. В логах веб–сайтов, по которым мы таким образом будем ходить, будет отображаться внешний IP–адрес нашего сервера — 111.111.111.111.

P.S. Из help–файла Putty 0.58:

Question A.10.3: What does «PuTTY» mean?

It’s the name of a popular SSH and Telnet client. Any other meaning is in the eye of the beholder. It’s been rumoured that «PuTTY» is the antonym of «getty», or that it’s the stuff that makes your Windows useful… 🙂

avz.org.ua

Памятка пользователям ssh / Хабр

abstract: В статье описаны продвинутые функций OpenSSH, которые позволяют сильно упростить жизнь системным администраторам и программистам, которые не боятся шелла. В отличие от большинства руководств, которые кроме ключей и -L/D/R опций ничего не описывают, я попытался собрать все интересные фичи и удобства, которые с собой несёт ssh.

Предупреждение: пост очень объёмный, но для удобства использования я решил не резать его на части.

Оглавление:

  • управление ключами
  • копирование файлов через ssh
  • Проброс потоков ввода/вывода
  • Монтирование удалённой FS через ssh
  • Удалённое исполнение кода
  • Алиасы и опции для подключений в .ssh/config
  • Опции по-умолчанию
  • Проброс X-сервера
  • ssh в качестве socks-proxy
  • Проброс портов — прямой и обратный
  • Реверс-сокс-прокси
  • туннелирование L2/L3 трафика
  • Проброс агента авторизации
  • Туннелирование ssh через ssh сквозь недоверенный сервер (с большой вероятностью вы этого не знаете)


Теория в нескольких словах: ssh может авторизоваться не по паролю, а по ключу. Ключ состоит из открытой и закрытой части. Открытая кладётся в домашний каталог пользователя, «которым» заходят на сервер, закрытая — в домашний каталог пользователя, который идёт на удалённый сервер. Половинки сравниваются (я утрирую) и если всё ок — пускают. Важно: авторизуется не только клиент на сервере, но и сервер по отношению к клиенту (то есть у сервера есть свой собственный ключ). Главной особенностью ключа по сравнению с паролем является то, что его нельзя «украсть», взломав сервер — ключ не передаётся с клиента на сервер, а во время авторизации клиент доказывает серверу, что владеет ключом (та самая криптографическая магия).

Генерация ключа


Свой ключ можно сгенерировать с помощью команды ssh-keygen. Если не задать параметры, то он сохранит всё так, как надо.

Ключ можно закрыть паролем. Этот пароль (в обычных графических интерфейсах) спрашивается один раз и сохраняется некоторое время. Если пароль указать пустым, он спрашиваться при использовании не будет. Восстановить забытый пароль невозможно.

Сменить пароль на ключ можно с помощью команды ssh-keygen -p.

Структура ключа


(если на вопрос про расположение ответили по-умолчанию).
~/.ssh/id_rsa.pub — открытый ключ. Его копируют на сервера, куда нужно получить доступ.
~/.ssh/id_rsa — закрытый ключ. Его нельзя никому показывать. Если вы в письмо/чат скопипастите его вместо pub, то нужно генерировать новый ключ. (Я не шучу, примерно 10% людей, которых просишь дать ssh-ключ постят id_rsa, причём из этих десяти процентов мужского пола 100%).

Копирование ключа на сервер


В каталоге пользователя, под которым вы хотите зайти, если создать файл ~/.ssh/authorized_keys и положить туда открытый ключ, то можно будет заходить без пароля. Обратите внимание, права на файл не должны давать возможность писать в этот файл посторонним пользователям, иначе ssh его не примет. В ключе последнее поле — user@machine. Оно не имеет никакого отношения к авторизации и служит только для удобства определения где чей ключ. Заметим, это поле может быть поменяно (или даже удалено) без нарушения структуры ключа.

Если вы знаете пароль пользователя, то процесс можно упростить. Команда ssh-copy-id user@server позволяет скопировать ключ не редактируя файлы вручную.

Замечание: Старые руководства по ssh упоминают про authorized_keys2. Причина: была первая версия ssh, потом стала вторая (текущая), для неё сделали свой набор конфигов, всех это очень утомило, и вторая версия уже давным давно переключилась на версии без всяких «2». То есть всегда authorized_keys и не думать о разных версиях.

Если у вас ssh на нестандартном порту, то ssh-copy-id требует особого ухищрения при работе: ssh-copy-id '-p 443 user@server' (внимание на кавычки).

Ключ сервера


Первый раз, когда вы заходите на сервер, ssh вас спрашивает, доверяете ли вы ключу. Если отвечаете нет, соединение закрывается. Если да — ключ сохраняется в файл ~/.ssh/known_hosts. Узнать, где какой ключ нельзя (ибо несекьюрно).

Если ключ сервера поменялся (например, сервер переустановили), ssh вопит от подделке ключа. Обратите внимание, если сервер не трогали, а ssh вопит, значит вы не на тот сервер ломитесь (например, в сети появился ещё один компьютер с тем же IP, особо этим страдают всякие локальные сети с 192.168.1.1, которых в мире несколько миллионов). Сценарий «злобной man in the middle атаки» маловероятен, чаще просто ошибка с IP, хотя если «всё хорошо», а ключ поменялся — это повод поднять уровень паранойи на пару уровней (а если у вас авторизация по ключу, а сервер вдруг запросил пароль — то паранойю можно включать на 100% и пароль не вводить).

Удалить известный ключ сервера можно командой ssh-keygen -R server. При этом нужно удалить ещё и ключ IP (они хранятся раздельно): ssh-keygen -R 127.0.0.1.

Ключ сервера хранится в /etc/ssh/ssh_host_rsa_key и /etc/ssh/ssh_host_rsa_key.pub. Их можно:
а) скопировать со старого сервера на новый.
б) сгенерировать с помощью ssh-keygen. Пароля при этом задавать не надо (т.е. пустой). Ключ с паролем ssh-сервер использовать не сможет.

Заметим, если вы сервера клонируете (например, в виртуалках), то ssh-ключи сервера нужно обязательно перегенерировать.

Старые ключи из know_hosts при этом лучше убрать, иначе ssh будет ругаться на duplicate key.




Передача файлов на сервер иногда может утомлять. Помимо возни с sftp и прочими странными вещами, ssh предоставляет нам команду scp, которая осуществляет копирование файла через ssh-сессию.

scp path/myfile [email protected]:/full/path/to/new/location/

Обратно тоже можно:
scp [email protected]:/full/path/to/file /path/to/put/here

Fish warning: Не смотря на то, что mc умеет делать соединение по ssh, копировать большие файлы будет очень мучительно, т.к. fish (модуль mc для работы с ssh как с виртуальной fs) работает очень медленно. 100-200кб — предел, дальше начинается испытание терпения. (Я вспомнил свою очень раннюю молодость, когда не зная про scp, я копировал ~5Гб через fish в mc, заняло это чуть больше 12 часов на FastEthernet).

Возможность копировать здорово. Но хочется так, чтобы «сохранить как» — и сразу на сервер. И чтобы в графическом режиме копировать не из специальной программы, а из любой, привычной.

Так тоже можно:


Теория: модуль fuse позволяет «экспортировать» запросы к файловой системе из ядра обратно в userspace к соответствующей программе. Это позволяет легко реализовывать «псевдофайловые системы». Например, мы можем предоставить доступ к удалённой файловой системе через ssh так, что все локальные приложения (за малым исключением) не будут ничего подозревать.

Собственно, исключение: O_DIRECT не поддерживается, увы (это проблема не sshfs, это проблема fuse вообще).

Использование: установить пакет sshfs (сам притащит за собой fuse).

Собственно, пример моего скрипта, который монтирует desunote.ru (размещающийся у меня на домашнем комьютере — с него в этой статье показываются картинки) на мой ноут:

#!/bin/bash
sshfs desunote.ru:/var/www/desunote.ru/ /media/desunote.ru -o reconnect

Делаем файл +x, вызываем, идём в любое приложение, говорим сохранить и видим:

Параметры sshfs, которые могут оказаться важными: -o reconnect (говорит пытаться пересоединиться вместо ошибок).

Если вы много работаете с данными от рута, то можно (нужно) сделать idmap:

-o idmap=user. Работает она следующим образом: если мы коннектимся как пользователь pupkin@server, а локально работаем как пользователь vasiliy, то мы говорим «считать, что файлы pupkin, это файлы vasiliy». ну или «root», если мы коннектимся как root.

В моём случае idmap не нужен, так как имена пользователей (локальное и удалённое) совпадают.

Заметим, комфортно работать получается только если у нас есть ssh-ключик (см. начало статьи), если нет — авторизация по паролю выбешивает на 2-3 подключение.

Отключить обратно можно командой fusermount -u /path, однако, если соединение залипло (например, нет сети), то можно/нужно делать это из-под рута: sudo umount -f /path.




ssh может выполнить команду на удалённом сервере и тут же закрыть соединение. Простейший пример:

ssh user@server ls /etc/

Выведет нам содержимое /etc/ на server, при этом у нас будет локальная командная строка.

Некоторые приложения хотят иметь управляющий терминал. Их следует запускать с опцией -t:
ssh user@server -t remove_command

Кстати, мы можем сделать что-то такого вида:
ssh user@server cat /some/file|awk '{print $2}' |local_app

Это нас приводит следующей фиче:

Проброс stdin/out


Допустим, мы хотим сделать запрос к программе удалённо, а потом её вывод поместить в локальный файл

ssh [email protected] command >my_file

Допустим, мы хотим локальный вывод положить удалённо

mycommand |scp — [email protected]:/path/remote_file

Усложним пример — мы можем прокидывать файлы с сервера на сервер: Делаем цепочку, чтобы положить stdin на 10.1.1.2, который нам не доступен снаружи:

mycommand | ssh [email protected] «scp — [email protected]:/path/to/file»

Есть и вот такой головоломный приём использования pipe’а (любезно подсказали в комментариях в жж):

tar -c * | ssh user@server "cd && tar -x"

Tar запаковывает файлы по маске локально, пишет их в stdout, откуда их читает ssh, передаёт в stdin на удалённом сервере, где их cd игнорирует (не читает stdin), а tar — читает и распаковывает. Так сказать, scp для бедных.


Скажу честно, до последнего времени не знал и не использовал. Оказались очень удобными.

В более-менее крупной компании часто оказывается, что имена серверов выглядят так: spb-MX-i3.extrt.int.company.net. И пользователь там не равен локальному. То есть логиниться надо так: ssh [email protected]. Каждый раз печатать — туннельных синдромов не напасёшься. В малых компаниях проблема обратная — никто не думает о DNS, и обращение на сервер выглядит так: ssh [email protected]. Короче, но всё равно напрягает. Ещё большая драма, если у нас есть нестандартный порт, и, например, первая версия ssh (привет цискам). Тогда всё выглядит так: ssh -1 -p 334 [email protected]. Удавиться. Про драму с scp даже рассказывать не хочется.

Можно прописать общесистемные alias’ы на IP (/etc/hosts), но это кривоватый выход (и пользователя и опции всё равно печатать). Есть путь короче.

Файл ~/.ssh/config позволяет задать параметры подключения, в том числе специальные для серверов, что самое важное, для каждого сервера своё. Вот пример конфига:

Host ric
        Hostname ооо-рога-и-копыта.рф
        User Администратор
        ForwardX11 yes
        Compression yes
Host home
        Hostname myhome.dyndns.org
        User vasya
        PasswordAuthentication no

Все доступные для использования опции можно увидеть в man ssh_config (не путать с sshd_config).




По подсказке UUSER: вы можете указать настройки соединения по умолчанию с помощью конструкции Host *, т.е., например:
Host *
User root
Compression yes

То же самое можно сделать и в /etc/ssh/ssh_config (не путать с /etc/ssh/sshd_config), но это требует прав рута и распространяется на всех пользователей.



Собственно, немножко я проспойлерил эту часть в примере конфига выше. ForwardX11 — это как раз оно.

Теория: Графические приложения в юникс обычно используют X-сервер (wayland в пути, но всё ещё не готов). Это означает, что приложение запускается и подключается к X-серверу для рисования. Иными словами, если у вас есть голый сервер без гуя и есть локальный x-сервер (в котором вы работаете), то вы можете дать возможность приложениям с сервера рисовать у вас на рабочем столе. Обычно подключение к удалённом X-серверу — не самая безопасная и тривиальная вещь. SSH позволяет упростить этот процесс и сделать его совсем безопасным. А возможность жать трафик позволяет ещё и обойтись меньшим трафиком (т.е. уменьшить утилизацию канала, то есть уменьшить ping (точнее, latency), то есть уменьшить лаги).

Ключики: -X — проброс X-сервера. -Y проброс авторизации.

Достаточно просто запомнить комбинацию ssh -XYC user@SERVER.
В примере выше (названия компании вымышленные) я подключаюсь к серверу ооо-рога-и-копыта.рф не просто так, а с целью получить доступ к windows-серверу. Безопасность microsoft при работе в сети мы все хорошо знаем, так что выставлять наружу голый RDP неуютно. Вместо этого мы подключаемся к серверу по ssh, а дальше запускаем там команду rdesktop:
ssh ric
rdesktop -k en-us 192.168.1.1 -g 1900x1200

и чудо, окошко логина в windows на нашем рабочем столе. Заметим, тщательно зашифрованное и неотличимое от обычного ssh-трафика.




Когда я оказываюсь в очередной гостинице (кафе, конференции), то местный wifi чаще всего оказывается ужасным — закрытые порты, неизвестно какой уровень безопасности. Да и доверия к чужим точкам доступа не особо много (это не паранойя, я вполне наблюдал как уводят пароли и куки с помощью банального ноутбука, раздающего 3G всем желающим с названием близлежащей кафешки (и пишущего интересное в процессе)).

Особые проблемы доставляют закрытые порты. То джаббер прикроют, то IMAP, то ещё что-нибудь.

Обычный VPN (pptp, l2tp, openvpn) в таких ситуациях не работает — его просто не пропускают. Экспериментально известно, что 443ий порт чаще всего оставляют, причём в режиме CONNECT, то есть пропускают «как есть» (обычный http могут ещё прозрачно на сквид завернуть).

Решением служит socks-proxy режим работы ssh. Его принцип: ssh-клиент подключается к серверу и слушает локально. Получив запрос, он отправляет его (через открытое соединение) на сервер, сервер устанавливает соединение согласно запросу и все данные передаёт обратно ssh-клиенту. А тот отвечает обратившемуся. Для работы нужно сказать приложениям «использовать socks-proxy». И указать IP-адрес прокси. В случае с ssh это чаще всего localhost (так вы не отдадите свой канал чужим людям).

Подключение в режиме sock-proxy выглядит так:

ssh -D 8080 user@server

В силу того, что чужие wifi чаще всего не только фиговые, но и лагливые, то бывает неплохо включить опцию -C (сжимать трафик). Получается почти что opera turbo (только картинки не жмёт). В реальном сёрфинге по http жмёт примерно в 2-3 раза (читай — если вам выпало несчастье в 64кбит, то вы будете мегабайтные страницы открывать не по две минуты, а секунд за 40. Фигово, но всё ж лучше). Но главное: никаких украденных кук и подслушанных сессий.

Я не зря сказал про закрытые порты. 22ой порт закрывают ровно так же, как «не нужный» порт джаббера. Решение — повесить сервер на 443-й порт. Снимать с 22 не стоит, иногда бывают системы с DPI (deep packet inspection), которые ваш «псевдо-ssl» не пустят.

Вот так выглядит мой конфиг:

/etc/ssh/sshd_config:
(фрагмент)
Port 22
Port 443

А вот кусок ~/.ssh/config с ноутбука, который описывает vpn

Host vpn
    Hostname desunote.ru
    User vasya
    Compression yes
    DynamicForward 127.1:8080
    Port 443

(обратите внимание на «ленивую» форму записи localhost — 127.1, это вполне себе законный метод написать 127.0.0.1)




Мы переходим к крайне сложной для понимания части функционала SSH, позволяющей осуществлять головоломные операции по туннелированию TCP «из сервера» и «на сервер».

Для понимания ситуации все примеры ниже будут ссылаться на вот эту схему:

Комментарии: Две серые сети. Первая сеть напоминает типичную офисную сеть (NAT), вторая — «гейтвей», то есть сервер с белым интерфейсом и серым, смотрящим в свою собственную приватную сеть. В дальнейших рассуждениях мы полагаем, что «наш» ноутбук — А, а «сервер» — Б.

Задача: у нас локально запущено приложение, нам нужно дать возможность другому пользователю (за пределами нашей сети) посмотреть на него.

Решение: проброс локального порта (127.0.0.1:80) на публично доступный адрес. Допустим, наш «публично доступный» Б занял 80ый порт чем-то полезным, так что пробрасывать мы будем на нестандартный порт (8080).

Итоговая конфигурация: запросы на 8.8.8.8:8080 будут попадать на localhost ноутбука А.

ssh -R 127.1:80:8.8.8.8:8080 [email protected]

Опция -R позволяет перенаправлять с удалённого (Remote) сервера порт на свой (локальный).
Важно: если мы хотим использовать адрес 8.8.8.8, то нам нужно разрешить GatewayPorts в настройках сервера Б.
Задача. На сервере «Б» слушает некий демон (допустим, sql-сервер). Наше приложение не совместимо с сервером (другая битность, ОС, злой админ, запрещающий и накладывающий лимиты и т.д.). Мы хотим локально получить доступ к удалённому localhost’у.

Итоговая конфигурация: запросы на localhost:3333 на ‘A’ должны обслуживаться демоном на localhost:3128 ‘Б’.

ssh -L 127.1:3333:127.1:3128 [email protected]

Опция -L позволяет локальные обращения (Local) направлять на удалённый сервер.

Задача: На сервере «Б» на сером интерфейсе слушает некий сервис и мы хотим дать возможность коллеге (192.168.0.3) посмотреть на это приложение.

Итоговая конфигурация: запросы на наш серый IP-адрес (192.168.0.2) попадают на серый интерфейс сервера Б.

ssh -L 192.168.0.2:8080:10.1.1.1:80 [email protected]

Вложенные туннели


Разумеется, туннели можно перенаправлять.

Усложним задачу: теперь нам хочется показать коллеге приложение, запущенное на localhost на сервере с адресом 10.1.1.2 (на 80ом порту).

Решение сложно:
ssh -L 192.168.0.2:8080:127.1:9999 [email protected] ssh -L 127.1:9999:127.1:80 [email protected]

Что происходит? Мы говорим ssh перенаправлять локальные запросы с нашего адреса на localhost сервера Б и сразу после подключения запустить ssh (то есть клиента ssh) на сервере Б с опцией слушать на localhost и передавать запросы на сервер 10.1.1.2 (куда клиент и должен подключиться). Порт 9999 выбран произвольно, главное, чтобы совпадал в первом вызове и во втором.

Реверс-сокс-прокси

Если предыдущий пример вам показался простым и очевидным, то попробуйте догадаться, что сделает этот пример:
ssh -D 8080 -R 127.1:8080:127.1:8080 [email protected] ssh -R 127.1:8080:127.1:8080 [email protected]

Если вы офицер безопасности, задача которого запретить использование интернета на сервере 10.1.1.2, то можете начинать выдёргивать волосы на попе, ибо эта команда организует доступ в интернет для сервера 10.1.1.2 посредством сокс-прокси, запущенного на компьютере «А». Трафик полностью зашифрован и неотличим от любого другого трафика SSH. А исходящий трафик с компьютера с точки зрения сети «192.168.0/24» не отличим от обычного трафика компьютера А.




Если к этому моменту попа отдела безопасности не сияет лысиной, а ssh всё ещё не внесён в список врагов безопасности номер один, вот вам окончательный убийца всего и вся: туннелирование IP или даже ethernet. В самых радикальных случаях это позволяет туннелировать dhcp, заниматься удалённым arp-спуфингом, делать wake up on lan и прочие безобразия второго уровня.

Подробнее описано тут: www.khanh.net/blog/archives/51-using-openSSH-as-a-layer-2-ethernet-bridge-VPN.html

(сам я увы, таким не пользовался).

Легко понять, что в таких условиях невозможно никаким DPI (deep packet inspection) отловить подобные туннели — либо ssh разрешён (читай — делай что хочешь), либо ssh запрещён (и можно смело из такой компании идиотов увольняться не ощущая ни малейшего сожаления).


Если вы думаете, что на этом всё, то…… впрочем, в отличие от автора, у которого «снизу» ещё не написано, читатель заранее видит, что там снизу много букв и интриги не получается.

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

Для начала о простом пробросе авторизации.

Повторю картинку:

Допустим, мы хотим подключиться к серверу 10.1.1.2, который готов принять наш ключ. Но копировать его на 8.8.8.8 мы не хотим, ибо там проходной двор и половина людей имеет sudo и может шариться по чужим каталогам. Компромиссным вариантом было бы иметь «другой» ssh-ключ, который бы авторизовывал [email protected] на 10.1.1.2, но если мы не хотим пускать кого попало с 8.8.8.8 на 10.1.1.2, то это не вариант (тем паче, что ключ могут не только поюзать, но и скопировать себе «на чёрный день»).

ssh предлагает возможность форварда ssh-агента (это такой сервис, который запрашивает пароль к ключу). Опция ssh -A пробрасывает авторизацию на удалённый сервер.

Вызов выглядит так:

ssh -A [email protected] ssh [email protected]

Удалённый ssh-клиент (на 8.8.8.8) может доказать 10.1.1.2, что мы это мы только если мы к этому серверу подключены и дали ssh-клиенту доступ к своему агенту авторизации (но не ключу!).

В большинстве случаев это прокатывает.

Однако, если сервер совсем дурной, то root сервера может использовать сокет для имперсонализации, когда мы подключены.

Есть ещё более могучий метод — он превращает ssh в простой pipe (в смысле, «трубу») через которую насквозь мы осуществляем работу с удалённым сервером.

Главным достоинством этого метода является полная независимость от доверенности промежуточного сервера. Он может использовать поддельный ssh-сервер, логгировать все байты и все действия, перехватывать любые данные и подделывать их как хочет — взаимодействие идёт между «итоговым» сервером и клиентом. Если данные оконечного сервера подделаны, то подпись не сойдётся. Если данные не подделаны, то сессия устанавливается в защищённом режиме, так что перехватывать нечего.

Эту клёвую настройку я не знал, и раскопал её redrampage.

Настройка завязана на две возможности ssh: опцию -W (превращающую ssh в «трубу») и опцию конфига ProxyCommand (опции командной строки, вроде бы нет), которая говорит «запустить программу и присосаться к её stdin/out». Опции эти появились недавно, так что пользователи centos в пролёте.

Выглядит это так (циферки для картинки выше):

.ssh/config:

Host raep
     HostName 10.1.1.2
     User user2
     ProxyCommand ssh -W %h:%p [email protected]

Ну а подключение тривиально: ssh raep.

Повторю важную мысль: сервер 8.8.8.8 не может перехватить или подделать трафик, воспользоваться агентом авторизации пользователя или иным образом изменить трафик. Запретить — да, может. Но если разрешил — пропустит через себя без расшифровки или модификации. Для работы конфигурации нужно иметь свой открытый ключ в authorized_keys как для [email protected], так и в [email protected]

Разумеется, подключение можно оснащать всеми прочими фенечками — прокидыванием портов, копированием файлов, сокс-прокси, L2-туннелями, туннелированием X-сервера и т.д.


Разумеется, в посте про туннели должен быть туннель, а в любой успешной статье — секретный ингредиент всеобщей популярности. Держите:

Как создать туннели SSH

Помимо отправки данных ssh, протокол ssh может туннелировать другой трафик между двумя хостами. Наиболее распространенные туннели являются удаленными и локальными. Знание того, как раскрутить ssh-туннель, может помочь вам достичь недоступных в других случаях сетей и систем.

Эти примеры работают из приглашения linux или терминала macOS. В Windows можно сделать то же самое, используя такие приложения, как putty или mobaXterm.

Локальный SSH-порт Переадресация

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

Прокси
для удаленного сервера

На изображении выше, синий хост не может достичь http://192.168.0.3 , но может ssh до 192.168.0.2. Следующая команда ssh, выполняемая на синем хосте , позволит синему хосту достичь красного хоста.

Теперь синий хост может открыть браузер и перейти по адресу http: // localhost: 8080 и получить веб-страницу, размещенную на 192.168.0.3.

Местный порт Форвард

На изображении выше синий хост хочет подключиться к красному хосту через порт 80, но между ними есть межсетевой экран, который это отрицает.Поскольку синий хост может подключаться по ssh к красному хосту, мы можем создать локальный порт, перенаправляющий туннель ssh для доступа к этому порту.

Команда на голубом хосте будет:

Теперь, когда синий хост открывает браузер и переходит на http: // localhost: 8080 , они смогут видеть все, что имеет красный сервер на порту 80.

Синтаксис переадресации локальных портов

Этот синтаксис для создания локального туннеля переадресации ssh-порта:

  ssh -L : :    

Переадресация удаленного порта SSH

В этом сценарии мы создаем обратный туннель SSH.Здесь мы можем инициировать ssh-туннель в одном направлении, а затем использовать этот туннель для создания ssh-туннеля обратно. Это может быть полезно, когда вы помещаете дрон-компьютер в сеть и хотите, чтобы он «позвонил домой». Затем, когда он звонит домой, вы можете подключиться к нему через установленный ssh-туннель.

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

Синий хост инициирует ssh-туннель следующим образом:

Это открывает порт 2222 на зеленом хосте, который затем перенаправляет его на порт 22 на синем хосте. Таким образом, если зеленый хост будет подключен к ssh через порт 2222, он достигнет синего хоста.

Зеленый хост теперь может использовать SSH для голубого хоста:

Использование опции -N

При использовании ssh вы можете указать флаг -N , который сообщает ssh, что вам не нужно отправлять какие-либо команды через соединение ssh, когда оно установлено.Этот параметр часто используется при создании туннелей, поскольку нам часто не требуется получать подсказку.

Autossh

Команда autossh используется для добавления постоянства в ваши туннели. Задача состоит в том, чтобы убедиться, что ваше ssh-соединение установлено, а если нет, создайте его.

Вот команда autossh, которую вы можете распознать.

Опция -i /home/blueuser/.ssh/id_rsa говорит об использовании сертификата для аутентификации этого ssh-соединения. Проверьте этот пост, чтобы узнать больше о сертификатах SSH.

Теперь, когда ваш туннель выйдет из строя, он автоматически попытается восстановить соединение и продолжит попытки, пока он не будет успешным. Чтобы сделать его постоянным после перезагрузки, добавьте команду ssh в качестве задания cron.

Статьи по теме

,

SSH Tunnel

На этой странице описывается SSH туннелирование (также называемое SSH-переадресация порта ), как его можно использовать для входа во внутреннюю корпоративную сеть из Интернета и как предотвратить SSH-туннели в брандмауэре. Туннелирование SSH является мощным инструментом, но им также можно злоупотреблять. Управление туннелированием особенно важно при перемещении сервисов в Amazon AWS или других сервисов облачных вычислений.

Что такое туннель SSH?

SSH туннелирование — это метод передачи произвольных сетевых данных через зашифрованное соединение SSH.Его можно использовать для добавления шифрования в устаревшие приложения. Его также можно использовать для реализации VPN (виртуальных частных сетей) и доступа к службам интрасети через брандмауэры.

SSH — это стандарт для безопасного удаленного входа и передачи файлов по ненадежным сетям. Он также обеспечивает способ защиты трафика данных любого приложения с использованием переадресации портов, в основном туннелируя любой порт TCP / IP через SSH. Это означает, что трафик данных приложения направляется в зашифрованное соединение SSH, поэтому его нельзя перехватить или перехватить во время передачи.Туннелирование SSH позволяет добавить сетевую безопасность к устаревшим приложениям, которые изначально не поддерживают шифрование.

На рисунке представлен упрощенный обзор туннелирования SSH. Безопасное соединение через ненадежную сеть устанавливается между клиентом SSH и сервером SSH. Это SSH-соединение зашифровано, защищает конфиденциальность и целостность и аутентифицирует взаимодействующие стороны.

Соединение SSH используется приложением для подключения к серверу приложений. При включенном туннелировании приложение связывается с портом на локальном хосте, который прослушивает клиент SSH.Затем SSH-клиент пересылает приложение по зашифрованному туннелю на сервер. Затем сервер подключается к реальному серверу приложений — обычно на той же машине или в том же центре обработки данных, что и сервер SSH. Таким образом, связь с приложением обеспечивается без необходимости изменения рабочих процессов приложения или конечного пользователя.

Кто использует SSH туннелирование?

Недостатком является то, что любой пользователь, который может войти на сервер, может включить переадресацию портов. Это широко используется внутренними ИТ-специалистами для входа на свои домашние машины или серверы в облаке, перенаправления порта с сервера обратно в корпоративную интрасеть на свою рабочую машину или подходящий сервер.

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

Чтобы увидеть, как настроить туннель SSH, см. Этот пример. Туннелирование часто используется вместе с ключами SSH и аутентификацией с открытым ключом для полной автоматизации процесса.

Преимущества SSH-туннелирования для предприятий

Туннели SSH широко используются во многих корпоративных средах, в которых в качестве бэкэндов приложений используются мэйнфрейм-системы.В этих средах сами приложения могут иметь очень ограниченную встроенную поддержку безопасности. Используя туннелирование, можно достичь соответствия SOX, HIPAA, PCI-DSS и другим стандартам без необходимости модификации приложений.

Во многих случаях эти приложения и серверы приложений таковы, что внесение в них изменений в коде может быть нецелесообразным или чрезмерно дорогим. Исходный код может быть недоступен, поставщик может больше не существовать, продукт может не поддерживаться или команда разработчиков может больше не существовать.Добавление оболочки безопасности, такой как туннелирование SSH, предоставило экономичный и практичный способ добавить безопасность для таких приложений. Например, целые сети банкоматов по всей стране используют туннелирование для обеспечения безопасности.

SSH-туннелирование в портфеле корпоративных рисков

Как бы ни было полезно SSH-туннелирование, оно также создает риск, который необходимо решать корпоративным командам ИТ-безопасности. Соединения SSH защищены надежным шифрованием. Это делает их содержимое невидимым для большинства развернутых решений по мониторингу сети и фильтрации трафика.Эта невидимость несет в себе значительную потенциальную опасность, если она используется в злонамеренных целях, таких как удаление данных. Киберпреступники или вредоносные программы могут использовать туннели SSH для сокрытия своих несанкционированных сообщений или для кражи украденных данных из целевой сети.

При атаке с использованием обратного туннелирования SSH злоумышленник настраивает сервер за пределами целевой сети (например, в Amazon AWS). Как только злоумышленник окажется в целевой системе, он подключится к внешнему SSH-серверу изнутри. Большинство организаций разрешают исходящие соединения SSH, по крайней мере, если у них есть серверы в публичном облаке.Это соединение SSH настроено с параметром, который позволяет перенаправлять порт TCP с порта на внешнем сервере на порт SSH на сервере во внутренней сети. Настройка этого обратного туннеля SSH требует одной однострочной команды внутри, и это может быть легко автоматизировано. Большинство брандмауэров практически не защищают от него.

Существует несколько широко известных и задокументированных случаев вредоносного ПО, использующего протокол SSH в качестве средства скрытия экфильтрации данных и каналов команд.Несколько экземпляров вредоносного ПО активно собирали ключи SSH. Захваченные и собранные ключи SSH также были проданы на хакерских форумах.

В сочетании с атаками с использованием неуправляемых ключей SSH туннелирование SSH позволяет злоумышленнику использовать украденные ключи SSH для интрасети из общедоступного Интернета .

SSH туннельные атаки также могут быть использованы для сокрытия источника атаки . Хакеры часто отскакивают атаки от систем и устройств, которые позволяют перенаправлению портов SSH скрывать свои следы.Это позволяет им обнаруживать уязвимости, пробовать различные учетные данные для входа в систему или запускать инструменты атаки на электронную почту, Интернет, телефонию и любые другие протоколы. Пропуск атаки через дюжину случайных устройств через зашифрованные туннели и другой трафик делает его практически не отслеживаемым. Akamai задокументировала миллионы IoT-устройств, используемых таким образом.

Противодействие этим рискам требует возможности мониторинга, контроля и аудита зашифрованных соединений SSH. Для предотвращения отскока требуется правильная настройка и усиление операционных систем IoT.

Следует также отметить, что туннельные атаки не являются специфическими для SSH — компетентный программист может написать инструмент для туннелирования портов за несколько часов и может запустить его на любой машине во внутренней сети. Это может сделать любой ноутбук или другое устройство во внутренней сети — ему просто нужно иметь возможность общаться с какой-либо (любой) службой в Интернете. Такой инструмент может быть создан для работы через SSL / TLS, может эмулировать HTTP или может работать через UDP и использовать пакеты, похожие на запросы и ответы DNS.SSH просто облегчает работу непрограммистов. Вы можете защитить только от туннельных атак против людей, которые могут запускать программное обеспечение изнутри или подключать любое устройство к внутренней сети, только разрешая протоколы, которые вы можете проверить через брандмауэр.

Как настроить туннель SSH

См. Страницу примера конфигурации для получения подробных инструкций по настройке. Опции командной строки SSH и страницы файла конфигурации сервера SSH также могут быть полезны.

Переадресация SSH-портов — Пример, команда, конфигурация сервера

Что такое переадресация SSH-портов, или SSH-туннелирование?

Переадресация портов SSH — это механизм в SSH для туннелирования портов приложений с клиентского компьютера на серверный компьютер или наоборот. Он может использоваться для , добавляя шифрование к унаследованным приложениям , , проходящим через брандмауэры , и некоторые системные администраторы и ИТ-специалисты используют его для , открывая внутренние двери во внутреннюю сеть со своих домашних компьютеров.Хакеры и вредоносные программы также могут использовать его для открытия доступа из Интернета во внутреннюю сеть. См. Страницу туннелирования SSH для более широкого обзора.

Локальная пересылка

Локальная переадресация используется для переадресации порта с клиентского компьютера на серверный компьютер. По сути, клиент SSH прослушивает соединения на настроенном порту, а когда он получает соединение, он туннелирует соединение с сервером SSH. Сервер подключается к настроенному порту назначения, возможно, на другом компьютере, чем сервер SSH.

Типичное использование для локальной переадресации портов включает в себя:

  • Сеансы туннелирования и передачи файлов через серверы скачков

  • Подключение к службе во внутренней сети извне

  • Подключение к удаленной общей папке через Интернет

Довольно много организаций для всех входящих SSH-доступа через один сервер перехода. Сервер может представлять собой стандартную коробку Linux / Unix, обычно с некоторой дополнительной защитой, обнаружением вторжений и / или журналированием, или это может быть коммерческое решение для сервера прыжков.

Многие серверы перехода разрешают переадресацию входящих портов после проверки подлинности соединения. Такая переадресация портов удобна, поскольку позволяет технически подкованным пользователям использовать прозрачные внутренние ресурсы. Например, они могут перенаправить порт на своем локальном компьютере на веб-сервер корпоративной интрасети, на порт IMAP внутреннего почтового сервера, на порты 445 и 139 локального файлового сервера, на принтер, в репозиторий управления версиями или почти на любая другая система во внутренней сети.Часто порт туннелируется на порт SSH на внутренней машине.

В OpenSSH перенаправление локального порта настраивается с использованием опции -L :

  ssh -L 80: intra.example.com: 80 gw.example.com  

В этом примере открывается соединение с ГВт .example.com сервер перехода и перенаправляет любое соединение с портом 80 на локальной машине на порт 80 на intra.example.com .

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

  ssh -L 127.0.0.1:80:intra.example.com:80 gw.example.com  

LocalForward Опция в файле конфигурации клиента OpenSSH может использоваться для настройки переадресации без указания ее в командной строке.

Удаленная пересылка

В OpenSSH переадресация удаленных портов SSH указывается с использованием опции -R . Например:

  ssh -R 8080: localhost: 80 public.example.com  

Это позволяет любому удаленному серверу подключаться к TCP-порту 8080 на удаленном сервере. Затем соединение будет туннелировано обратно к клиентскому хосту, а затем клиент устанавливает TCP-соединение с портом 80 на localhost . Любое другое имя хоста или IP-адрес можно использовать вместо localhost , чтобы указать хост для подключения.

Этот конкретный пример будет полезен для предоставления кому-либо извне доступа к внутреннему веб-серверу.Или выставление внутреннего веб-приложения в общедоступный Интернет. Это может сделать сотрудник, работающий дома, или злоумышленник.

По умолчанию OpenSSH позволяет подключаться только к удаленным перенаправленным портам с хоста сервера. Однако опция GatewayPorts в файле конфигурации сервера sshd_config может использоваться для управления этим. Возможны следующие альтернативы:

  GatewayPorts №  

Это предотвращает подключение к перенаправленным портам извне серверного компьютера.

  GatewayPorts yes  

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

  GatewayPorts определено клиентами  

Это означает, что клиент может указать IP-адрес, с которого разрешены подключения к порту. Синтаксис этого:

  ssh -R 52.194.1.73:8080:localhost:80 host147.aws.example.com  

В этом примере только соединения с IP-адресом 52.194.1.73 к порту 8080 разрешены.

OpenSSH также позволяет перенаправленному удаленному порту быть заданным как 0. В этом случае сервер будет динамически выделять порт и сообщать об этом клиенту. При использовании с опцией -O forward клиент печатает номер выделенного порта в стандартный вывод.

Открытие бэкдоров на предприятии

Удаленная переадресация портов SSH обычно используется сотрудниками для открытия бэкдоров на предприятии. Например, сотрудник может настроить получение сервера бесплатного уровня от Amazon AWS и войти из офиса на этот сервер, указав удаленную переадресацию с порта на сервере на какой-либо сервер или приложение во внутренней корпоративной сети.Можно указать несколько удаленных переадресаций, чтобы открыть доступ к нескольким приложениям.

Сотрудник также установит GatewayPorts да на сервере (большинство сотрудников не имеют фиксированных IP-адресов дома, поэтому они не могут ограничить IP-адрес).

Например, следующая команда открывает доступ к внутренней базе данных Postgres на порту 5432 и внутреннему порту SSH на порту 2222.

  ssh -R 2222: d76767.nyc.example.com: 22 -R 5432: postgres3. NYC.example.com:5432 aws4.mydomain.net  

Конфигурация на стороне сервера

Опция AllowTcpForwarding в файле конфигурации сервера OpenSSH должна быть включена на сервере, чтобы разрешить переадресацию портов. По умолчанию пересылка разрешена. Возможные значения для этой опции: да или все , чтобы разрешить всю пересылку TCP, нет , чтобы запретить всю пересылку TCP, локальная , чтобы разрешить локальные пересылки, и удаленная , чтобы разрешить удаленную пересылку.

Другой интересный вариант — AllowStreamLocalForwarding , который можно использовать для пересылки доменных сокетов Unix. Он допускает те же значения, что и AllowTcpForwarding . По умолчанию да .

Например:

  AllowTcpПересылка удаленного
    AllowStreamLocalForwarding no  

Опция конфигурации GatewayPorts , как описано выше, также влияет на переадресацию удаленных портов. Возможные значения: , не (разрешены только локальные соединения с хоста сервера; по умолчанию), , да (любой пользователь в Интернете может подключаться к удаленным перенаправленным портам) и , указанное клиентом (клиент может указать IP-адрес, который может подключаться, любой может если не указано).

Как предотвратить переадресацию порта SSH с обходных брандмауэров

Рекомендуется явно отключить переадресацию портов, когда в этом нет необходимости. Если переадресация портов включена, это может подвергнуть организацию угрозам безопасности и бэкдорам. Например, если сервер, предназначенный только для передачи файлов SFTP, разрешает переадресацию портов, эти переадресации могут использоваться для получения непреднамеренного доступа во внутреннюю сеть из интрасети.

Проблема в том, что на практике переадресация портов может быть предотвращена только сервером или брандмауэром.Предприятие не может контролировать все серверы в Интернете. Управление на основе брандмауэра также может быть сложным, так как большинство организаций имеют серверы в Amazon AWS и других облачных сервисах, и доступ к этим серверам обычно осуществляется через SSH.

Дополнительная информация

.
izcet / ssh_tunnel: более подробное описание того, как настроить SSH-туннель между несколькими системами Unix. перейти к содержанию Зарегистрироваться
  • Почему GitHub? Особенности →
    • Обзор кода
    • Управление проектами
    • Интеграция
    • Действия
    • Пакеты
    • Безопасность
    • Управление командой
    • Хостинг
    • Мобильный
    • Отзывы клиентов →
    • Безопасность →
  • команда
  • предприятие
  • Проводить исследования
    • Исследуйте GitHub →
    учиться и внести свой вклад
    • Темы
    • Коллекции
    • Тенденции
    • Learning Lab
    • Руководства с открытым исходным кодом
    Общайтесь с другими
    • События
    • Общественный форум
    • G
.