Як створити сертифікат захисту

ДОВІДНИК З NODE-RED українською мовою

Як створити сертифікат захисту

by Julian Knight

джерело

Створіть сертифікати для Node-RED, яким довіряють усі сучасні браузери. Це дозволить отримати доступ до Node-RED (та інших служб) через зашифроване посилання HTTPS.

Задача

Ох! Чому так важко створювати та керувати довіреними сертифікатами для “внутрішніх” сервісів! Хоча ви можете створювати власні “самопідписані” сертифікати, тепер усі сучасні веб-переглядачі відзначають їх як небезпечні та намагаються не допустити до них доступу. Це неправильно. Веб-переглядачі повинні дозволяти доступ до сертифікатів, що підписуються самостійно, якщо вони вказують на IP-адресу без маршрутизації (наприклад, 192.168. *. * Або 10. *. *. *) Або недійсний кореневий домен, такий як .something.local .

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

Можливі виправлення

Ви можете вручну додати новий (самопідписаний) кореневий сертифікат на всі пристрої, які потребують доступу до ваших внутрішніх сервісів, щоб довіряти вашим самопідписаним сертифікатам - спробуйте пройти повз решту сім’ї!

Єдиною іншою альтернативою є використання довіреного CA (центра сертифікації). Оскільки я припускаю, що ви робите це для тестування або для використання вдома, я також вважаю, що ви не хочете витрачати багато грошей. Довірені сертифікати зазвичай коштують - багато! Часто 100 доларів США на рік і більше.

Однак є один постачальник, який видає безкоштовні довірені сертифікати. Let’s Encrypt. Це чудовий сервіс за чудову ціну. Але це має деякі накладні витрати.

Це ніколи не просто

Гаразд, тож припускаючи, що ми хочемо використовувати шифр Let’s Encrypt (LE), які проблеми нам зараз потрібно подолати?

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

    Зауважте, що сертифікати, як правило, видаються на конкретні доменні імена, так що www.thing.com та thing.com є різними іменами. Ми не хочемо постійно з цим возитися, особливо якщо ми робимо багато тестів. Тож тепер ми можемо використовувати сертифікат «wildcard» для * .thing.com

  2. Далі, ми повинні мати спосіб для серверів Let’s Encrypt переконатися, що наше доменне ім’я насправді наше, з чим щось робити.

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

    На щастя, LE зараз має альтернативу під назвою DNS-01. На жаль, для цього потрібна наша DNS (служба доменних імен) для підтримки певного типу захищеного API. Для цього ми можемо використовувати Cloudflare або будь-яку з інших служб DNS, перелічених на веб-сайті LE.

  3. Нарешті, нам потрібно поновлювати сертифікат кожні 3 місяці, тому що це все, що Let’s Encrypt дозволяє нам зберігати сертифікат. Це біль, але вона має деякі переваги для безпеки.

Давайте розглянемо деталі, як це зробити.

1. Отримайте домен

Нам потрібен домен, і він нам потрібен для того, щоб він міг, принаймні певною мірою, контролювати. Тож деякі безкоштовні “динамічні DNS-сервіси”, ймовірно, не скоротять його. Однак ми можемо отримати власний домен за кілька фунтів/доларів на рік, тому продовжуйте робити це. Збережіть собі біль у наступному шматочку, використовуючи Cloudflare для реєстрації вашого домену.

Щойно ми маємо домен, нам потрібно дозволити йому керувати DNS, який підтримує API підтвердження DNS-01. Можливо, вам пощастить, що ваш реєстратор домену вже це підтримує. У більшості випадків вони не будуть. Тож тепер ви повинні передати контроль над налаштуваннями DNS тому, хто, як Cloudflare, який безкоштовний сервіс, є достатнім для того, що нам потрібно. Ваш реєстратор домену підкаже, як змінити сервери імен, які керують вашим доменом. Не хвилюйтеся, ваш реєстратор залишається загальним контролером, тому оновлення не є проблемою.

Оскільки ми будемо використовувати сертифікат підстановки, нам не потрібно турбуватися про налаштування конкретних імен.

Крім того, оскільки ми будемо використовувати перевірку DNS-01, нам не потрібно нічого вказувати на нашу загальнодоступну IP-адресу. Використовуйте параметри DNS, щоб вказати запис DNS за замовчуванням на фіктивну IP-адресу, наприклад, “10.10.10.10”. Це добре, і це означає, що ми не будемо просочувати будь-яку інформацію про нашу приватну мережу.

2a. Встановіть клієнт для шифрування Let’s

Клієнтів для ЛЕ багато, дивіться список на їхньому веб-сайті. Для цієї посади я буду використовувати Raspberry Pi, оскільки в мене працює постійно діюча система домашньої автоматизації. Ви також можете використовувати NAS або будь-який ПК. Навіть деякі маршрутизатори, такі як колись чудовий Ubiquity EdgeRouter Lite можна використовувати.

Я збираюся використовувати сторонній сценарій BASH (командного рядка Linux), оскільки це набагато простіше, ніж офіційний сценарій на основі Python.

З вашого Pi дотримуйтесь інструкції щодо встановлення сценарію. Запустіть віддалений командний рядок за допомогою клієнта SSH із зручного комп’ютера. Увійдіть, використовуючи ідентифікатор, якому дозволено здійснювати адміністрування на Pi. Потім встановіть скрипт, використовуючиcurl https://get.acme.sh | sh. Зауважте, що я не намагався отримати root, оскільки мені потрібно використовувати сертифікат із сервісом Node.JS, який не працює у всьому світі як root (це найкраща практика, не запускайте речі як root, що відкриває додаткову безпеку питання). Я також керував alias acme.sh=~/.acme.sh/acme.sh вручну, а не виходив і знову входити, щоб забрати визначений псевдонім.

2b. Отримайте подробиці API Cloudflare

Отже, ми готові зараз? Не зовсім. Спочатку нам потрібно десь запустити клієнтський інструмент, який спочатку отримає наш перший сертифікат, а потім періодично запускається для відновлення сертифіката.

Оскільки ми використовуємо перевірку DNS-01 з Cloudflare, нам потрібні дані доступу до API. Перейти вперед до інструкцій acme.sh до частини про DNS API integration , оскільки саме це нам потрібно щоб уникнути впливу наших внутрішніх серверів в Інтернет. Нам потрібен файл конфігурації. Інструкції знаходяться у папці dnsapi.

Увійдіть у свій обліковий запис Cloudflare, перейдіть до розділу “Мій профіль” під значком маленької людини вгорі праворуч. Візьміть перевірену електронну адресу, потім прокрутіть донизу «Ключі API» та натисніть «Переглянути» проти «Глобального ключа API». Поки ви перебуваєте там, увімкніть двофакторну автентифікацію, щоб захистити свій акаунт та послуги. Зберігайте цю інформацію в безпеці! Якщо хтось захопить це, він може змінити ваші DNS та інші налаштування.

Випустіть команди export CF_Key="sdfsdfsdfljlbjkljlkjsdfoiwje" && export CF_Email="xxxx@sss.com", які тимчасово поміщають інформацію про безпеку в змінні середовища.

2c. Отримайте наш перший сертифікат

Тепер ми готові спробувати отримати перший сертифікат. Виконайте наступне з командного рядка SSH:

acme.sh --issue --dns dns_cf -d example.com -d *.example.com

Очевидно заміна доменних імен на власні. Запис, який починається з “*”, дає сертифікат підстановки, щоб ви могли використовувати цей сертифікат на будь-якому субдомені, наприклад “www.example.com” або fred.example.com.

3. Поновлення сертифікату

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

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

acme.sh --upgrade --auto-upgrade

Використання імен замість IP-адрес

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

Зауважте, що ви більше не можете посилатися на свої послуги за IP-адресою.

Наприклад pi.example.com, але не ` 192.168.1.20`.

Використання IP-адреси призведе до помилки в сучасних браузерах.

Таким чином, невелика зморшка у нашому прагненні позбутися помилок браузера, оскільки більшість домашніх серверів отримують доступ через IP-адресу, а не ім’я. Як це виправити? У нас є пара варіантів.

  1. Використовуйте службу DHCP або DNS вашого маршрутизатора, щоб визначити назви локальних служб.

  2. Встановіть службу DNS на локальний пристрій.

  3. Оновіть файл hosts на кожному клієнтському пристрої.

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

І 1, і 2 потребують певної конфігурації. Ми робимо імена, які вказують на локальні IP-адреси. Як це зробити, залежить від маршрутизатора або сервера DNS, який у вас є.

В будь-якому випадку ми дійсно хочемо, щоб фіксована IP-адреса працювала, щоб наш Pi (або інший пристрій, що працює з нашими послугами) завжди був за однією адресою. Усі маршрутизатори повинні мати можливість це робити, тому шукайте налаштування DHCP. Вам потрібно буде знати MAC-адресу пристрою, він виглядає приблизно як b8:27:eb:df:49:7e (ви можете бачити це з великої літери та / або без кольорових знаків). На сторінках DHCP маршрутизатора буде список активних “оренди”, який показуватиме цю інформацію. Ви використовуєте цю адресу, яка визначена мережевим інтерфейсом на пристрої, щоб видавати фіксовану IP-адресу через службу DHCP. Переконайтеся, що ваші фіксовані адреси не збігаються з діапазоном, визначеним для DHCP, щоб динамічно видавати.

Іноді ваш DHCP-сервер дасть вам змогу визначити ім’я для цієї конфігурації. Це чудово, тому що тепер ви можете вказати ім’я для включення домену, якому видається сертифікат. напр. pi.example.com.

Ubiquiti EdgeRouter дозволить вам визначити імена вручну за допомогою майстра під назвою “[Імена хостів DNS] (https://192.168.1.1/#Wizard/feature/DNS_host_names)”. Деякі інші маршрутизатори можуть надати вам доступ до файлу хостів маршрутизатора.

Якщо ви не можете цього зробити на своєму маршрутизаторі, вам знадобиться DNS-сервер, який дозволить вам визначити імена для IP-адрес. Це трохи складніше і виходить за рамки цього, вже досить тривалого повідомлення в блозі.

Використання вашого сертифіката

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

Ви можете налаштувати більшість сервісів на основі TCP/IP для використання TLS (Transport Layer Security), для чого ми в основному хочемо наш сертифікат. Більшість людей будуть знайомі з доступом до веб-сторінок через HTTPS, який TLS застосовується до HTTP. Але ми також можемо використовувати сертифікат для захисту зв’язку для передачі файлів (FTPS або SFTP), електронної пошти (SMTPS, IMAPS тощо).

Node-RED

Node-RED - це сервіс, побудований на NodeJS та ExpressJS. Він створює веб-сервер, який ми можемо захистити, використовуючи наш сертифікат. Цей самий сертифікат також буде використовуватися для забезпечення захисту websocket.

Щойно ви змінили налаштування, наведені нижче, не забудьте отримати доступ до Node-RED, використовуючи ім’я сервера замість IP-адреси. Вам потрібно буде перезапустити сервіс Node-RED.

settings.js

У цьому файлі ми налаштовуємо Node-RED для використання HTTPS. Зверніть увагу, що налаштування такі ж, як у NodeJS, тому ви можете перевірити будь-які інші налаштування в документації на NodeJS.

Файл settings.js знаходиться у вашій папці ` userDir, яка, як правило, ~/.node-red , якщо вона встановлена відповідно до інструкцій на веб-сайті Node-RED. ~` - “домашня” папка для ідентифікатора користувача, що виконує сервіс Node-RED.

...
module.exports = {
    ...
    const path = require('path');
    const fs   = require('fs');
    ...
    https: {
        // Don't forget to adjust the paths below
        // according to your installation
        key: fs.readFileSync(
            path.join(
                '..','.acme.sh','<server_name>', '<server_name>.key'
            )
        ),
        cert: fs.readFileSync(
            path.join(
                '..','.acme.sh','<server_name>', 'fullchain.cer'
            )
        ),
    },
    ...
}

Where <server_name> is something like pi2.example.com - whatever you have defined as the name associated with the IP address.