Всем доброго времени суток!

Уже на следующей неделе у нас стартует очередная группа «Администратор Linux», в связи с чем мы провели ряд мероприятий. Одно из них — открытый урок на тему «SSH/NC/Socat: tips & tricks». На нём мы вспомнили, что такое ssh, его историю и предназначение. Рассмотрели различные варианты его использования: remote, local port forwarding, secure copy, socks proxy, reverse proxy. Попробовали на деле в виртуальной лаборатории утилиты nc и socat.

Вебинар провёл опытный системный администратор Владимир Дроздецкий — разработчик инфраструктуры letundra.com, exposcan.ru, crispmessenger.com.

Предлагаем вашему вниманию подробное описание прошедшего мероприятия.


Вспоминаем, что такое SSH

SSH (англ. Secure Shell) — «безопасная оболочка», сетевой протокол прикладного уровня. Он позволяет удалённо управлять операционной системой и выполнять туннелирование TCP-соединений (к примеру, для передачи файлов). По своей функциональности SSH схож с протоколами Telnet и rlogin, однако имеет отличия от них, так как шифрует весь трафик, включая и передаваемые пароли. Спецификация протокола SSH-2 содержится в RFC 4251.

Давайте посмотрим различные варианты использования SSH, как стандартные, так и нестандартные. В этом нам поможет следующий стенд:



Стенд представляет четыре виртуальных машины, которые находятся за файрволом. Все действия будем производить с машины Node-1.

Создание ключа SSH

Для того чтобы использовать ключ SSH, сначала необходимо его создать. Для этого подойдёт специальная утилита, которая есть абсолютно в любом дистрибутиве Linux:

ssh-keygen -t RSA -N otuslinux -f ~/.ssh/otus

  • -t — какой алгоритм шифрования использовать;
  • -N — ключ шифрования (удобный аргумент, если необходимо создать ключ без шифрования и ответов на различные запросы ssh-keygen);
  • -f — в какой файл сохранить ключ.

SSH-настройки ssh-server

Для дальнейшей работы потребуется отредактировать файл /etc/ssh/sshd_config и перезапустить ssh server. Тут следует обратить внимание на следующие опции:

RSAAuthentication yes (разрешена ли аутентификация по RSA);
PubkeyAuthentication yes (разрешена ли аутентификацию по ключу);
AuthorizedKeysFile %h/.ssh/authorized_keys (путь к публичной части ключа);
PasswordAuthentication yes (разрешена ли аутентификация).

Чтобы скопировать ключ на сервер, действуем следующим образом:

ssh-copy-id -i /path/to/pub/key user@server (копируем публичную часть ключа на удалённый сервер, публичный ключ будет скопирован по пути в файл %h/.ssh/authorized_keys)

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

eval $(ssh-agent -s) (eval является частью POSIX. Его интерфейс также может быть оболочкой. Ключ в агенте будет храниться уже в расшифрованном виде).

ssh-add ~/.ssh/our_private_key (Добавляем приватный ключ).

В данном случае:

  • -i — указываем расположение публичного ключа;
  • user — имя пользователя на удалённом сервере;
  • server — ip или dns целевого сервера.

Для простоты подключения к удалённому серверу параметры подключения мы можем описать в ssh config file, который располагается по пути ~/.ssh/config

Таким образом, получаем следующий SSH config file:

Host myserver
HostName ip/hostname Port 22/???
User username
IdentityFile ~/.ssh/id_rsa

Здесь всё просто:

  • Host — имя нашего подключения;
  • HostName — имя сервера;
  • Port — порт ssh
  • User — имя пользователя;
  • IdentityFile — ssh-ключ.

SSH SCP

Идём дальше. Самый простой вариант использования SSH — скопировать файл из одной машины на удаленную. Для этого используем утилиту SCP (Secure Copy Protocol). С её помощью можно скопировать каталог или файл как с локального сервера на удалённый, так и наоборот:

scp test.txt username@server:/some/directory (Копирование файла с локального сервера на удалённый сервер).
scp username@server:test.txt /some/directory (Копирование файла с удалённого сервера на локальный).
scp -r dir_name username@server:/some/directory (Копирование папки с локального сервера на удалённый).

Здесь:

  • username — имя пользователя;
  • server — адрес сервера;
  • /some/server — директория, куда копируем;
  • dir_name — имя папки;
  • -r — использовать рекурсивно.

SSH tunnel, proxy

Теперь давайте рассмотрим вариант, как пробросить на локальную машину порт с удалённой. Возьмём для примера классический случай, то есть связку, когда у нас есть «злой безопасник» и один сервер с веб-приложением, в мир смотрит порт ssh и https, а нам очень хочется подключиться к MySQL-серверу.

Итак:

ssh -f -N -L 9906:127.0.0.1:3306 user@server (Как раз наш случай с MySQL)

В результате мы можем подключиться к локальному порту 9906 клиентом mysql и попасть на наш “секьюрный” сервер.

ssh -D 8080 -q -C -N -f servername (Проксирование трафика через SOCKS через порт 8080)

Данной командой мы создаём socks5 прокси-сервер посредством ssh. Для проверки его работоспособности мы можем использовать следующую команду:

curl -x socks5h://server-with-proxy:8080 https://test.domain

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

ssh -f -N -R 2255:localhost:22 username@servername (проброс с удалённого сервера на локальный).

На удалённом сервер откроется 2255 порт, который будет перенаправлен в 22 порт нашего сервера за натом. Для подключения к такому серверу мы можем воспользоваться командой:

ssh -p 2255 username@localhost

Обратите внимание, что:

  • -f — отправит ssh в background;
  • -N — не выполнять команду на удалённом хосте;
  • -L — проброс локального порта (локальный порт: локальная машина: удалённый порт);
  • -R — порт на удаленной машине;
  • -q — тихий режим;
  • -D — определяет локальную динамическую маршрутизацию портов уровня приложения;
  • -C — запрос на сжатие данных.

Netcat (nc)

Следующая наша остановка — Netcat — утилита Unix, позволяющая устанавливать соединения TCP и UDP, принимать оттуда данные и передавать их. Несмотря на свою полезность и простоту, данная утилита не входит ни в какой стандарт и не поставляется в составе какого-либо дистрибутива. Соответственно, её приходится устанавливать руками.

Одна из интересных особенностей Netcat (nc) — возможность просканировать порты:

nc -vn ipaddress 22 (сканирование одного порта);
nc -v ipaddress 10-55 (сканирование диапазона портов);
nc -l 4444 (открываем и слушаем порт 4444);
nc servername 4444 (подключаемся к серверу по нужному порту).

После открытия порта и подключения к нему у нас получается небольшой сетевой чатик =).

Далее мы рассмотри возможность передачи файлов при помощи утилиты nc. Для этого нам поможет следующая команда:

cat test_file | pv -b | nc -l 4444 (открываем порт и через пайп передаем в него файл, утилита pv с ключем -b используется для отображения прогресса передачи файла в байтах).

nc servername 4444 | pv -b > filename (подключаемся к серверу для получения файла, pv -b используется аналогично).

Мы можем усложнить наш пайп путём добавления архивации файлов на лету:

tar -czf - /path/to/ | pv -b | nc -l 4444 (архивирование на лету папки и отправка);
nc servername 4444 | pv -b > file.tar.gz (получение отправленного архива).

Не очень очевидная возможность nc — это создание просто http-сервера.

while true; do nc -lp 80 < index.html; done 

Обратите внимание, что для того чтобы использовать 80 порт, необходимо обладать root-правами.

Также обратите внимание, что:

  • -l — указываем режим работы listen;
  • -n — не использовать запросы к DNS;
  • -v — подробный вывод.

Socat

Тоже полезная утилита, позволяющая устанавливать TCP-соединения между машинами, перенаправлять порты и пр. Работает по принципу Netcat: открывает два двунаправленных соединения, может передавать данные, потоки и т. д. Однако у неё есть одна интересная особенность. Например, с помощью Socat мы можем смапить COM-порты в ТСР-порты и т. д.

Примеры работы Socat:

socat -u FILE:file_name TCP-LISTEN:5778,reuseaddr #отправка файла;
socat -u TCP:192.168.1.48:5778 STDOUT | pv -r > file_name #получение файла;
socat TCP-LISTEN:80,fork TCP:ubuntunode-4:80 #перенаправление порта удалённого сервера на локальный порт;
socat TCP-LISTEN:1234,reuseaddr EXEC:/bin/bash #Открываем remote shell =);
socat - TCP:server_with_remote_shell:1234 #Подключаемся к remote shell удалённого сервера.

Небольшая расшифровочка:

  • -u — использование однонаправленного режима;
  • FILE — указываем, что используем файл;
  • TCP-LISTEN — слушаем tcp-порт;
  • reuseaddr — разрешает другим сокетам связываться с этим же адресом, даже если он используется;
  • fork — после установления соединения канал обрабатывается в дочернем процессе;
  • TCP — тип соединения.

Стоит ли теперь смотреть видеоверсию?

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

Мы же, в свою очередь, не прощаемся и приглашаем вас на курс «Администратор Linux»!

Комментарии (1)


  1. conformist
    24.01.2019 00:19

    Я понимаю, что лекция для новичков и опытным пользователям здесь будет мало интересного, но хотелось бы отметить, что вводя эти «магические» команды в терминал стоило бы больше внимания уделить объяснению, что же конкретно происходит. Получилось же так: смотрите, что я умею и публика ахнула. Хорошие вопросы задавали пользователи, но ответы на них были настолько поверхностные и непонятные, что складывается впечатление, что автор плохо подготовил материал для подачи не задав себе вопросов по ходу лекции, которые могут возникнуть и как на них ответить. Всё равно спасибо.