| 1 | = Выпуск и автоматическое обновление сертификата SSL для платы SW-01 = |
| 2 | |
| 3 | Веб-интерфейс платы SW-01 предоставляет возможность ручной установки сертификата SSL. Однако срок действия сертификатов имеет свойство истекать в самый неподходящий момент. При ручной установке и обновлении сертификатов пользователь вынужден самостоятельно следить за сроком действия всех установленных сертификатов и своевременно их обновлять. Это не очень удобно, а также есть шанс забыть вовремя обновить какой-либо из сертификатов. Кроме этого генерация ключа сертификата на одном хосте с последующим его копированием на другой хост (тем более по небезопасному протоколу HTTP!) является не лучшей практикой в плане безопасности. В данной статье рассматривается альтернативный вариант получения и последующего полностью автоматического обновления сертификата SSL для платы SW-01. |
| 4 | |
| 5 | == Исходные данные == |
| 6 | |
| 7 | Прежде чем приступить к делу, нам потребуется: |
| 8 | |
| 9 | - Запись в DNS имени хоста, по которому будет происходить обращение к веб-интерфейсу платы SW-01. В данном примере мы будем использовать имя samurai-res.kolez.com. |
| 10 | |
| 11 | - Веб-интерфейс платы SW-01 должен быть доступен из интернета по TCP порту 80 (HTTP) или 443 (HTTPS). Для работы по HTTPS потребуется установить в плату любой временный сертификат SSL: он может быть самоподписанный или даже с истекшим сроком годности - удостоверяющий центр не будет проверять валидность сертификата. |
| 12 | |
| 13 | == Установка uacme == |
| 14 | |
| 15 | Выпуск и обновление сертификатов мы будем осуществлять с использованием стандартного в этой области протокола ACMEv2. Для этого установим программный пакет uacme, содержащий "легковесный" клиент ACMEv2. Подключаемся к плате SW-01 терминалом по протоколу SSH и первым делом обновляем список пакетов командой `opkg update`: |
| 16 | |
| 17 | {{{ |
| 18 | root@sw01:~# opkg update |
| 19 | Downloading https://repo.adc-line.ru/sw-01/ipk/all/Packages.gz. |
| 20 | Inflating https://repo.adc-line.ru/sw-01/ipk/all/Packages.gz. |
| 21 | Updated list of available packages in /var/lib/opkg/all. |
| 22 | Downloading https://repo.adc-line.ru/sw-01/ipk/all/Packages.sig. |
| 23 | Signature check passed. |
| 24 | Downloading https://repo.adc-line.ru/sw-01/ipk/armv5te/Packages.gz. |
| 25 | Inflating https://repo.adc-line.ru/sw-01/ipk/armv5te/Packages.gz. |
| 26 | Updated list of available packages in /var/lib/opkg/armv5te. |
| 27 | Downloading https://repo.adc-line.ru/sw-01/ipk/armv5te/Packages.sig. |
| 28 | Signature check passed. |
| 29 | Downloading https://repo.adc-line.ru/sw-01/ipk/at91sam9g20ek/Packages.gz. |
| 30 | Inflating https://repo.adc-line.ru/sw-01/ipk/at91sam9g20ek/Packages.gz. |
| 31 | Updated list of available packages in /var/lib/opkg/at91sam9g20ek. |
| 32 | Downloading https://repo.adc-line.ru/sw-01/ipk/at91sam9g20ek/Packages.sig. |
| 33 | Signature check passed. |
| 34 | }}} |
| 35 | |
| 36 | Теперь устанавливаем пакет `uacme` командой `opkg install uacme`: |
| 37 | |
| 38 | {{{ |
| 39 | root@sw01:~# opkg install uacme |
| 40 | Installing uacme (1.7.4-r0.9) on root. |
| 41 | Downloading https://repo.adc-line.ru/sw-01/ipk/armv5te/uacme_1.7.4-r0.9_armv5te.ipk. |
| 42 | libcurl4: unsatisfied recommendation for curl-certs |
| 43 | Installing libcurl4 (7.50.3-r6.0.9) on root. |
| 44 | Downloading https://repo.adc-line.ru/sw-01/ipk/armv5te/libcurl4_7.50.3-r6.0.9_armv5te.ipk. |
| 45 | Installing libnghttp2-14 (1.26.0-r0.9) on root. |
| 46 | Downloading https://repo.adc-line.ru/sw-01/ipk/armv5te/libnghttp2-14_1.26.0-r0.9_armv5te.ipk. |
| 47 | Configuring libnghttp2-14. |
| 48 | Configuring libcurl4. |
| 49 | Configuring uacme. |
| 50 | }}} |
| 51 | |
| 52 | == Создание учетной записи == |
| 53 | |
| 54 | Прежде чем запрашивать сертификат, необходимо создать учетную запись в удостоверяющем центре. Для этого выполняет команду `uacme new`. При создании учетной записи будет сгенерирован секретный ключ, которым будут подписываться все запросы к удостоверяющему центру. По умолчанию uacme генерирует ключи RSA размером 2048 бит. Тип ключа можно изменить на EC, добавив опцию `-t EC`. Размер генерируемого ключа можно изменить опцией `-b`, подробности смотрите в [https://ndilieto.github.io/uacme/uacme.html справочном руководстве] uacme. По умолчанию uacme использует каталог конфигурации (каталог, в котором хранятся сертификаты и ключи) в `/etc/ssl/uacme`. Создадим этот каталог: |
| 55 | |
| 56 | {{{ |
| 57 | root@sw01:~# mkdir -p /etc/ssl/uacme |
| 58 | }}} |
| 59 | |
| 60 | Теперь создадим учетную запись с ключом EC размером 384 бита. В процессе выполнения uacme предложит прочитать и принять условия использования сервиса, введя "y": |
| 61 | |
| 62 | {{{ |
| 63 | root@sw01:~# uacme -v -t EC -b 384 new |
| 64 | uacme: version UNKNOWN starting on Thu, 23 Mar 2023 11:13:59 +0000 |
| 65 | uacme: loading key from /etc/ssl/uacme/private/key.pem |
| 66 | uacme: fetching directory at https://acme-v02.api.letsencrypt.org/directory |
| 67 | uacme: creating new account at https://acme-v02.api.letsencrypt.org/acme/new-acct |
| 68 | uacme: type 'y' to accept the terms at https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf |
| 69 | y |
| 70 | uacme: account created at https://acme-v02.api.letsencrypt.org/acme/acct/1023358517 |
| 71 | }}} |
| 72 | |
| 73 | == Выпуск сертификата == |
| 74 | |
| 75 | Для выпуска сертификата введем команду `uacme issue samurai-res.kolez.com`, также выбрав ключ EC размером 384 бита. При выполнении этой команды удостоверяющий центр попросит установить на веб-сервере специальный файл-токен чтобы убедиться, что мы имеем контроль над сервером хоста, для которого получаем сертификат. Для установки и последующего удаления токена в пакете uacme уже имеется специальный скрипт `/usr/share/uacme/uacme.sh`, который необходимо указать в команде uacme с помощью опции `-h`: |
| 76 | |
| 77 | {{{ |
| 78 | root@sw01:~# uacme -v -t EC -b 384 -h /usr/share/uacme/uacme.sh issue samurai-res.kolez.com |
| 79 | uacme: version UNKNOWN starting on Thu, 23 Mar 2023 11:22:35 +0000 |
| 80 | uacme: loading key from /etc/ssl/uacme/private/key.pem |
| 81 | uacme: created directory /etc/ssl/uacme/private/samurai-res.kolez.com |
| 82 | uacme: created directory /etc/ssl/uacme/samurai-res.kolez.com/ |
| 83 | uacme: loading key from /etc/ssl/uacme/private/samurai-res.kolez.com/key.pem |
| 84 | uacme: /etc/ssl/uacme/private/samurai-res.kolez.com/key.pem not found |
| 85 | uacme: generating new 384-bit EC key |
| 86 | uacme: key saved to /etc/ssl/uacme/private/samurai-res.kolez.com/key.pem |
| 87 | uacme: checking existence and expiration of /etc/ssl/uacme/samurai-res.kolez.com/cert.pem |
| 88 | uacme: /etc/ssl/uacme/samurai-res.kolez.com/cert.pem does not exist |
| 89 | uacme: generating certificate request |
| 90 | uacme: fetching directory at https://acme-v02.api.letsencrypt.org/directory |
| 91 | uacme: retrieving account at https://acme-v02.api.letsencrypt.org/acme/new-acct |
| 92 | uacme: account location: https://acme-v02.api.letsencrypt.org/acme/acct/1023358517 |
| 93 | uacme: creating new order at https://acme-v02.api.letsencrypt.org/acme/new-order |
| 94 | uacme: order location: https://acme-v02.api.letsencrypt.org/acme/order/1023358517/171799917907 |
| 95 | uacme: retrieving authorization at https://acme-v02.api.letsencrypt.org/acme/authz-v3/213321949517 |
| 96 | uacme: running /usr/share/uacme/uacme.sh begin http-01 samurai-res.kolez.com xEIoLW2A0Mdxnky4i8D2Ehp6dZlPmUdX3E7agiBloK4 xEIoLW2A0Mdxnky4i8D2Ehp6dZlPmUdX3E7agiBloK4.kh7u922KG_AhdSqfbFhPjz_n5poyn31Jw2NqUyGCbyo |
| 97 | uacme: starting challenge at https://acme-v02.api.letsencrypt.org/acme/chall-v3/213321949517/4isMwQ |
| 98 | uacme: polling challenge status at https://acme-v02.api.letsencrypt.org/acme/chall-v3/213321949517/4isMwQ |
| 99 | uacme: running /usr/share/uacme/uacme.sh done http-01 samurai-res.kolez.com xEIoLW2A0Mdxnky4i8D2Ehp6dZlPmUdX3E7agiBloK4 xEIoLW2A0Mdxnky4i8D2Ehp6dZlPmUdX3E7agiBloK4.kh7u922KG_AhdSqfbFhPjz_n5poyn31Jw2NqUyGCbyo |
| 100 | uacme: polling order status at https://acme-v02.api.letsencrypt.org/acme/order/1023358517/171799917907 |
| 101 | uacme: finalizing order at https://acme-v02.api.letsencrypt.org/acme/finalize/1023358517/171799917907 |
| 102 | uacme: polling order status at https://acme-v02.api.letsencrypt.org/acme/order/1023358517/171799917907 |
| 103 | uacme: retrieving certificate at https://acme-v02.api.letsencrypt.org/acme/cert/04dd142ab955eef7232fd502f73b49f878a2 |
| 104 | uacme: saving certificate to /etc/ssl/uacme/samurai-res.kolez.com/cert.pem.tmp |
| 105 | uacme: renaming /etc/ssl/uacme/samurai-res.kolez.com/cert.pem.tmp to /etc/ssl/uacme/samurai-res.kolez.com/cert.pem |
| 106 | }}} |
| 107 | |
| 108 | Наш сертификат выпущен и находится в файле `/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` соответственно: |
| 109 | |
| 110 | {{{ |
| 111 | root@sw01:~# cd /usr/share/sw/ |
| 112 | root@sw01:/usr/share/sw# ln -s /etc/ssl/uacme/samurai-res.kolez.com/cert.pem server.cer |
| 113 | root@sw01:/usr/share/sw# ln -s /etc/ssl/uacme/private/samurai-res.kolez.com/key.pem server.key |
| 114 | }}} |
| 115 | |
| 116 | После этого сервер платы SW-01 автоматически обнаружит и начнет использовать наш сертификат (для этого будет перезапущен сервер HTTPS). Мы можем убедиться в том, что все работает правильно, открыв веб-браузером URL `https://samurai-res.kolez.com/`. |
| 117 | |
| 118 | == Настройка автоматического обновления сертификата == |
| 119 | |
| 120 | Для настройки автоматического перевыпуска сертификата нам потребуется установить пакет `cron`: |
| 121 | |
| 122 | {{{ |
| 123 | root@sw01:/usr/share/sw# opkg install cron |
| 124 | Installing cron (3.0pl1-r8.9) on root. |
| 125 | Downloading https://repo.adc-line.ru/sw-01/ipk/armv5te/cron_3.0pl1-r8.9_armv5te.ipk. |
| 126 | Configuring cron. |
| 127 | Adding system startup for /etc/init.d/cron. |
| 128 | System startup links for /etc/init.d/cron already exist. |
| 129 | Stopping Vixie-cron. |
| 130 | Starting Vixie-cron. |
| 131 | }}} |
| 132 | |
| 133 | Теперь настроим выполнение команды обновления сертификата каждый день в 0:15 UTC. Для этого выполним команду `crontab -e`. Запустится текстовый редактор vi. В редакторе переходим в режим вставки текста нажатием `i` и вводим следующую строку: |
| 134 | |
| 135 | {{{ |
| 136 | 15 0 * * * /usr/bin/uacme -t EC -b 384 -h /usr/share/uacme/uacme.sh issue samurai-res.kolez.com |
| 137 | }}} |
| 138 | |
| 139 | Теперь выходим из режима вставки нажатием `ESC`, а затем сохраняем отредактированный текст и завершаем редактор командой `:wq`. |
| 140 | |
| 141 | Как видно выше, для обновления сертификата используется та же команда, что и для его первоначального выпуска (только без опции `-v`, чтобы uacme не выводила никакого текста в ходе выполнения, если только не произошла ошибка). Каждый день в 0:15 UTC cron будет выполнять заданную нами выше команду. Если до истечения срока действия сертификата остается больше 30 дней (это значение можно изменть опцией `-d`), uacme ничего не будет делать. Если же срок действия текущего сертификата заканчивается раньше, uacme запросит выпуск нового сертификата. В случае успеха старый файл сертификата будет заменен новым (копия же старого сертификата будет сохранена под другим именем в том же каталоге). HTTPS сервер платы SW-01 обнаружит изменение файла сертификата и перезапустит сервер с использованием нового сертификата автоматически. |
| 142 | |
| 143 | == Заключение == |
| 144 | |
| 145 | В данном примере мы пользовались услугами удостоверяющего центра Let's Encrypt, но вместо него можно использовать (почти) любой другой удостоверяющий центр, поддерживающий выпуск сертификатов по протоколу ACMEv2. |
| 146 | |
| 147 | Если это возможно, рекомендуется использовать ключи типа EC, так как алгоритм RSA требует намного большего объема вычислений чем алгоритм EC, при этом производительность процессора платы SW-01 не очень велика, что может приводить к значительным задержкам. Так, при использовании ключа RSA размером 4096 бит установка одного соединения TLS длится около 2 секунд. Для сравнения: при использовании ключа EC размером 384 бита установка соединения TLS длится лишь 150 мс. |