= Выпуск и автоматическое обновление сертификата SSL для платы SW-01 = Веб-интерфейс платы SW-01 предоставляет возможность ручной установки сертификата SSL. Однако срок действия сертификатов имеет свойство истекать в самый неподходящий момент. При ручной установке и обновлении сертификатов пользователь вынужден самостоятельно следить за сроком действия всех установленных сертификатов и своевременно их обновлять. Это не очень удобно, а также есть шанс забыть вовремя обновить какой-либо из сертификатов. Кроме этого генерация ключа сертификата на одном хосте с последующим его копированием на другой хост (тем более по небезопасному протоколу HTTP!) является не лучшей практикой в плане безопасности. В данной статье рассматривается альтернативный вариант получения и последующего полностью автоматического обновления сертификата SSL для платы SW-01. == Исходные данные == Прежде чем приступить к делу, нам потребуется: - Запись в DNS имени хоста, по которому будет происходить обращение к веб-интерфейсу платы SW-01. В данном примере мы будем использовать имя samurai-res.kolez.com. - Веб-интерфейс платы SW-01 должен быть доступен из интернета по TCP порту 80 (HTTP) или 443 (HTTPS). Для работы по HTTPS потребуется установить в плату любой временный сертификат SSL: он может быть самоподписанный или даже с истекшим сроком годности - удостоверяющий центр не будет проверять валидность сертификата. == Установка uacme == Выпуск и обновление сертификатов мы будем осуществлять с использованием стандартного в этой области протокола ACMEv2. Для этого установим программный пакет uacme, содержащий "легковесный" клиент ACMEv2. Подключаемся к плате SW-01 терминалом по протоколу SSH и первым делом обновляем список пакетов командой `opkg update`: {{{ root@sw01:~# opkg update Downloading https://repo.adc-line.ru/sw-01/ipk/all/Packages.gz. Inflating https://repo.adc-line.ru/sw-01/ipk/all/Packages.gz. Updated list of available packages in /var/lib/opkg/all. Downloading https://repo.adc-line.ru/sw-01/ipk/all/Packages.sig. Signature check passed. Downloading https://repo.adc-line.ru/sw-01/ipk/armv5te/Packages.gz. Inflating https://repo.adc-line.ru/sw-01/ipk/armv5te/Packages.gz. Updated list of available packages in /var/lib/opkg/armv5te. Downloading https://repo.adc-line.ru/sw-01/ipk/armv5te/Packages.sig. Signature check passed. Downloading https://repo.adc-line.ru/sw-01/ipk/at91sam9g20ek/Packages.gz. Inflating https://repo.adc-line.ru/sw-01/ipk/at91sam9g20ek/Packages.gz. Updated list of available packages in /var/lib/opkg/at91sam9g20ek. Downloading https://repo.adc-line.ru/sw-01/ipk/at91sam9g20ek/Packages.sig. Signature check passed. }}} Теперь устанавливаем пакет `uacme` командой `opkg install uacme`: {{{ root@sw01:~# opkg install uacme Installing uacme (1.7.4-r0.9) on root. Downloading https://repo.adc-line.ru/sw-01/ipk/armv5te/uacme_1.7.4-r0.9_armv5te.ipk. libcurl4: unsatisfied recommendation for curl-certs Installing libcurl4 (7.50.3-r6.0.9) on root. Downloading https://repo.adc-line.ru/sw-01/ipk/armv5te/libcurl4_7.50.3-r6.0.9_armv5te.ipk. Installing libnghttp2-14 (1.26.0-r0.9) on root. Downloading https://repo.adc-line.ru/sw-01/ipk/armv5te/libnghttp2-14_1.26.0-r0.9_armv5te.ipk. Configuring libnghttp2-14. Configuring libcurl4. Configuring uacme. }}} == Создание учетной записи == Прежде чем запрашивать сертификат, необходимо создать учетную запись в удостоверяющем центре. Для этого выполняет команду `uacme new`. При создании учетной записи будет сгенерирован секретный ключ, которым будут подписываться все запросы к удостоверяющему центру. По умолчанию uacme генерирует ключи RSA размером 2048 бит. Тип ключа можно изменить на EC, добавив опцию `-t EC`. Размер генерируемого ключа можно изменить опцией `-b`, подробности смотрите в [https://ndilieto.github.io/uacme/uacme.html справочном руководстве] uacme. По умолчанию uacme использует каталог конфигурации (каталог, в котором хранятся сертификаты и ключи) в `/etc/ssl/uacme`. Создадим этот каталог: {{{ root@sw01:~# mkdir -p /etc/ssl/uacme }}} Теперь создадим учетную запись с ключом EC размером 384 бита. В процессе выполнения uacme предложит прочитать и принять условия использования сервиса, введя "y": {{{ root@sw01:~# uacme -v -t EC -b 384 new uacme: version UNKNOWN starting on Thu, 23 Mar 2023 11:13:59 +0000 uacme: loading key from /etc/ssl/uacme/private/key.pem uacme: fetching directory at https://acme-v02.api.letsencrypt.org/directory uacme: creating new account at https://acme-v02.api.letsencrypt.org/acme/new-acct uacme: type 'y' to accept the terms at https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf y uacme: account created at https://acme-v02.api.letsencrypt.org/acme/acct/1023358517 }}} == Выпуск сертификата == Для выпуска сертификата введем команду `uacme issue samurai-res.kolez.com`, также выбрав ключ EC размером 384 бита. При выполнении этой команды удостоверяющий центр попросит установить на веб-сервере специальный файл-токен чтобы убедиться, что мы имеем контроль над сервером хоста, для которого получаем сертификат. Для установки и последующего удаления токена в пакете uacme уже имеется специальный скрипт `/usr/share/uacme/uacme.sh`, который необходимо указать в команде uacme с помощью опции `-h`: {{{ root@sw01:~# uacme -v -t EC -b 384 -h /usr/share/uacme/uacme.sh issue samurai-res.kolez.com uacme: version UNKNOWN starting on Thu, 23 Mar 2023 11:22:35 +0000 uacme: loading key from /etc/ssl/uacme/private/key.pem uacme: created directory /etc/ssl/uacme/private/samurai-res.kolez.com uacme: created directory /etc/ssl/uacme/samurai-res.kolez.com/ uacme: loading key from /etc/ssl/uacme/private/samurai-res.kolez.com/key.pem uacme: /etc/ssl/uacme/private/samurai-res.kolez.com/key.pem not found uacme: generating new 384-bit EC key uacme: key saved to /etc/ssl/uacme/private/samurai-res.kolez.com/key.pem uacme: checking existence and expiration of /etc/ssl/uacme/samurai-res.kolez.com/cert.pem uacme: /etc/ssl/uacme/samurai-res.kolez.com/cert.pem does not exist uacme: generating certificate request uacme: fetching directory at https://acme-v02.api.letsencrypt.org/directory uacme: retrieving account at https://acme-v02.api.letsencrypt.org/acme/new-acct uacme: account location: https://acme-v02.api.letsencrypt.org/acme/acct/1023358517 uacme: creating new order at https://acme-v02.api.letsencrypt.org/acme/new-order uacme: order location: https://acme-v02.api.letsencrypt.org/acme/order/1023358517/171799917907 uacme: retrieving authorization at https://acme-v02.api.letsencrypt.org/acme/authz-v3/213321949517 uacme: running /usr/share/uacme/uacme.sh begin http-01 samurai-res.kolez.com xEIoLW2A0Mdxnky4i8D2Ehp6dZlPmUdX3E7agiBloK4 xEIoLW2A0Mdxnky4i8D2Ehp6dZlPmUdX3E7agiBloK4.kh7u922KG_AhdSqfbFhPjz_n5poyn31Jw2NqUyGCbyo uacme: starting challenge at https://acme-v02.api.letsencrypt.org/acme/chall-v3/213321949517/4isMwQ uacme: polling challenge status at https://acme-v02.api.letsencrypt.org/acme/chall-v3/213321949517/4isMwQ uacme: running /usr/share/uacme/uacme.sh done http-01 samurai-res.kolez.com xEIoLW2A0Mdxnky4i8D2Ehp6dZlPmUdX3E7agiBloK4 xEIoLW2A0Mdxnky4i8D2Ehp6dZlPmUdX3E7agiBloK4.kh7u922KG_AhdSqfbFhPjz_n5poyn31Jw2NqUyGCbyo uacme: polling order status at https://acme-v02.api.letsencrypt.org/acme/order/1023358517/171799917907 uacme: finalizing order at https://acme-v02.api.letsencrypt.org/acme/finalize/1023358517/171799917907 uacme: polling order status at https://acme-v02.api.letsencrypt.org/acme/order/1023358517/171799917907 uacme: retrieving certificate at https://acme-v02.api.letsencrypt.org/acme/cert/04dd142ab955eef7232fd502f73b49f878a2 uacme: saving certificate to /etc/ssl/uacme/samurai-res.kolez.com/cert.pem.tmp uacme: renaming /etc/ssl/uacme/samurai-res.kolez.com/cert.pem.tmp to /etc/ssl/uacme/samurai-res.kolez.com/cert.pem }}} Наш сертификат выпущен и находится в файле `/etc/ssl/uacme/samurai-res.kolez.com/cert.pem`, а ключ сертификата - в файле `/etc/ssl/uacme/private/samurai-res.kolez.com/key.pem`. Для того чтобы этот сертификат начал использоваться веб-сервером платы SW-01, создадим симлинки на сертификат и ключ `/usr/share/sw/server.cer` и `/usr/share/sw/server.key` соответственно: {{{ root@sw01:~# cd /usr/share/sw/ root@sw01:/usr/share/sw# ln -s /etc/ssl/uacme/samurai-res.kolez.com/cert.pem server.cer root@sw01:/usr/share/sw# ln -s /etc/ssl/uacme/private/samurai-res.kolez.com/key.pem server.key }}} После этого сервер платы SW-01 автоматически обнаружит и начнет использовать наш сертификат (для этого будет перезапущен сервер HTTPS). Мы можем убедиться в том, что все работает правильно, открыв веб-браузером URL `https://samurai-res.kolez.com/`. == Настройка автоматического обновления сертификата == Для настройки автоматического перевыпуска сертификата нам потребуется установить пакет `cron`: {{{ root@sw01:/usr/share/sw# opkg install cron Installing cron (3.0pl1-r8.9) on root. Downloading https://repo.adc-line.ru/sw-01/ipk/armv5te/cron_3.0pl1-r8.9_armv5te.ipk. Configuring cron. Adding system startup for /etc/init.d/cron. System startup links for /etc/init.d/cron already exist. Stopping Vixie-cron. Starting Vixie-cron. }}} Теперь настроим выполнение команды обновления сертификата каждый день в 0:15 UTC. Для этого выполним команду `crontab -e`. Запустится текстовый редактор vi. В редакторе переходим в режим вставки текста нажатием `i` и вводим следующую строку: {{{ 15 0 * * * /usr/bin/uacme -t EC -b 384 -h /usr/share/uacme/uacme.sh issue samurai-res.kolez.com }}} Теперь выходим из режима вставки нажатием `ESC`, а затем сохраняем отредактированный текст и завершаем редактор командой `:wq`. Как видно выше, для обновления сертификата используется та же команда, что и для его первоначального выпуска (только без опции `-v`, чтобы uacme не выводила никакого текста в ходе выполнения, если только не произошла ошибка). Каждый день в 0:15 UTC cron будет выполнять заданную нами выше команду. Если до истечения срока действия сертификата остается больше 30 дней (это значение можно изменть опцией `-d`), uacme ничего не будет делать. Если же срок действия текущего сертификата заканчивается раньше, uacme запросит выпуск нового сертификата. В случае успеха старый файл сертификата будет заменен новым (копия же старого сертификата будет сохранена под другим именем в том же каталоге). HTTPS сервер платы SW-01 обнаружит изменение файла сертификата и перезапустит сервер с использованием нового сертификата автоматически. == Заключение == В данном примере мы пользовались услугами удостоверяющего центра Let's Encrypt, но вместо него можно использовать (почти) любой другой удостоверяющий центр, поддерживающий выпуск сертификатов по протоколу ACMEv2. Если это возможно, рекомендуется использовать ключи типа EC, так как алгоритм RSA требует намного большего объема вычислений чем алгоритм EC, при этом производительность процессора платы SW-01 не очень велика, что может приводить к значительным задержкам. Так, при использовании ключа RSA размером 4096 бит установка одного соединения TLS длится около 2 секунд. Для сравнения: при использовании ключа EC размером 384 бита установка соединения TLS длится лишь 150 мс.