В этой статье мы поговорим о полезных приемах и командах при работе с SSH. А именно:
- Как использовать двухфакторную аутентификацию для SSH-подключений.
- Безопасное использование «проброса ключа» (agent forwarding).
- Завершение зависшей сессии.
- Оставляем терминал открытым при выходе или разрыве связи.
- Расшариваем удаленный терминал с другом (без Zoom!).
Многофакторная аутентификация
Для того, чтобы активировать ее, есть целых пять способов.
1. Обновляем OpenSSH и используем аппаратные токены. В феврале этого года в OpenSSH была добавлена поддержка токенов FIDO U2F (Universal Second Factor). Что сказать — это отлично, но есть один нюанс.
Дело в том, что обновление добавляет новые типы ключей для поддержки токенов. Но использовать эту функцию можно лишь при обновлении клиента и сервера до версии 8.2 или более поздней. Текущую версию клиента можно проверить — для этого есть команда ssh -V. Что касается удаленного сервера, то здесь стоит воспользоваться nc [servername] 22.
Кроме того, были добавлены два новых типа ключей — ecdsa-sk и ed25519-sk. Для них же есть и сертификаты. Для того, чтобы создать ключевые файлы, необходимо вставить токен и выполнить команду
$ ssh-keygen -t ecdsa-sk -f ~/.ssh/id_ecdsa_sk.
Что она делает? Создает открытый и закрытый ключи, которые привязаны к U2F токену. Закрытый ключ на токене используется для расшифровки закрытого ключа, который хранится на диске.
Еще одна возможность — задание в качестве второго фактора пароль для ключевых файлов. Дело в том, что OpenSSH работает с еще одним вариантом генерации — sk. Таким образом, ключевые файлы хранятся на аппаратном токене, и они всегда с собой. Для того, чтобы создать резидентный ключ, нужно воспользоваться командой:
$ ssh-keygen -t ecdsa-sk -O resident -f ~/.ssh/id_ecdsa_sk.
Ну а для того, чтобы перенести ключевой файл на новую машину, требуется вставить носитель и выполнить команду $ ssh-add -K. Помните — токен нужно активировать при подключении.
2. Используем PIV+PKCS11 и Yubikey. В том случае, если нужно подключаться к машинам, где установлены более ранние версии SSH-сервера, есть еще одна возможность. Вот подробная инструкция U2F+SSH с PIV/PKCS11. Немного сложно, но оно стоит того.
3. Третий способ — использование yubikey-agent. Вот сам SSH-агент для Yubikeys, его создал Filipo Valsorda.
4. Touch ID и sekey. Еще один способ заключается в использовании Sekey — агента с открытым исходным кодом. Он сохраняет закрытые ключи в системе secure enclave для MacOS и дает возможность запускать функцию подписания посредством Touch ID.
5. Наконец, использование Single Sign On SSH. Вот здесь размещена инструкция по настройке. Преимущество Single Sign On SSH в том, что пользователь получает возможность использовать политику безопасности поставщика учетных записей, включая поддержку многофакторной аутентификации.
Безопасный проброс ключа (agent forwarding)
Для чего используется проброс ключа? Для доступа удаленного хоста к локальному SSH-агенту пользователя. Дело в том, что когда SSH-клиент использует проброс ключа (чаще всего активируется ssh -A), то в ходе соединения присутствуют 2 канала. Первый — это интерактивная сессия пользователя, второй — канал проброса ключа.
Локальный SSH-агент создает IPC-сокет, который подключается через этот канал к удаленному хосту. Это достаточно опасно, поскольку у пользователя с правами root а удаленном хосте есть доступ к локальному SSH-агенту подключившегося пользователя. Таким образом, его можно использовать для доступа к ресурсам сети от имени этого пользователя. И если работать со стандартным SSH-агентом, о проблеме не узнать. Но вот с U2F-ключом или Sekey эту проблему можно убрать.
В целом, пробрасывать ключ можно, но желательно не использовать этот метод часто и для всех своих подключений. Желательно применять его лишь в том случае, когда пользователь уверен в ситуации.
Выход из подвисшей SSH-сессии
SSH-сессии частенько зависают из-за проблем с сетью, потери контроля выполняемой программой или одной из управляющей последовательностей терминала, блокирующих ввод с клавиатуры. Есть несколько способов выхода из зависшей сессии:
1. Автоматически при разрыве сети. Для этого в файл SSH-конфигурации, .ssh/config, необходимо добавить:
ServerAliveInterval 5
ServerAliveCountMax 1
В этом случае ssh станет проверять соединение, отправляя echo-запросы на удаленный хост через определенные промежутки времени. Они задаются параметром ServerAliveInterval. Если без ответа остается больше, чем ServerAliveCountMax запросов, SSH закрывает соединение.
2. Разрыв сессии. ssh использует символ ~ в качестве управляющей последовательности по умолчанию. Команда ~ закрывает текущее соединение и возвращает в терминал.
Кроме того, команда ~? Выводит весь список команд, которые можно использовать в текущей сессии. Если у вас установлено несколько раскладок, то придется нажимать кнопку ~ дважды для отправки символа.
Оставляем терминал на удаленном хосте открытым
Есть два варианта для сохранения сессии во время переключения между сетями.
1. Использование Mosh или Eternal Terminal
Если нужно надежное и не закрывающееся соединение, даже во время переключения между сетями, то есть выход — нужно использовать Mosh — mobile shell. Mosh называют защищенную оболочку, которая использует SSH для инициализации сессии (handshake). После этого она переключается на собственный зашифрованный канал, который весьма стабилен. Он, например, может обрабатывать разные ситуации, включая разрывы связи, изменение IP-адреса устройства, большие лаги при передаче данных и все прочее. Все это — благодаря UDP и протоколу синхронизации, который использует Mosh.
Для работы с ним нужно, прежде всего, установить его как на сервере, так и клиенте, открыв порты с 60000 по 61000 для входящего UDP трафика на вашем удаленном хосте. После этого нужно просто набрать mosh user@server для подключения.
Mosh работает на уровне экранов терминала и нажатий клавиш, что дает ему большое количество плюсов по сравнению с SSH, передающим бинарный поток данных с обычного ввода вывода между клиентами и сервером. Если же нужно синхронизировать лишь экран терминала и нажатия клавиш, то прерванное соединение восстанавливается значительно быстрее. Тому же SSH необходимо хранить в буфере и пересылать все, а вот Mosh требуется лишь сохранять нажатия клавиш, синхронизируя последнее состояние терминального окна с клиентом.
2. Использование tmux. Для того, чтобы подключаться и отключаться при необходимости, сохраняя ту же сессию на удаленном хосте, стоит использовать мультиплексор терминала, который называется tmux. В том случае, если SSH-соединение отваливается, нужно снова подключиться и набрать tmux attach. После этого пользователь возвращается в сессию tmux.
Он предлагает также несколько дополнительных функций, включая табы, панели, такие же, как в терминале macOS, плюс возможность работать с терминалом вместе с другим пользователем. Еще больше возможностей можно получить при помощи Byobu — это пакет, добавляющий большое количество удобных функций и сочетания клавиш. Он поставляется с Ubuntu, а в macOS его можно запустить при помощи Homebrew.
Расшариваем удаленный терминал
Бывают ситуации, когда необходимо расшарить SSH-сессию — например, во время решения сложных проблем с серверами. Лучший способ сделать это — tmux. Для решения задачи нужно сделать вот что:
- Убедиться в том, что tmux установлен на сервере в DMZ (или локации, к которой нужно подключиться).
- Обоим пользователям требуется подключиться к серверу через SSH с одним и тем же аккаунтом.
- Один из пользователей должен запустить tmux для создания tmux-сессии.
- Второй пользователь выполняет команду tmux attach.
- Все готово!
Если же нужна тонкая настройка мульти пользовательских сессий, стоит воспользоваться tmate. Это улучшенный форк tmux.
Советы от эксперта
Перевод мы решили дополнить собственными советами — надеемся, что они тоже пригодятся. Своим полезным опытом поделился Максим Клочков, старший консультант центра сетевых решений компании «Инфосистемы Джет» и преподаватель курса «Профессия Специалист по кибербезопасности» в Skillbox.
Проброс TCP-портов
У ssh есть два полезных параметра: -L и -R.
Параметр -L организует на нашем локальном компьютере открытый порт TCP, при попытке установить TCP-соединение на который происходит прозрачный проброс этого соединения в туннель ssh, и далее — установление соединения с удаленного компьютера.
После параметра -L указывается аргумент в следующем виде:
ssh -L XXX:server1:YYY login@server2
Здесь server2 — удаленный сервер, на который мы заходим по ssh, login — имя пользователя, под которым мы заходим на удаленный сервер, XXX — номер порта, который надо организовать на локальном компьютере, server1 — хост, на который надо пробросить соединение с этого порта, и наконец YYY — порт, на который надо пробросить это соединение.
Рассмотрим два примера.
Пример 1.
- Мы находимся на сервере spb.company1.ru, и хотим протестировать веб-приложение, которое обращается к базе по адресу central-db.company1.ru
- Эта база доступна только с сервера moscow.company1.ru, на порту 9999
- Мы организуем проброс локального порта 55555 к базе данных через ssh-туннель следующим образом: ssh -L 55555:central-db.company1.ru:9999 login@moscow.company1.ru
- После этого разворачиваем на нашем локальном сервере веб-приложение, и в качестве базы указыаем не central-db.company1.ru:9999, а localhost:55555 — это соединение будет проброшено на сервер moscow.company1.ru, и уже этот сервер выполнит соединение с базой данных на хосте central-db.company1.ru, порт 9999
Пример 2.
- Мы находимся на сервере spb.company1.ru, и хотим показать заказчику тестовый веб-сайт по адресу moscow.company1.ru, порт 5000.
- К этому сайту нет доступа из Интернета, есть только внутренний доступ с того же хоста, где он развернут, т. е. с moscow.company1.ru
- Мы организуем проброс локального порта 80 через ssh-туннель следующим образом ssh -L 80:localhost:5000 login@moscow.company1.ru
- Если теперь пользователь зайдет браузером по ссылке spb.company1.ru, то соединение будет проброшено через ssh-туннель к серверу moscow.company1.ru, и уже этот сервер выполнит установку соединения по адресу localhost:5000, т. е. к нашему тестовому веб-сайту.
Параметр -R организует на удаленном сервере открытый порт TCP, при попытке установить TCP-соединение на который просходит прозрачный проброс этого соединения в туннель ssh, и далее — установление соединения с локального сервера.
После параметра -R указывается аргумент в следующем виде:
ssh -R XXX:server1:YYY login@server2
Здесь server2 — удаленный сервер, на который мы заходим по ssh, login — имя пользователя, под которым мы заходим на удаленный сервер, XXX — номер порта, который надо организовать на удаленном сервере, server1 — хост, на который надо пробросить соединение с удаленного сервера, и наконец YYY — порт, на который надо пробросить это соединение.
Рассмотрим два примера.
Пример 1.
- Мы находимся на сервере moscow.company1.ru, и с этого сервера доступна база данных на сервере central-db.company1.ru, на порту 9999.
- Мы разворачиваем веб-приложение на сервере spb.company1.ru, и с этого сервера база данных недоступна.
- Мы организуем проброс порта с сервера spb.company1.ru к базе данных следующим образом: ssh -R 55555:central-db.company1.ru:9999 login@spb.company1.ru
- После этого мы разворачиваем на сервере spb.company1.ru наше веб-приложение, но в качестве базы указываем не central-db.company1.ru:9999, поскольку этот сервер нам недоступен, а localhost:55555 — это соединение будет проброшено на нашу локальную машину через ssh-туннель, и далее локальная машина установит соединение на сервер central-db.company1.ru, порт 9999.
Пример 2.
- Мы находимся на сервере moscow.company1.ru, и на нашем сервере развернут тестовый веб-сайт, на порту 5000.
- Этот тестовый веб-сайт доступен только локально, соединения из Интернета к нему запрещены, но мы хотим продемонстрировать этот сайт заказчику, который может заходить веб-браузером на сервер spb.company1.ru
- Мы организуем проброс порта с сервера spb.company1.ru следующим образом: ssh -R 80:localhost:5000 login@spb.company1.ru
- Если теперь пользователь зайдет браузером по ссылке spb.company1.ru, то соединение будет проброшено через ssh-туннель на наш локальный сервер moscow.company1.ru, и уже с него будет установлено соединение на localhost:5000 — то есть к нашему тестовому веб-сайту.
А какими хитростями можете поделиться вы?
По теме:
- Статья «Как с помощью Bash быстрее выполнять задачи»;
- Практический онлайн-курс «Администрирование ОС Linux?».
fedorro
Дежавю:
habr.com/ru/company/itsumma/blog/499920
habr.com/ru/post/502728
Вероятно при заполнении поля первоисточника для перевода нужно добавить вывод списка переводов которые уже имеются на Хабре.
itNews
Тут вроде дополнение от эксперта больше, чем сам перевод, не дубль.