Алгоритм роботи протоколу SSH

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

Спробую внести трохи ясності в роботу протоколу SSH, а заодно розглянути роль алгоритму RSA і ключів авторизації користувача…

Алгоритм протоколу SSH можна розділити на три рівні, кожен з яких розташовується над попереднім: транспорт (відкриття захищеного каналу), аутентифікація, підключення. Для цілісності картини я також додам рівень встановлення мережевого з’єднання, хоча офіційно цей рівень знаходиться нижче SSH.

1. Установка TCP-з’єднання

Не буду детально зупинятися на принципі роботи стека TCP/IP, так як ця тема досить добре задокументована в Рунеті. При необхідності ви легко знайдете інформацію.

На цьому етапі відбувається мережеве підключення клієнта до сервера на TCP-порт, зазначений в опції Port (за замовчуванням: 22) у файлі конфігурації сервера /etc/ssh/sshd_config.

2. Відкриття захищеного каналу

2.1 Обмін ідентифікаційними даними

Після встановлення TCP-з’єднання, клієнт і сервер (далі по тексту – сторони) обмінюються версіями SSH-протоколу та іншими допоміжними даними, необхідними для з’ясування сумісності протоколів і для вибору алгоритмів роботи.

2.2 Вибір алгоритмів: обміну ключами шифрування, стиснення і т. п.

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

Читайте також  Створення ігор-головоломок на Puzzle Script

Список доступних алгоритмів обміну ключами на стороні клієнта (використовуються для отримання сесійного ключа) можна подивитися командою:

ssh -Q kex

Перелік доступних в системі симетричних алгоритмів (використовуються для шифрування каналу):

ssh -Q cipher

Список типів ключів для авторизації у клієнта:

ssh -Q key-cert

2.3 Отримання сесійного ключа шифрування

Процес отримання сесійного ключа може відрізнятися в залежності від версії алгоритму, але в загальних рисах зводиться до наступного:

  • Сервер відсилає клієнтові свій ключ (DSA, RSA або т. п. за домовленістю між сторонами, виробленими в п. 2.2).
  • Якщо клієнт здійснює з’єднання з даним сервером вперше (про що говорить відсутність запису у файлі /home/username/.ssh/known_hosts у клієнта), то користувачеві буде поставлено питання про довіру ключа сервера. Якщо ж з’єднання з даним сервером вже встановлювалося раніше, то клієнт порівнює присланий ключ з ключем, записаним в /home/username/.ssh/known_hosts. Якщо ключі не співпадають, то користувач отримає попередження про можливу спробу злому. Втім, цю перевірку можна пропустити, якщо викликати ssh з опцією StrictHostKeyChecking:
    ssh -o StrictHostKeyChecking=no username@servername

    Також, якщо користувачеві потрібно видалити старий ключ сервера (наприклад, коли є точна впевненість, що ключ був змінений на сервері), то використовується команда:

    ssh-keygen -R servername
  • Як тільки клієнт визначився з довірою до ключа сервера, за допомогою однієї з реалізацій (версія визначається п. 2.2) алгоритму Діффі-Хеллмана клієнт і сервер генерує сеансовий ключ, який буде використовуватися для симетричного шифрування каналу.

Сеансовий ключ створюється виключно на період життя каналу і знищується при закритті з’єднання.

3. Аутентифікація клієнта

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

Читайте також  Угорський алгоритм, або про те, як математика допомагає у розподілі призначень

В загальних рисах, аутентифікація за допомогою ключів відбувається наступним чином:

  • Клієнт посилає серверу ім’я користувача (username) і свій публічний ключ.
  • Сервер перевіряє у файлі /home/username/.ssh/authorized_keys наявність наданого клієнтом відкритого ключа. Якщо відкритий ключ знайдено, то сервер генерує випадкове число і шифрує його відкритим ключем клієнта, після чого результат відправляється клієнту.
  • Клієнт розшифровує повідомлення своїм приватним ключем і відправляє результат сервера.
  • Сервер перевіряє отриманий результат на збіг з тим числом, яке він спочатку зашифрував відкритим ключем клієнта, і в разі збігу вважає аутентифікацію успішною.

 

4. Рівень підключення

Після проведення всіх перерахованих вище процедур, користувач отримує можливість передавати команди сервера або копіювати файли.

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

Від теорії до практики

Ну а тепер, думаю, у читачів виникло цілком закономірне запитання: а навіщо потрібно знати всі ці тонкощі роботи SSH-протоколу, якщо для повсякденної роботи достатньо знань команд створення ключів (ssh-keygen), відкриття термінальній сесії (ssh), передачі файлів (scp)?

У власній практиці я не пригадаю жодного спостерігача в зовнішню мережу сервера, який би щодня не піддавався долбежке на 22-й порт. У ситуації, якщо SSH у вас працює на стандартному порту (і нічим додатково не захищений), навіть якщо аутентифікація виключно по ключам і ніякі підбирання паролів не лякають, то з причини постійно валящихся запитів від недобросовісних клієнтів сервер все одно змушений здійснювати масу непотрібної роботи: встановлювати TCP-з’єднання, обирати алгоритми, генерувати сесійний ключ, відправляти запити аутентифікації, писати лог-файл.

У ситуації ж, коли на 22-му порту нічого немає, або порт захищений за допомогою iptables (або надбудовами над ним типу fail2ban), то зловмисник буде дропнут ще на етапі встановлення TCP-з’єднання.

Читайте також  Огляд безкоштовних 2D САПР

Найбільш цікаво описане виглядає у вигляді таблиці*

Конфігурація Вірогідність злому Втрати від флуду**

22 порт,
авторизація по паролю,
без захисту
висока високі
22 порт,
авторизація по ключам,
без захисту
середня*** високі
22 порт,
авторизація по ключам,
захист на основі обмеження невдалих спроб авторизації
низька середні****
Нестандартний порт,
авторизація по паролю,
без захисту
висока низькі
Нестандартний порт,
авторизація по ключам,
без захисту
середня*** низькі
Нестандартний порт,
авторизація по ключам,
захист на основі обмеження невдалих спроб авторизації
низька низькі

* — значення параметрів (високий, середній, низький) носять відносний характер і служать тільки для порівняння показників.
** — мається на увазі витрати ресурсів сервера (процесор, диск, мережевий канал тощо) на обробку лавини запитів, зазвичай йдуть на 22-й порт.
*** — здійснити злом, якщо для авторизації використовуються RSA-ключі, дуже складно, однак необмежена кількість спроб авторизації робить це можливим.
**** — кількість спроб авторизації обмежена, але серверу все одно доводиться обробляти їх від великої кількості зловмисників.

Додаткові матеріали

  • Исходники SSH
  • Специфікації протоколу SSH (en)
  • Алгоритм Діффі-Хелмана
  • Алгоритм RSA
  • Як SSH з’явився на 22 порту
  • Що записано в файлі .ssh/known_hosts
  • Пам’ятка користувачам ssh

Степан Лютий

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

You may also like...

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *