SSH – как управлять сервером, не привлекая внимания хакеров

Intro

Тут на днях я узнал про выход новой Raspberry Pi 4 (кто не в курсе, это такой одноплатный мини-компьютер), и хоть я уже был счастливым обладателем 3 пишки, не удержался и купил обновленную версию. И, признаться, остался не совсем доволен из-за таких вещей как замена видеоразъёма HDMImicroHDMI (провод к которому еще надо найти и купить), традиционные периодические проблемы с питанием и тд. Но это – тема отдельной статьи. После того как все необходимые ингридиенты были получены и  обнаруженные проблемы более-менее устранены, я как тру-админ и бекендер в душе настроил удаленный доступ к плате по SSH. В ходе этого занимательного процесса пришлось порыться в задворках своей памяти и почитать разные статьи в интернете по теме. Собственно эта статья и будет квинтессенцией того что я вспомнил про этот замечательный протокол с примесью инфы, сворованной из википедии.

Предупреждаю, я буду делать много вставок, возможно временами нести бред и использовать мат; мне вообще похуй, это мой сайт как никак, здесь ЦП не только в ЛС, а везде слать можно. Ладно всё, расслабьтесь, это шутка (но не точно), слава двачу, погнали!

Contents

  • Intro
  • Theory
  • Practice
  • Outro

Theory

Итак, закройте глаза, расслабьтесь (но не засыпайте, вам еще статью дочитывать)  и представьте себе такую ситуацию:
Вы – админ серьёзной компании, настолько серъёзной, что у нее есть сайт. У вашей компании также есть сервер, на котором этот сайт и работает: HTML/CSS/JS-файлы, базы данных – всё там. А сервера – существа довольно прихотливые: подавай им то усиленное охлаждение, то определённую влажность воздуха, то еще что-то.  Поэтому компанией было принято решение поставить ваш сервер в отдельное специально оборудованное помещение, с проветриванием и стойками – так называемой серверной. Вы же сидите в своем лампово обустроенном кабинете и гоняете кску усердно работаете. Ваша задача как админа – осуществлять настройку, обновление и бесперебойную работу сервера, чтобы клиенты компании всегда получали лучший юзер-експериенс от использования вашего сайта. А для этого естественно надо какаим-то образом взаимодействовать с сервером, вводить разные умные команды (по типу sudo rmrf /). Что делать? Один из вариантов – переехать из вашего уютного кабинета с родными плакатами голых женщин и ретро-игр в шумную и жаркую серверную, чтобы иметь непосредственный доступ к серваку. Звучит как-то не очень воодушевляюще. Другое решение (рекомендую, особенно если вы уже приросли к стулу в своем кабинете) – настроить удалённый доступ. Вы по гайдам (и возможно по этой статье) совершаете определённый ритуал ввода магических команд и установки подозрительных пакетов, вследствие чего вы обретаете суперспособность управлять сервером с компьютера в вашем кабинете как если бы вы управляли им будучи рядом с ним в серверной. Not bad, по-моему.

 

Для осуществления такого удалённого доступа существует несколько протоколов: telnet, rlogin, SSH. Как говорят, последний в списке не обязательно последний по значимости, а возможно наоборот, потому что с точки зрения безопасности SSH наиболее предпочтителен для использования, и это еще мягко сказано, ввиду того что при разработке telnet и rlogin вопросы безопасности не рассматривались вообще. Сейчас посмотрим всё на схемах:

 

Абсолютно все данные при использовании ПО для удалённого доступа, использующего telnet/rlogin, передаются в открытом виде. Соответственно какому-нибудь кул-хацкеру не составит большого труда не только смотреть логины, пароли, какие именно команды вы выполняете на сервере и что они выдают в ответ, но и самому получить возможность выполнять на нём команды, а это полнейшее фиаско и фак гг. В случае использования SSH удалённый доступ осуществляется по другому принципу, в 2 этапа:

  1. Инициализация безопасного соединения
  2. Защищённый удалённый доступ

Перед началом сессии удалённого доступа две целевые машины с помощью хитрой математики создают защищённый “тоннель” (это конечно абстракция для удобства представления и повествования, на самом деле передаваемые просто “накрываются” шифрованием), такой, что если через него передавать данные, то возможность прочитать данные будет только у целевой машины на другой стороне. У хайкера на этот раз ничего не получится сделать, всё защищено тоннелем, и он пойдёт дальше мечтать о крутости на какой-нибудь hackertyper.net.

Далее мы можем осуществлять удаленный доступ как обычно.

И сейчас, когда образное представление о предметной области было получено, давайте добавим более номенклатуризированную (я чуть не сдох пока писал это слово) и точную теорию.
SSH (Secure Shell – защищённый шелл) – сетевой протокол прикладного уровня, использующийся главным образом для удалённого доступа/управления различными узлами в сети (хосты/роутеры/…). Также он может туннелировать внутри себя другие протоколы (например Linux-протокол удалённого рабочего стола X11). Стандартный номер сетевого порта – 22. Работает по модели взаимодействия клиент-сервер: на управляемой машине устанавливается SSHсервер, исполняющий на ней команды от авторизованных SSHклиентов, установленных на других машинах. Поддерживается параллельное подключение нескольких клиентов к одному SSHсерверу. Предусмотрена возможность сжатия данных, удобного для передачи аудио/видео.

Переходим к самому интересному: каким именно образом SSH осуществляет защищённое соединение. В SSH предусмотрены 3 вида аутентификации:

  1. Аутентификация по IP-адресу. Удалённый доступ предоставляется только той машине, которая имеет определённый IP-адрес. Ввиду того, что злоумышленник потенциально может “захватить” этот IP-адрес для своего хоста (кому интересно, гуглить по темам DHCP,ARP, routing tables) и далее успешно пройти аутентификацию, является небезопасным способом.
  2. Аутентификация по паролю. При создании соединения используется пароль, который клиент должен предоставить для подключения.
  3. Аутентификация по открытому ключу. На сервере хранятся файлы открытых ключей клиентов, которым разрешено подключаться у нему по SSH.

Аутентификация по IP-адресу. Удалённый доступ предоставляется только той машине, которая имеет определённый IP-адрес. Ввиду того, что злоумышленник потенциально может “захватить” этот IP-адрес для своего хоста (кому интересно как, гуглить по темам DHCP,ARP,ARPspoofing, routing tables) и далее успешно пройти аутентификацию, является небезопасным способом.

 

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

 

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

 

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

Что касается конкретных алгоритмов шифрования: для выработки общего сессионного ключа используется алгоритм Диффи-Хеллмана; для шифрования передаваемых данных в ходе соединения используется симметричное шифрование, а именно AES, 3DES, Blowfish; за целостность отвечают CRC-32/HMACSHA-1/HMACMD5.

Practice

“Theory is when you know everything but nothing works. Practice is when everything works but no one knows why. In our lab, theory and practice are combined: nothing works and no one knows why”

“Это всё конечно красиво звучит, но Влад, на словах ты Лев Толстой, а по итогу мы ничего реального еще и не сделали” – скажете вы. Хм, соглашусь, я и сам терпеть не могу надменных теоретиков, поэтому lets get hands dirty right fucking now!

Дано: 2 хоста в одной сети, на обоих системах: ОС Linux Ubuntu 18.04 64bit.

Задача: настроить удалённый доступ одного хоста (SSHклиент)  к другому (SSHсервер).

 

1. Установка

Большинство ­Linuxдистрибутивов уже имеют предустановленный SSH-клиент, который запускается так:

ssh [params]

соответственно на клиентскую машину(192.168.1.100)  мы ничего устанавливать не будем. А вот на второй машине(192.168.1.200) установим SSHсервер:

sudo apt update
sudo apt install ssh

SSHсервер работает как служба, соответственно чтобы её запустить, набираем:

sudo systemctl start ssh.service

Если надо запускать SSHсервер при старте системы (добавить в автозагрузку):

sudo systemctl enable ssh.service

Получить информацию о состоянии SSHслужбы:

sudo systemctl status ssh.service

Тут всё довольно тривиально.

Конфигурационные данные SSH хранятся в /etc/ssh/. Здесь особое внимание стоит обратить на файл  sshd_config – это основной  конфигурационный файл SSH-сервера, нутро которого мы сейчас будем ковырять. Откроем его текстовым редактором на выбор, я буду использовать vim:

sudo vim /etc/ssh/sshd_config

Тут мы видем много ‘#’. Это символы начала однострочного комментария. Параметры имеют такую форму:

parameter_name param_value

Некоторые параметры закомментированы:

#parameter_name param_value

Если надо поменять дефолтные значения определённого параметра, надо его раскомментировать т.е. убрать ‘#’ вначале (если он вообще был закомментирован конечно) и собственно поменять значение на нужное.

Теперь посмотрим поближе на некоторые важные параметры в конфиге.

Port – номер сетевого порта на котором работает SSH-сервер. Если хост на котором у вас установлен SSH-сервер выходит в какую-нибудь сеть, где могут обитать нехорошие люди (например интернет) то рекомендуется поменять дефолтное значение 22, на какое-нибудь другое. Зачем? Всё очень просто. Вышеупомянутые нехорошие люди пишут специальные проги, ищущие хосты с  SSH-серверами  и пытающиеся подобрать пароль перебором. Мало того, что они своим флудом могут повлиять на производительность, так еще и реально же пароль подобрать удачно могут, и тогда “гг вп, админ репортед”. Соответственно если порт переназначить с дефолтного значения, то всей этой истории уже не бывать, так как ставка переборщиков сделана на стандартный 22 порт, соответственно туда и ломится весь этот брутфорс-трафик, который кончено будет дропнут, если порт закрыт.

Логирование SSH тесно связано с syslog-механизмом (кому интересно: https://en.wikipedia.org/wiki/Syslog).

SyslogFacility – определяет к какому типу syslog-сообщений будут относиться логи SSH.

LogLevel – определяет “уровень важности” логируемых сообщений. Все генерируемые SSH логи, имеющие этот уровень ниже установленного значения, записываться и храниться не будут. Возвращаясь к теме кул хацкеров и брутфорсеров паролей: если вы хотите заценить, насколько сильны их порывы заовнить ваш ваш сервак через SSH, просто установите в LogLevel значение VERBOSE (по умолчанию оно должно быть INFO):

LogLevel VERBOSE

После изменения лог-уровня попытки аутентификации будут зафиксированы в логе. Посмотреть всё это и впечатлиться упорностью можно в файле /var/log/auth.log.

PermitRootLogin – определяет возможность аутентификации на SSH-сервере как root. С точки зрения безопасности не очень хорошо, если такая аутентификация возможна, так как root – это бог, его права и возможности в системе неограничены. Если вдруг креды утекут нехорошим людям, то можно ливать. Гораздо лучше создать пользователя которому предоставлены только те привилегии, которые необходимы для работы (дада, принцип минимализма в ИБ) и предоставлять возможность авторизовываться через него (параметр AllowUsers), отключив аутентификацию как root.

AllowUsers – устанавливает список пользователей, в качестве которых могут авторизоваться SSH-клиенты. Авторизоваться возможно только в качестве указанных пользователей.

MaxAuthTries – устанавливает количество попыток входа по истечении которого последующие блокируются

MaxSessions – устанавливает максимальное количество подключений к серверу в каждый момент времени. Да, как упоминалось ранее, SSH-сервер имеет возможность поддержки сразу нескольких параллельных соединений.

PubkeyAuthentification –если значение “on”, то используется аутентификация по открытому ключу. Ваш кеп.

PasswordAuthentification если значение “on”, то используется аутентификация по паролю. Cap strikes back.

Banner – Сообщение, которое будет показано при попытке подключения. Можно написать что-нибудь по типу “This server is under Area 51 & Mario jurisdiction”, чтобы скрипткидисы, пытающиеся похакать ваш сервак, сразу убежали от страха, роняя кал.

2. Использование

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

Парольная аутентификация:

Устанавливаем значения в конфиге:

PasswordAuthentification on
PubkeyAuthentification off

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

ssh <user_name>@<server_ip/server_hostname>

Т.е. в нашем сетапе полная команда будет выглядеть так:

ssh user@192.168.1.200

Далее вводим пароль пользователя user и получаем удаленную командную строку от его имени. ??? Profit!

Aутентификация по ключу

Устанавливаем значения в конфиге:

PasswordAuthentification off
PubkeyAuthentification on

Настройка сервера закончена. Далее нужно сгенерировать для клиента пару открытый-закрытый ключ (т.е. 1 файл с открытым ключом (расширение .pub) и 1 файл с закрытым ключом, , по умолачнию в имя ключеваых файлов – id_rsa). Делается это с помощью команды sshkeygen:

ssh-keygen

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

Для того, чтобы иметь возможность проводить аутентификацию по открытому ключу, серверу нужно хранить открытые ключи клиентов, у которых есть разрешение на подключение. У каждого пользователя на сервере есть специальный файл в его личной папке – /home/<user_name>/.ssh/authorized_keysгде как раз сохранён список открытый ключей тех клиентов, которым разрешено подключиться к серверу в качестве этого пользователя. Поэтому открытый ключ, сгенерированный на клиенте, надо передать на сервер. Есть несколько способов сделать это, например взять флешку, записать файла открытого ключа с клиента и перенести с её помощью его на сервер, записав в соответствующий файл authorized_keys. Другое решение – опять же сделать всё это по сети, удалённо, и для этого также предусмотрена  специальная программа – sshcopyid:

ssh-copy-id  -i <pub_key_path> <user_name>@<server_ip/server_hostname>

В нашей конфигурации соответственно вот так:

ssh-copy-id -i /home/user/.ssh/id_rsa.pub user@192.168.1.200

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

И теперь когда сервер имеет нужный файл открытого ключа, можем подключаться:

ssh user@192.168.1.200

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

Как нетрудно видеть, ничего сверхсложного в настройке SSH нет – всё для пользователя, это вам не сайт госуслуг :3

Еще пара слов про SSHклиенты. Это такие программы, которые служат для подключения по SSH(обычно поддерживается не только он, но и telnet, rlogin, …) плюс имеют различные свистелки –перделки по типу GUI-интерфейса, сохранения деталей подключения (адрес сервера, креды, …) в профили и тд. Навскидку примеры таких прог: PuTTY, SecureCRT.

Outro

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

Подписывайтесь, ставьте лайки, оставляйте положительные комментарии. Имейте дело исключительно с надежными, проверенными серваками и практикуйте только безопасное подключение для здоровой и полноценной сетевой жизни 😉

Links:

Leave a Reply

Your email address will not be published. Required fields are marked *