Як створити ключ клієнта VPN і подати CSR на підпис
Тримайте приватний ключ у клієнта й надсилайте лише запит. Перевірте CSR, затвердьте особу, підпишіть із явними розширеннями, потім підтвердьте пару.
Рано чи пізно користувач VPN запропонує надіслати приватний ключ поштою, щоб адміністратор міг видати сертифікат, і саме від цієї пропозиції треба відмовитися. Робочий процес тримає ключ у клієнта від першої команди: клієнт його створює, надсилає запит на підпис сертифіката, видавець перевіряє його й авторизує, а підписаний сертифікат повертається й лежить поруч із ключем, який його створив. Контрольний список нижче відмовляє закрито на кожному кроці, і в цьому сенс, бо два з п'яти кроків — саме ті, які люди пропускають, коли поспішають.
Крок 1: створіть ключ там, де він житиме
Створюйте на машині, яка зберігатиме ключ, і залишайте його там. Програмний ключ потрапляє у файл із суворими правами; ключ на апаратній основі або в керованому сховищі ніколи не стає файлом, а шлях його реєстрації зазвичай окремий інструмент, а не команда OpenSSL. Так чи інакше, нікому не потрібно бачити приватну половину.
Програмний процес виглядає так, ключ і запит створюються в одній сесії:
umask 077
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out client.key
openssl req -new -key client.key -out client.csr -subj "/CN=alice-vpn/O=Example"Рядок umask важливіший, ніж здається. Без нього ключ записується читабельним для всіх у системі з дозвільними правами за замовчуванням, а копіювання файлу пізніше це поширює. Повторне використання наявного ключа законне, коли він уже захищений і відповідає вашій політиці; створювати новий для кожного пристрою легше обґрунтувати.
Крок 2: помістіть особу в запит, а не в лист
Вирішіть, що VPN насправді автентифікує, до створення запиту, бо ця відповідь належить усередину CSR. OpenVPN традиційно прив'язує особу клієнта до спільного імені сертифіката, а такі інструменти, як strongSwan, зіставляють рядок особи із суб'єктом або альтернативним ім'ям суб'єкта. Лист, у якому сказано, що мене звати alice, не є доказом, а запит, у суб'єкті якого сказано те саме, лише трохи кращий.
Додайте альтернативне ім'я суб'єкта, коли ваш перевіряльник його перевіряє, оскільки сучасне зіставлення часто ігнорує старий CN:
openssl req -new -key client.key -out client.csr \
-subj "/CN=alice-vpn/O=Example" \
-addext "subjectAltName=DNS:alice-vpn"Тримайте CN коротким, стабільним і прив'язаним до облікового запису, а не до моделі ноутбука. Ім'я, що містить серійний номер пристрою користувача, — це проблема підтримки, яка чекає на першу заміну обладнання.
Крок 3: перевірте запит, перш ніж підписувати його
Видавець перевіряє дві різні речі, і їх змішування — класична помилка. По-перше, що запит внутрішньо узгоджений: підпис перевіряється проти відкритого ключа, який він несе. По-друге, що заявник має право на те, що вимагає запит, і на це не може відповісти жодна криптографічна перевірка.
Механічна частина — одна команда, і вона має вивести результат перевірки разом із суб'єктом:
openssl req -in client.csr -noout -verify -subject
openssl req -in client.csr -noout -pubkey | openssl pkey -pubin -noout -textЗверніть увагу, що це доводить. Запит, що пройшов перевірку, показує лише те, що відправник володів відповідним приватним ключем на момент подання; він не доводить, що відправник — це особа, названа в суб'єкті, і не авторизує доступ до запитаної групи чи маршруту. Перевірка реєстрації — окремі ворота, і запит на групу, яку ніхто не затвердив, слід відхилити, а не тихо відредагувати.
Крок 4: авторизуйте, потім підпишіть із явними розширеннями
Підписування — це місце, де CA вирішує політику, а не приймає запит дослівно. Термін дії, використання ключа й розширення ролі належать до файлу розширень, а не до значень за замовчуванням, які ви не згадаєте через пів року. Клієнтському сертифікату для автентифікації VPN як призначення потрібна автентифікація клієнта.
cat > client.ext <<'EOF'
basicConstraints = CA:FALSE
keyUsage = digitalSignature
extendedKeyUsage = clientAuth
EOF
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -days 365 -extfile client.ext -out client.crtВикористовуйте -CAserial з наявним файлом серійних номерів, якщо він уже застосовується, і тримайте ключ CA офлайн або в тому захищеному сховищі, яке називає ваша політика. Серійні номери сертифікатів мають бути унікальними для кожного видавця; перестворення файлу серійних номерів з нуля ризикує колізіями, які роблять відкликання неоднозначним.
Записуйте, що було видано: серійний номер, суб'єкт, запитану особу, особу, що затвердила, і термін. Саме на цей запис пізніше спирається рішення про відкликання, і його не можна відновити лише з сертифіката, якщо слід реєстрації живе тільки в поштовій скриньці.
Крок 5: установіть його поруч із відповідним ключем і доведіть пару
Клієнт отримує сертифікат і ланцюжок видавця, ніколи не ключ. Перед підключенням підтвердьте, що сертифікат справді утворює пару з ключем, який уже лежить на диску, бо невідповідна пара дає заплутану помилку рукостискання значно пізніше:
openssl x509 -in client.crt -noout -pubkey | openssl pkey -pubin -outform DER | openssl sha256
openssl pkey -in client.key -pubout -outform DER | openssl sha256Обидва дайджести мають збігтися. Потім підключіться й підтвердьте, що особа, яку реєструє сервер, — це та, яку ви авторизували, а не просто те, що тунель піднявся. Якщо ключ втрачено або пристрій замінено, відповідь — відкликання плюс новий запит із нового пристрою; прохання до адміністратора надіслати ключ звідкись інше не відновлює оригінал і тихо ламає модель, яка робила запит безпечним.