Як керувати SSH ключами: базові правила
Посібник з налаштування SSH ключів: використання ed25519, правильні права доступу для sshd, конфігурація Host у файлі config та процедура відкликання ключів.
Як працюють SSH keys
SSH key — це пара файлів: приватний ключ (private key), який зберігається на вашому пристрої, та публічний ключ (public key), який ви копіюєте на кожен сервер для входу. Під час підключення сервер використовує публічний ключ, щоб надіслати запит (challenge), на який може відповісти лише відповідний приватний ключ. Приватний ключ ніколи не залишає ваш пристрій, тому секретні дані не передаються через мережу. Навіть якщо сервер буде зламано, з нього неможливо викрасти корисні дані. Саме тому ключі надійніші за паролі. Правильне керування SSH keys базується на чотирьох правилах: один ключ на один пристрій, дотримання прав доступу до файлів, що вимагає sshd, використання файлу ~/.ssh/config для автоматизації параметрів, а також вміння видалити ключ у разі втрати ноутбука.
Цей посібник описує кожне правило на Ubuntu 24.04, хоча більшість порад застосовується до будь-якого Linux сервера та будь-якої сучасної версії OpenSSH.
Важливе уточнення щодо термінології для уникнення помилок. Публічний ключ не є секретним. Ви можете вставити його в тікет, надіслати електронною поштою або опублікувати — це не дозволить нікому увійти в систему. Приватний ключ є секретним. Будь-хто, хто скопіює цей файл і знатиме його passphrase (якщо вона встановлена), буде вважатися вами з точки зору ваших серверів.
Створення ключа: ed25519 — оптимальний вибір за замовчуванням
На власному комп'ютері, а не на сервері, виконайте:
ssh-keygen -t ed25519 -C "laptop"-t ed25519 визначає тип ключа. Ed25519 — сучасний стандарт: ключі мають короткий розмір, працюють швидко та підтримуються кожною версією OpenSSH, випущеною з 2014 року. Використовуйте ssh-keygen -t rsa -b 4096 лише у разі необхідності підключення до застарілих пристроїв, які не підтримують ed25519. -C "laptop" встановлює коментар. Коментар не впливає на криптографію, але він допоможе вам ідентифікувати цей ключ у файлі authorized_keys на сервері через два роки. Тому вкажіть назву пристрою, на якому зберігається ключ.
ssh-keygen запитує шлях для збереження ключа. Залиште значення за замовчуванням, ~/.ssh/id_ed25519. Далі буде запит пароля (passphrase). Встановіть його; у розділі нижче пояснюється, чому це не ускладнює щоденну роботу. Ви отримаєте два файли: ~/.ssh/id_ed25519 — це приватний ключ, а ~/.ssh/id_ed25519.pub — публічний ключ. Перегляньте публічну частину:
cat ~/.ssh/id_ed25519.pubssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF3k2s0vQx7GdKQhX1yBz... laptopЦе один рядок: тип ключа, сам ключ та ваш коментар. Саме цей рядок буде розміщено на ваших серверах.
Один ключ на пристрій, а не один на сервер
Перше питання, яке виникає у всіх: чи потрібен новий ключ для кожного сервера? Ні. Створюйте один ключ для кожного пристрою, з якого ви працюєте, і додавайте цей публічний ключ на кожен сервер, до якого має бути доступ пристрою. Ключ ідентифікує пристрій. Файл authorized_keys на кожному сервері — це список дозволених пристроїв.
Ця модель масштабується, тоді як альтернативи мають передбачувані недоліки. Використання одного ключа на сервер означає, що ноутбук із двадцятьма серверами містить двадцять приватних ключів, і ви втратите контроль над тим, який за що відповідає. Використання одного спільного ключа для всіх пристроїв — гірший варіант: якщо ноутбук буде викрадено, ви не зможете анулювати доступ лише для ноутбука, не заблокувавши при цьому робочий стіл. Оскільки вони мають однаковий приватний ключ, вам доведеться замінити ключ всюди та одночасно розповсюдити його на всіх пристроях.
При використанні одного ключа на пристрій втрата ноутбука коштуватиме вам лише одного рядка на кожному сервері: видаліть рядок ноутбука з authorized_keys, і всі інші пристрої продовжуватимуть працювати. Коментар, який ви встановили за допомогою -C, дозволяє легко знайти цей рядок.
Принцип цієї моделі: приватний ключ створюється на пристрої та видаляється разом із цим пристроєм. Ніколи не копіюйте приватний ключ на іншу машину і ніколи не завантажуйте його на сервер. Якщо новому пристрою потрібен доступ, згенеруйте на ньому новий ключ.
Додайте публічний ключ на сервер
Найпростіший спосіб — це ssh-copy-id, який постачається разом з OpenSSH:
ssh-copy-id matt@10.0.0.10Ця утиліта виконує вхід за наявними методами (зазвичай за паролем), додає ваш публічний ключ до файлу ~/.ssh/authorized_keys на сервері та створює директорію та файл з правильними правами доступу, якщо вони відсутні. Перевірте результат, відкривши нову SSH-сесію: сервер має впустити вас без запиту пароля облікового запису. Якщо ваш ключ захищений passphrase, ваша локальна машина може запитати його; цей запит є локальним і не є паролем сервера.
Якщо вхід за паролем уже вимкнено, ssh-copy-id не зможе підключитися, тому рядок потрібно додати вручну. Увійдіть через робочу сесію або веб-консоль провайдера та виконайте на сервері наступну команду:
mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF3k2s0vQx7GdKQhX1yBz... laptop" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keysВставте ваш публічний ключ замість тексту в лапках (повний рядок з id_ed25519.pub). У файлі authorized_keys кожен рядок — це один публічний ключ; це вся база даних доступу. Щоб додати пристрій, потрібно додати рядок, щоб видалити доступ пристрою — видалити рядок. На новому сервері цей крок слід виконати у перші 10 хвилин роботи з новим VPS, безпосередньо перед вимкненням входу за паролем.
Права доступу, що перешкоджають входу за ключем
Це найпоширеніша причина помилки входу за ключем. З боку клієнта помилка виникає без жодних повідомлень. У Ubuntu 24.04 sshd за замовчуванням працює з параметром StrictModes yes. Це означає, що сервер відмовляється використовувати authorized_keys файл, який може редагувати інший користувач. Якщо файл, директорія ~/.ssh або ваш домашній каталог доступні для запису будь-кому, крім вас, sshd ігнорує ваш ключ. У такому разі клієнт просто запитує пароль без пояснення причин. (OpenSSH у Ubuntu допускає лише один виняток: файл, доступний для запису вашій приватній групі, до якої не входять інші користувачі. Не покладайтеся на це; використовуйте налаштування нижче). Причина помилки відображається лише в логах сервера:
sudo grep 'Authentication refused' /var/log/auth.logНа мінімальних образах без rsyslog немає auth.log; той самий рядок міститься в journal: sudo journalctl -u ssh | grep 'Authentication refused'.
Authentication refused: bad ownership or modes for file /home/matt/.ssh/authorized_keysДля виправлення потрібно змінити права доступу та перевірити власника. Виконайте ці команди на сервері від імені відповідного користувача:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R matt:matt ~/.sshПравило для запам'ятовування: 700 для директорії .ssh та 600 для всього вмісту всередині неї. Ці самі налаштування діють і на вашому комп'ютері, оскільки клієнт також перевіряє права. Якщо приватний ключ доступний для читання іншим користувачам, ssh відхилить його, і цього разу помилка буде явно виведена:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/home/matt/.ssh/id_ed25519' are too open.chmod 600 ~/.ssh/id_ed25519 вирішує цю проблему.
~/.ssh/config: припиніть ручне введення параметрів
Файл ~/.ssh/config на вашому комп'ютері призначений для призначення коротких імен серверам та збереження параметрів конфігурації. Створіть його з правами 600 та додайте блок Host для кожного сервера:
Host web1
HostName 10.0.0.10
User matt
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
Host db1
HostName 10.0.0.11
User matt
Port 2222
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yesТепер ssh web1 замінює ssh -p 22 matt@10.0.0.10. Те саме коротке ім'я працюватиме в scp, rsync та git, оскільки всі вони читають цей файл. HostName — це реальна адреса, User позбавляє необхідності вводити ім'я користувача, а IdentityFile вказує конкретний ключ для автентифікації.
Варто згадати про IdentitiesOnly yes, оскільки це вирішує проблему помилкової автентифікації. Якщо SSH agent містить кілька ключів, клієнт пропонує їх по черзі, а сервер розцінює кожну пропозицію як невдалу спробу. При великій кількості завантажених ключів ви отримаєте Received disconnect: Too many authentication failures ще до того, як буде спробовано правильний ключ. Параметр IdentitiesOnly yes змушує клієнт пропонувати лише ключ, вказаний у IdentityFile, що запобігає виникненню цієї помилки.
Passphrases and ssh-agent
Passphrase шифрує файл приватного ключа на диску. Без неї будь-хто, хто скопіює файл, зможе використати його миттєво. З нею вкрадений файл буде марним, доки не буде підібрано passphrase. Для ключа на ноутбуці це саме той рівень захисту, який необхідний, оскільки ноутбуки часто викрадають, а бекапи ноутбуків можуть потрапити у відкритий доступ.
Причина, чому використання passphrase не створює додаткових витрат у практиці, — це ssh-agent. Agent зберігає ваш розшифрований ключ у пам'яті, тому ви вводите passphrase лише один раз за сесію входу, а всі наступні підключення відбуваються миттєво. Більшість дистрибутивів Linux для desktop та macOS вже запускають agent автоматично. Завантажте ваш ключ у нього за допомогою:
ssh-add ~/.ssh/id_ed25519ssh-add -l виводить список ключів, які зараз зберігає agent. Застереження: agent forwarding (ssh -A) дозволяє віддаленому серверу використовувати ваш agent для подальшої автентифікації під час вашого підключення. Увімкнюйте цю функцію лише для серверів, яким ви повністю довіряєте, і за замовчуванням тримайте її вимкненою.
Ротація та відкликання: сценарій при втраті ноутбука
Відкликання звичайного SSH-ключа — це просто видалення відповідного рядка з authorized_keys на кожному сервері, де він прописаний. Не потрібно сповіщати центр сертифікації або чекати на закінчення терміну дії. Як тільки рядок видалено, вхід за цим ключем стає неможливим.
Проведіть перевірку зараз, поки це не є екстреною ситуацією. Виберіть сервер, відкрийте ~/.ssh/authorized_keys і знайдіть ключ за його коментарем. Видаліть рядок за допомогою редактора або відфільтруйте його за коментарем:
grep -v ' laptop$' ~/.ssh/authorized_keys > ~/.ssh/authorized_keys.tmp
mv ~/.ssh/authorized_keys.tmp ~/.ssh/authorized_keysПотім підтвердьте з пристрою, на якому ви щойно відкликали ключ, що вхід не працює, а з іншого пристрою — що вхід все ще працює. Зверніть увагу на одну деталь: видалення ключа не розриває вже відкриті сесії, оскільки перевірка ключа відбувається лише під час входу. Якщо ви відкликаєте доступ для вкраденого пристрою, також перевірте who на сервері та завершіть усі невідомі вам сесії.
Ротація — це та сама операція, але в іншому порядку: згенеруйте новий ключ на пристрої, встановіть його за допомогою ssh-copy-id, переконайтеся, що новий ключ дозволяє увійти, а потім видаліть старий рядок. Виконуйте це при зміні власника пристрою, при можливій компрометації ключа або при звільненні співробітника. Виконання цих дій вручну на двох серверах є прийнятним; для двадцяти серверів потрібна автоматизація, а managing multiple Linux servers показує, як застосувати однаковий стан authorized_keys до всього парку серверів.
Чого не слід робити
- Не використовуйте один приватний ключ на всіх пристроях. У разі крадіжки одного пристрою ви не зможете анулювати ключ, не замінивши його всюди.
- Не додавайте приватний ключ у git repository, навіть у приватний. Автоматизовані сканери відстежують публічні репозиторії та перевіряють витік ключів протягом хвилин після push. Якщо репозиторій пізніше стане публічним, весь його history буде скомпрометовано.
- Не завантажуйте приватний ключ вашого laptop на сервер для доступу до іншого сервера. Згенеруйте окремий ключ безпосередньо на сервері та надайте йому відповідні права лише там, де це необхідно.
- Не вставляйте приватний ключ у чат, email або ticket. Публічний ключ, файл
.pub, є єдиною частиною, яку можна передавати.
Коли ключ забезпечить надійний вхід, вимкніть password authentication. Це унеможливить підбір пароля до вашого сервера. Налаштування для цього можна знайти в SSH hardening on a VPS.
FAQ
Як працюють SSH-ключі без передачі пароля?
Сервер зберігає ваш публічний ключ у ~/.ssh/authorized_keys. Під час входу сервер надсилає запит (challenge), ваш клієнт підписує цей запит приватним ключем, а сервер перевіряє підпис за допомогою публічного ключа. Приватний ключ ніколи не залишає ваш пристрій, тому перехоплення даних під час передачі неможливе, а вкрадений з сервера файл не можна використати повторно. Зламаний сервер може розкрити лише публічні ключі, які не можна використати для входу на інші системи.
Чи варто використовувати один і той самий SSH-ключ для всіх серверів?
Використовувати один ключ для багатьох серверів — це правильно, якщо цей ключ зберігається лише на одному пристрої. Правило полягає в тому, що ключ має бути один на пристрій, а не на сервер: публічний ключ вашого ноутбука має бути на кожному сервері, до якого потрібен доступ з ноутбука, а ваш стаціонарний комп'ютер повинен мати свій власний ключ. Це спрощує відкликання доступу: якщо пристрій втрачено, потрібно видалити лише один рядок на кожному сервері, і інші пристрої продовжуватимуть працювати.
Які права доступу мають бути у директорії .ssh та файлі authorized_keys?
Встановіть 700 для ~/.ssh та 600 для authorized_keys та для кожного приватного ключа. Власником файлів має бути обліковий запис, який їх використовує. За замовчуванням sshd працює з StrictModes yes, тому, якщо будь-хто інший, крім вас, має право на запис у файл або домашню директорію, sshd ігноруватиме ваш ключ. Єдиним слідком буде Authentication refused: bad ownership or modes у журналі auth сервера або journal.
Як видалити SSH-ключ із сервера?
Видаліть рядок із ключем із файлу ~/.ssh/authorized_keys у відповідному обліковому записі. Знайдіть потрібний рядок за коментарем (текст після самого ключа). Нові спроби входу з цим ключем одразу не будуть успішними, але вже відкриті сесії залишаться активними. Якщо пристрій було викрадено, завершіть усі активні сесії для цього пристрою. Повторіть цю процедуру на кожному сервері, куди було скопійовано ключ.
Чи потрібно встановлювати passphrase для SSH-ключа?
Для ключа на ноутбуці або стаціонарному комп'ютері — так. Passphrase шифрує файл ключа, тому вкрадена або викрадена копія сама по собі буде марною. Використання ssh-agent означає, що ви вводите пароль лише один раз за сесію, а не при кожному підключенні. Ключі, які використовуються автоматизацією на сервері, зазвичай не мають passphrase, оскільки там немає людини для його введення; захищайте такі ключі шляхом обмеження прав облікового запису, який вони використовують.