Всем доброго времени суток!
Уже на следующей неделе у нас стартует очередная группа «Администратор 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»!
Автор: MaxRokatansky