• Час читання ~8 хв
  • 25.03.2024

SSH є дуже потужним і гнучким інструментом, але, як показує практика, далеко не всі розуміють, як він працює, і правильно його використовують. Слово Secure є частиною абревіатури SSH і є одним з ключових аспектів протоколу, але часто безпеці приділяється недостатньо уваги. У цій статті я хочу розповісти про кілька поширених помилок при роботі з SSH, а також про деякі, які часто не беруться до уваги.

image

Существует несколько способов аутентификации пользователя:

  1. По паролю — стандартный механизм, но не самый надежный, я не буду заострять на нем внимание
  2. По ключу — самый надежный способ аутентификации, но это при условии, если правильно его использовать
  3. По IP адресу — режим совместимости. Привожу просто для справки, сомневаюсь, что кто-то будет использовать его в трезвом уме.

Асиметричне шифрування

SSH використовує асиметричне шифрування, що означає, що існує два ключі: відкритий ключ і закритий ключ. Ви можете зашифрувати повідомлення за допомогою відкритого ключа, а можете розшифрувати його за допомогою закритого ключа. Приватний ключ зберігається в безпеці, а відкритий ключ доступний кожному. Крім того, ви можете підписати повідомлення приватним ключем і перевірити цей підпис за допомогою відкритого ключа.

Як видно зі схеми, після обміну публічними ключами два вузли можуть безпечно зв'язуватися один з одним через незахищений інтернет.

Крім того, користувач може бути аутентифікований за допомогою цієї пари ключів.

Відкритий ключ користувача має бути додано до файлу $HOME/.ssh/authorized_keys
У цьому файлі може бути кілька відкритих ключів, і всі вони працюватимуть.

image

Захист від атак

MITM Атака MITM — це тип атаки в криптографії, коли зловмисник таємно ретранслює та, за необхідності, змінює зв'язок між двома сторонами, які вважають, що вони безпосередньо спілкуються один з одним. Це метод компрометації каналу зв'язку, при якому зловмисник, підключившись до каналу між контрагентами, втручається в протокол передачі, видаляючи або спотворюючи інформацію.

Одним з головних нововведень у другій версії протоколу є вбудований захист від атак MITM.

image

Суть захисту полягає в тому, що кожна сторона повинна переконатися, що інша сторона - саме та, на яку чекають, а не нападник.

Параметр StrictHostKeyChecking і файл known_hosts відповідають за захист MITM на стороні клієнта (тобто за визначення того, що ви підключаєтеся до свого сервера).

Публічні ключі серверів зберігаються в наступних файлах:
$HOME/.ssh/known_hosts є нетиповим файлом,
/etc/ssh/ssh_known_hosts є системним файлом.

Кожен запис в known_hosts являє собою рядок, який містить поля і використовує пробіл в якості роздільника:

  1. одно или несколько имен серверов или IP-адресов, разделенных запятыми
  2. тип ключа
  3. открытый ключ
  4. любые дополнительные комментарии

Саме тут відбувається «ідентифікація» сервера

StrictHostKeyChecking=no|ask|yes 

Значення можуть бути наступними:

  • Ні — з'єднання відбудеться в будь-якому випадку, максимум ми отримаємо попередження про те, що з'єднання не безпечне. Його часто можна зустріти у всіляких автоматизованих скриптах на кшталт автотестів і авторозгортань, і саме в цьому криється основна проблема: якщо скрипт працює нормально, то користувач (адміністратор) не помітить нічого поганого, і відбудеться зараження/компрометація.
  • ask — запитати при новому підключенні (значення за замовчуванням), якщо запису ще немає в known_hosts, і якщо ви погоджуєтеся на підключення, додається новий запис
  • Так — завжди скануйте, найбезпечніший варіант, який я настійно рекомендую використовувати в автоматизованих системах. Підключення здійснюється тільки при наявності запису в known_hosts

Що це нам дає:

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

Якщо з другим пунктом все зрозуміло, то як бути з першим?

Тут є як мінімум три варіанти:З мого досвіду,

  1. Довериться случаю и согласиться на добавление нового ключа сервера
  2. Добавить флаг VisualHostKey=key, при этом клиент отобразит визуальное представление открытого ключа сервера, это представление уникально и облегчит запоминание ключа
  3. Флешка или открытые источники: это вариант для параноиков, однако, если компрометация системы может стоить десятков тысяч долларов, то это не лишне.

image
Использование визуализации открытого ключа

image
Если открытый ключ изменился

Сообщение о смене ключа может происходить по нескольким причинам:

  1. Изменился адрес сервера
  2. Изменился ключ сервера, например, при переустановке системы
  3. MITM атака

варіанти 1 і 2 в сумі мають тенденцію до 100%, але і пункт 3 виключати не можна.

Ось приклад лайфхака, який поєднує в собі підходи

curl https://server.com/ssh_fingerprint | tee -a ~/.ssh/known_hosts

web і ssh На перший погляд, це не дуже безпечно, проте цю інформацію можна отримати за допомогою

ssh-keyscan example.com

Однак у першому варіанті ми додатково перевіряємо справжність отриманого ключа за допомогою HTTPS.

У критично важливих CI/CD використання

ssh-keyscan example.com >> ~/.ssh/known_hosts

комбінації під час ініціалізації в поєднанні з

StrictHostKeyChecking=yes

атаками MITM може бути надійно захищене від атак MITM.

Багато ключів

Часто можна побачити наступну закономірність:

image

Кожен сервер на клієнті має свої пари ключів, а $HOME/.ssh/ - це повний безлад.

З одного боку, це безпечніше, ніж використання однієї пари клієнтських ключів — якщо один ключ скомпрометовано, скомпрометовано лише одну систему, а не всі, з якими працював користувач.

Однак, як показує практика, це останнє, чим керуються користувачі, часто вони просто покроково виконують всі інструкції:

ssh-keygen
...
...

Іноді я спостерігав ситуацію, коли одні клавіші терлися іншими без будь-яких роздумів в голові.

image

Нагадуємо, що якщо ви параноїк щодо безпеки, достатньо мати одну пару ключів, але захищати її потрібно належним чином.

До речі, про захист ключів

image

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

Що можна виділити:

  1. Хранить ключ надо в безопасном месте, в идеале это шифрованное хранилище
  2. Никому не предоставлять доступ к ключу, скомпрометированный ключ компрометирует все системы где разрешен доступ по нему
  3. Шифрование приватного ключа увеличивает безопасность, т.к. при потере ключа необходимо еще получить пароль для его дешифрации, либо потратить время и вычислительные мощности на его взлом.
  4. Не забывать про установку корректных прав на файл ключа 400, кстати, это распространенная ошибка, когда клиент отказывается использовать ключ

Змінити або додати пароль можна за допомогою команди

ssh-keygen -p

SSH-Agent

Але часто виникає ситуація, коли потрібно зайти на сервер зі своїм ключем і використовувати його там. Є три варіанти вирішення цієї проблеми:

  1. Скопировать свой приватный ключ на сервер
  2. Сгенерировать новую пару ключей и прописать ее в качестве варианта доступа
  3. Использовать ssh-agent

З мого досвіду, перші два варіанти користувачі вибирають в 90% випадків, і як ми вже говорили: немає нічого страшнішого, ніж компроміс ключа.

Я рекомендую використовувати третій спосіб

image

: SSH-агент зберігає приватні ключі і використовує їх при необхідності. Програма (наприклад, ssh), коли їй потрібно використовувати закритий ключ, не робить цього сама, а викликає ssh-агент, який, у свою чергу, використовує дані про відомі тільки їй приватні ключі. Таким чином, приватні ключі не розкриваються нікому, навіть програмам. належить користувачеві.

Команда ssh-agent створює файл сокета із назвою /tmp/ssh-XXXXXXXX/agent.ppid, за допомогою якого агент обмінюється даними. Для всіх дочірніх процесів агент використовує змінні середовища SSH_AUTH_SOCK (де зберігається ім'я файлу сокета) і SSH_AGENT_PID (де зберігається ідентифікатор процесу агента), щоб надати інформацію про те, як зв'язатися з агентом.

Агент надає інформацію у формі, зручній для використання оболонкою.

SSH_AUTH_SOCK=/tmp/ssh-XXt4pHNr/agent.5087; export SSH_AUTH_SOCK;
SSH_AGENT_PID=5088; export SSH_AGENT_PID;
echo Agent pid 5088;

Якщо вказано перемикач -c, агент використовує синтаксис оболонки C. Типово (і якщо явним чином вказано перемикач -s) використовується синтаксис оболонки Борна. Ці змінні має бути встановлено у поточній оболонці, тому загальноприйнято поєднувати виклик ssh-agent із командою eval.

$ eval `ssh-agent`
Agent pid 5088

Агент запускатиметься, аж доки його явним чином не буде перервано сигналом або викликом

$ ssh-agent -k

Список закритих ключів, відомих агенту, можна переглянути за допомогою тієї самої команди ssh-add із перемикачем командного рядка -l.

$ ssh-add -l
1024 46:88:64:82:a7:f9:aa:ea:3b:21:9e:aa:75:be:35:80 /home/user/.ssh/id_rsa (RSA)

Приклад роботи з ssh-agent можна побачити нижче

image

Крім того, агент вирішує ще одну проблему: якщо ви зашифрували закритий ключ, у вас не будуть запитуватися пароль при кожному зверненні до нього. Якщо ви користуєтеся агентом, вам потрібно буде ввести пароль лише під час додавання ключа до агента.

Локальна конфігурація

Якби кожен раз, коли я дивився рядок типу форми

ssh -p 2022 [email protected] -o StrictHostKeyChecking=yes -i ~/.ssh/server.pem

, мені давали рубль, я б давно жив в Сочі.

На локальній машині можна знайти файл $HOME/.ssh/config

Host server
	User root
	HostName 192.168.0.3
	IdentityFile ~/.ssh/server.pem
Host example.com
	User admin
	IdentityFile ~/.ssh/production.pem

Відповідно, в цей файл можна записати більшість параметрів хоста і не вводити його кожен раз.

Інші способи підвищення безпеки

1. Використовуючи аутентифікацію ключа, не забувайте, що у вас все ще є пароль, і незалежно від того, як ви захистите свій приватний ключ, зловмисник зможе вгадати ваш qwerty-пароль і увійти в систему, не викрадаючи ключ

Є кілька рішень:

  • Встановіть дуже складний пароль, який буде складно вгадати і зберегти в надійному місці. Це дозволить вам мати альтернативний спосіб входу.
  • Видаліть пароль повністю, але тоді можуть виникнути проблеми з sudo та іншими речами
  • Відключення аутентифікації паролем на сервері, насправді, як правило, це заборонено для користувача root. Єдине, що залишилося зробити, це відключити для всіх користувачів.

PasswordAuthentication немає в /etc/ssh/sshd_config

2. Ви також можете вимкнути використання ssh v1
Протокол 2 у /etc/ssh/sshd_config

3. І обов'язково заблокуйте доступ до SSH для ненадійних джерел

на брандмауері 4. Раніше я б порадив вам змінити порт зі стандартного 22 на інший, але спостерігаючи, скільки спроб увійти в нестандартні порти, можу сказати однозначно: це не захист від злому.

5. Якщо ми вже розглядаємо підбір пароля, то не зайвим буде налаштувати fail2ban , щоб обмежити спроби вгадати пароль.

6. У протоколі та бібліотеках періодично виявляються проблеми та вразливості, вірш тут універсальний підхід — слідкуйте за оновленнями програмного забезпечення та намагайтеся регулярно встановлювати хоча б патчі безпеки.

7. SSH-агент безпечніший, ніж просто копіювання файлів, однак його також може зламати, наприклад, користувач root на сервері. Тому рекомендується включати переадресацію тільки в тих випадках, коли це необхідно.

Висновки Прочитайте

документацію, там написано все, як би вульгарно це не звучало.
SSH є дуже безпечним протоколом, але людські помилки часто є основним джерелом проблем, тому стежте за безпекою.

використовувані матеріали
Захист за допомогою SSH-ключів
Керування ключами SSH на основі агентів

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Про автора CrazyBoy49z
WORK EXPERIENCE
Контакти
Ukraine, Lutsk
+380979856297