27 июня 2016 в 12:06

Пример простой автоматизации letsencrypt tutorial

image

Удостоверяющий центр «Let’s Encrypt» (далее просто letsencrypt) вышел из беты пару месяцев назад, пообтерся в реальных условиях, избавился от детских болезней и оброс различными клиентами. И к этому моменту выдал 5 миллионов сертификатов. Самое время внедрять, т.е. получать сертификаты на свои домены и обновлять их в автоматическом режиме. Но как внедрить так, чтобы приблизиться к любимому админскому «поставил и забыл»? Чтобы было просто получать новые сертификаты, а старые при этом обновлялись автоматом? Ну и как добавить немного безопасности в этот процесс?
Ответ под катом.

TL;DR/Quick Start/шпаргалка
  • Скачать и настроить скрипт
    sudo adduser --system --home /opt/letsencrypt le
    sudo -u le -s
    git clone https://github.com/lukas2511/letsencrypt.sh.git /opt/letsencrypt/
    mkdir /opt/letsencrypt/.acme-challenges
    echo CONTACT_EMAIL="your@email" > /opt/letsencrypt/config
    echo "ваш_домен" > /opt/letsencrypt/domains.txt
    
  • добавить в конфиг виртуального хоста nginx строчку
    location /.well-known/acme-challenge/ { alias /opt/letsencrypt/.acme-challenges/; }
    
  • запустить скрипт
    sudo -u le /opt/letsencrypt/letsencrypt.sh --cron
    
  • добавить ещё три строчки в конфиг виртуального хоста
    listen 443 ssl;
    ssl_certificate /opt/letsencrypt/certs/ваш_домен/fullchain.pem;
    ssl_certificate_key /opt/letsencrypt/certs/ваш_домен/privkey.pem;
    
  • добавить в крон пользователя le
    1 0 * * * /opt/letsencrypt/letsencrypt.sh --cron
    


Как я уже сказал, letsencrypt оброс различными клиентами, которые позволяют получить сертификат. Этих самых клиентов, кстати, уже десятки под разные системы и языки программирования. В статье будет рассказано про реализацию клиента на bash от lukas2511, letsencrypt.sh. Это один скрипт на bash, который лежит в своей папке и для работы ему нужен только openssl. Запускаться он будет под отдельным пользователем. Конечно, при желании, всегда можно ещё сильнее закрутить гайки в плане безопасности — запускать в chroot и т.д.

Сначала нужно скачать и настроить скрипт.
Предположим, что ОС — linux, веб сервер — nginx, рабочая папка скрипта — /opt/letsencrypt, а пользователь — le.
Создадим системного пользователя, из под которого будет работать скрипт. При создании системного пользователя в debian/ubuntu, ему выставляется оболочка /bin/false и назначается группа nogroup, что нам вполне подходит.
$ sudo adduser --system --home /opt/letsencrypt le

Теперь можно стать этим пользователем и все делать под ним (кроме настройки nginx).
Скачиваем скрипт и смотрим содержимое.
$ sudo -u le -s
$ git clone https://github.com/lukas2511/letsencrypt.sh.git /opt/letsencrypt/
$ ls -la /opt/letsencrypt/
total 84
drwxr-xr-x 4 le   le    4096 Jun 25 15:56 .
drwxr-xr-x 3 root root  4096 Jun 25 15:53 ..
-rw-r--r-- 1 le   le    1406 Jun 25 15:56 CHANGELOG
drwxr-xr-x 3 le   le    4096 Jun 25 15:56 docs
drwxr-xr-x 8 le   le    4096 Jun 25 15:56 .git
-rw-r--r-- 1 le   le     108 Jun 25 15:56 .gitignore
-rwxr-xr-x 1 le   le   37634 Jun 25 15:56 letsencrypt.sh
-rw-r--r-- 1 le   le    1080 Jun 25 15:56 LICENSE
-rw-r--r-- 1 le   le    3040 Jun 25 15:56 README.md
-rwxr-xr-x 1 le   le    8048 Jun 25 15:56 test.sh
-rw-r--r-- 1 le   le     107 Jun 25 15:56 .travis.yml

Для работы скрипту нужна папка, куда он будет складывать файлы для валидации доменов.
По умолчанию скрипт настроен использовать папку /opt/letsencrypt/.acme-challenges и будет падать с ошибкой, если такой папки нет.
Так же желательно создать конфиг с нужными параметрами. Параметры для работы скрипт пытается брать из файла /opt/letsencrypt/config. По умолчанию файла нет и скрипт использует значения по умолчанию, но есть хорошо документированный конфиг в папке с документацией, который можно взять за основу.
Создаем папку и копируем конфиг
$ mkdir /opt/letsencrypt/.acme-challenges
$ cp /opt/letsencrypt/docs/examples/config /opt/letsencrypt/config

Чтобы посмотреть, с какими значениями работает скрипт, его можно вызвать с ключем --env
$ /opt/letsencrypt/letsencrypt.sh --env
# letsencrypt.sh configuration
#
# !! WARNING !! No main config file found, using default config!
#
declare -- CA="https://acme-v01.api.letsencrypt.org/directory"
declare -- LICENSE="https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf"
declare -- CERTDIR="/opt/letsencrypt/certs"
declare -- CHALLENGETYPE="http-01"
declare -- DOMAINS_TXT="/opt/letsencrypt/domains.txt"
declare -- HOOK=""
declare -- HOOK_CHAIN="no"
declare -- RENEW_DAYS="30"
declare -- ACCOUNT_KEY="/opt/letsencrypt/accounts/aHR0cHM6Ly9hY21lLXYwMS5hcGkubGV0c2VuY3J5cHQub3JnL2RpcmVjdG9yeQo/account_key.pem"
declare -- ACCOUNT_KEY_JSON="/opt/letsencrypt/accounts/aHR0cHM6Ly9hY21lLXYwMS5hcGkubGV0c2VuY3J5cHQub3JnL2RpcmVjdG9yeQo/registration_info.json"
declare -- KEYSIZE="4096"
declare -- WELLKNOWN="/opt/letsencrypt/.acme-challenges"
declare -- PRIVATE_KEY_RENEW="yes"
declare -- OPENSSL_CNF="/usr/lib/ssl/openssl.cnf"
declare -- CONTACT_EMAIL=""
declare -- LOCKFILE="/opt/letsencrypt/lock"

Описание некоторых параметров
CA — какой удостоверяющий центр использовать. Их, как минимум два — боевой (по умолчанию) и тестовый. Дело в том, что у боевого есть разные ограничения по частоте запросов и количеству доменов. В эти ограничения легко упереться при тестировании. Поэтому я рекомендую для тестовых запусков указать тестовый центр. Он работает так же, как боевой, просто генерирует невалидные сертификаты.
Вот тестовый CA:
CA="https://acme-staging.api.letsencrypt.org/directory"

CERTDIR — папка для сертификатов. Внутри неё отельные папки по имени хоста. А в этих папках уже сертификаты для каждого хоста. Нужно будет настроить nginx читать сертификаты из этих папок (см. ниже).

DOMAINS_TXT — список доменов. Одна строчка — один сертификат. В одной строчке может быть несколько доменов, тогда создается один сертификат для них. Скрипт берет первый домен, как название сертификата, а остальные домены указывает, как дополнительные. Например, для такого файла, скрипт создаст два сертификата: some.domain.com и test.com.
some.domain.com another.domain.net example.domain.org
test.com www.test.org ftp.test.net

HOOK — скрипт, который запускается при различных действиях (при валидации доменов, при генерации сертификатов и т.д.).
Скрипту передаются разные параметры: название операции, пути к новым сертификатам и т.д.
Указание своего скрипта может помочь, если вам нужно выполнять чуть больше действий на каждом шаге.
Например, сертификат нужно разложить на несколько серверов, или нужно проводить валидацию домена через dns, а не через файл.
Скрипт, который ничего не делает, но содержит массу комментариев, лежит по адресу /opt/letsencrypt/docs/examples/hook.sh

RENEW_DAYS — через сколько дней обновлять сертификат. Максимум 90, по умолчанию 30.

CONTACT_EMAIL — рабочий email администратора.

Я рекомендую указать в конфиге свой email в CONTACT_EMAIL и на время тестов прописать тестовый CA.
Установка и первоначальная настройка скрипта на этом завершены. Теперь можно получать сертификаты.

Для начала получим сертифкат для одного домена: letest.lexore.net
В nginx для теста сделаем простой конфиг виртуального хоста, который будет выводить протокол, http или https.
server {
    listen 80;
    server_name letest.lexore.net;
    location /.well-known/acme-challenge/ { alias /opt/letsencrypt/.acme-challenges/; }

    location / {
         default_type text/plain;
         return 200 "scheme: $scheme";
    }
}

Ключевой параметр: location /.well-known/acme-challenge/
В папке /opt/letsencrypt/.acme-challenges/ создаются файлы для подтверждения, что вы управляете сайтом.
Они должны быть доступны по адресу имя_сайта/.well-known/acme-challenge/, иначе сертификат не подпишут.
Названия файлов генерируются случайным образом, поэтому проще открыть доступ ко всей папке.
В конце скрипт удаляет созданный файл, так что папка не будет захламляться.

Перезагрузим nginx и проверим сайт:
$ curl -i letest.lexore.net
HTTP/1.1 200 OK
Server: nginx
Date: Sun, 26 Jun 2016 13:13:18 GMT
Content-Type: text/plain
Content-Length: 12
Connection: keep-alive

scheme: http

Теперь нужно прописать имя хоста в domains.txt и запустить сам скрипт
$ echo letest.lexore.net > /opt/letsencrypt/domains.txt
$ /opt/letsencrypt/letsencrypt.sh --cron
# INFO: Using main config file /opt/letsencrypt/config
Processing letest.lexore.net
 + Signing domains...
 + Creating new directory /opt/letsencrypt/certs/letest.lexore.net ...
 + Generating private key...
 + Generating signing request...
 + Requesting challenge for letest.lexore.net...
 + Responding to challenge for letest.lexore.net...
 + Challenge is valid!
 + Requesting certificate...
 + Checking certificate...
 + Done!
 + Creating fullchain.pem...
 + Done!

Сертификат готов, файлы сертификата и ключа лежат в папке "/opt/letsencrypt/certs/letest.lexore.net".
Осталось добавить настройки в nginx. Нужно добавить следующие строки в конфиг виртуального хоста:
listen   443 ssl;
ssl_certificate /opt/letsencrypt/certs/letest.lexore.net/fullchain.pem;
ssl_certificate_key /opt/letsencrypt/certs/letest.lexore.net/privkey.pem;

После перезагрузки nginx, можно пробовать сайт в браузере.
Если в конфиге скрипта был указан тестовый CA, браузер заругается на сертификат.
Как выглядит такой сертификат в firefox
image

Но это все равно значит, что скрипт и nginx настроены правильно.
Теперь нужно просто поменять CA в конфиге на боевое значание и запустить скрипт ещё раз, добавив параметр --force.
Без этого параметра скрипт не станет заново генерировать сертификат, т.к. ещё не подошел срок устаревания, указанный в конфиге.
le@endor:~$ /opt/letsencrypt/letsencrypt.sh --cron --force
# INFO: Using main config file /opt/letsencrypt/config
Processing letest.lexore.net
 + Checking domain name(s) of existing cert... unchanged.
 + Checking expire date of existing cert...
 + Valid till Sep 24 12:13:00 2016 GMT (Longer than 80 days). Ignoring because renew was forced!
 + Signing domains...
 + Generating private key...
 + Generating signing request...
 + Requesting challenge for letest.lexore.net...
 + Responding to challenge for letest.lexore.net...
 + Challenge is valid!
 + Requesting certificate...
 + Checking certificate...
 + Done!
 + Creating fullchain.pem...
 + Done!

После запуска скрипта и перезагрузки nginx у сайта появится правильный сертификат.
Сертификат готов, https работает.
Как выглядит правильный сертификат


Пару слов про несколько доменов.
Один сертификат может использоваться для нескольких доменов. Например, вот как это будет выглядеть, если добавить subdomain.letest.lexore.net.
Запуск скрипта:
$ /opt/letsencrypt/letsencrypt.sh --cron --force
# INFO: Using main config file /opt/letsencrypt/config
Processing letest.lexore.net with alternative names: subdomain.letest.lexore.net
 + Checking domain name(s) of existing cert... changed!
 + Domain name(s) are not matching!
 + Names in old certificate: letest.lexore.net
 + Configured names: letest.lexore.net subdomain.letest.lexore.net
 + Forcing renew.
 + Checking expire date of existing cert...
 + Valid till Sep 24 12:48:00 2016 GMT (Longer than 80 days). Ignoring because renew was forced!
 + Signing domains...
 + Generating private key...
 + Generating signing request...
 + Requesting challenge for letest.lexore.net...
 + Requesting challenge for subdomain.letest.lexore.net...
 + Responding to challenge for letest.lexore.net...
 + Challenge is valid!
 + Responding to challenge for subdomain.letest.lexore.net...
 + Challenge is valid!
 + Requesting certificate...
 + Checking certificate...
 + Done!
 + Creating fullchain.pem...
 + Done!

Правка конфига nginx, перезапуск, и вот новый сертификат работает уже на два домена.
Скриншот такого сертификата в firefox


Домены не обязаны быть как-то связаны, можно сделать один домен для domain.com и ftp.example.net.
Максимум можно указать 100 доменов в одном сертификате.
Кому-то этого может хватить, чтобы обойтись одним сертификатом для всех сайтов на сервере.
Правда, этот сертификат придется пересоздавать на каждый новый домен в списке, и можно упереться в лимиты.

А теперь самое приятное — автоматизация.
Для того, чтобы скрипт сам обновлял все сертификаты из файла domains.txt и вы забыли про манипуляции руками, нужно добавить одну строчку в крон пользователя le:
0 1 * * * /opt/letsencrypt/letsencrypt.sh --cron

Таким образом, алгоритм перевода последующих сайтов на https:
  • добавить location /.well-known/acme-challenge/ { alias /opt/letsencrypt/.acme-challenges/; }
  • добавить ваш_домен в domains.txt
  • запустить скрипт /opt/letsencrypt/letsencrypt.sh --cron
  • добавить настройки ssl
    listen   443 ssl;
    ssl_certificate /opt/letsencrypt/certs/ваш_домен/fullchain.pem;
    ssl_certificate_key /opt/letsencrypt/certs/ваш_домен/privkey.pem;
    


Это не единственный способ автоматизации, многие клиенты letsencrypt позволяют свести всю работу к запуску одного скрипта по крону.
Данный скрипт мне понравился за простоту- всю работу делает один скрипт на bash.
А так же, за свои дополнительные возможности — кроме простой автоматизации, он из коробки поддерживает «сложную» автоматизацию, запуск своих скриптов и переопределение параметров.
Например, я уже упомянул про параметр HOOK в конфиге, который позволяет запускать свой скрипт.
Так же из коробки есть параметр CONFIG_D — папка, в которой будут запускаться все .sh скрипты для переопределения параметров основного конфига.
Плюс, поддержка разных «аккаунтов» через указание разных ACCOUNTDIR — папок с приватными ключами для подписи запросов.
Мне кажется, это позволит использовать скрипт в больших и сложных инфраструктурах.
Игорь @lexore
карма
42,0
рейтинг 0,0
Системный администратор
Похожие публикации

Комментарии (38)

  • 0
    Теперь нужно просто поменять CA в конфиге на боевое значание и запустить скрипт ещё раз, добавив параметр --force.
    Без этого параметра скрипт не станет заново генерировать сертификат, т.к. ещё не подошел срок устаревания, указанный в конфиге.


    Столкнулся с этим недавно. Использовал letsencrypt-auto renew без --force-renewal. В итоге сертификаты не обновились. Попробовал вручную — не обновляет, skipped… Несмотря на то, что срок истёк уж как 3 дня. С --force-renewal обновилось. + потребовалось перегрузить nginx руками.
  • +3
    По letsencrypt куча всяких костылей-советов.
    Это похоже на годный гайд. Спасибо! Буду пробовать.
    • –1
      Всё равно в нём мало смысла, когда есть бесплатный StartSSL на год с 5 доменами в SAN и дешевый GGSSL с wildcard за $50.
      • 0
        У StartSSL есть один минус. Для меня лично серьезный. Необходимость запуска их демона да еще и от рута.
        Лично мне как-то боязно на своих серверах крутить чей то черный ящик к коду которого доступа не предоставляется.
      • +1
        Несколько лет использовал StartSSL. После выхода letsencrypt и настройки его автоматического продления ( крон раз в два месяца), не вижу смысла связываться с StartSSL и тем более платить деньги за сертификат GGSSL.
        • –1
          StartSSL запустили свой аналог letsencrypt — https://www.startssl.com/StartEncrypt
        • 0
          Плюс платных сертификатов в сроке действия и подтверждении через обычный CSR.
          А с LE целое дело подтверждать сайт недоступный из интернета и даже для публичных до сих пор не сделали официальную поддержку nginx.
          • 0
            Срок действия на мой взгляд не очень критичен, если обновление сертификатов можно поставить, как задачу в cron. Для публичных сайтов — работа с LE, хорошо документирована, и обновление сертификата для nginx не создает каких либо сложностей (в силу то, что все действия можно автоматизировать)
            • 0
              Там ниже написали про certbot, но там тоже предупреждают про экспериментальную поддержку и у меня большинство сервисов приватные, так что проще раз в три года обновить сертификат на балансировщике за небольшую денежку.

              Странно, что производители железок не спешат добавлять ACME-клиент — даже в ASA сейчас кнопка для какого-то платного CA, хотя сама Cisco спонсирует LE.
          • 0
            В DNS можно и не руками записи добавлять и «целое дело» по сути тоже сводится к запуску задачи через крон.
  • 0
    В easyengine очень дурацкий баг с ними, который никак не пофиксят.
    https://github.com/EasyEngine/easyengine/issues/699

    так что если не завелось вдруг, то проверьте, прописан ли WWW поддомен.
    • 0

      Насколько я понял, по ссылке issue насчет другого ПО (EasyEngine), которое автоматом создает сертификат на два домена: domain.com и www.domain.com.
      И эта операция падает с ошибкой, если домена www.domain.com нет в dns.
      Сам letsencrypt вполне может подписать сертификат на два домена, domain.com и www.domain.com, просто он проверит каждый домен на доступность.
      А если какого-то домена нет, то он не сможет его проверить и откажет в подписи сертификата.
      Мне кажется, это вполне логично.

      • 0
        Так если чисто letsencrypt использовать для поддомена, не указывая www, он откажет в подписи?
        Если откажет, то он сообщит, что не может найти WWW поддомен?
        • 0

          Не совсем понял вопрос, если честно.
          Если запустить клиент letsencrypt для домена domain.com, он его проверит и сделает сертификат только для одного этого домена: domain.com. Он не будет проверять домен www.domain.com.
          Если нужен сертификат для двух доменов, domain.com и www.domain.com, нужно это явно указать в запросе. Letsencrypt последовательно проверит оба эти домена. И если с ними все ок, сделает один сертификат для них. А если с одним из доменов что-то не так, как я понял, он просто не делает сертифкат.
          Можно сделать два отдельных сертифтата: один для domain.com и один для www.domain.com


          Мне кажется, что проблема в EasyEngine — там рассчитывают на то, что большинство удостоверяющих центров делают один сертификат на два домена — domain.com и www.domain.com.
          Причем, вписывают два домена, даже не проверяя, а есть ли домен www.domain.com.
          А letsencrypt так не делает — он проверяет каждый домен или поддомен.


          UPD
          Кажется, я понял ваш вопрос.
          Для генерации сертификата нужно доказать, что вы управляете сайтом. Для этого нужно или положить файл (который запросит сервер letsencrypt), или сделать запись в DNS. Если в DNS нет домена www.domain.com, то и проверить сайт нельзя. В DNS его нет, а сайт по адресу www.domain.com уж тем более будет недоступен :)

  • +1
    С чем столкнулся — так с неудобством юзания LE совместно с key-pinning.
    Достаточно геморно автоматизировать всё это дело, каждый раз у nginx надо конфиг править.
    • +1
      А что там геморного то? Получаем сертификаты, формируем сниппет, который инклудим куда надо.

      у меня а-ля так:
      Скрытый текст#!/bin/bash
      tmp=«add_header public-key-pins '»
      for D in "/etc/letsencrypt/live/"*
      do
      cx509=`openssl x509 -pubkey -noout -in $D/cert.pem | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64`
      echo -e `basename $D`"\t: "$cx509" ("`openssl x509 -startdate -noout -in $D/cert.pem`")"
      tmp+='pin-sha256="'$cx509'"; '
      done

      for D in "/root/git/letsencrypt/"*.pem
      do
      cx509=`openssl x509 -pubkey -noout -in $D | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64`
      echo -e `basename $D`"\t: "$cx509" ("`openssl x509 -enddate -noout -in $D`")"
      tmp+='pin-sha256="'$cx509'"; '
      done

      tmp+='pin-sha256=«Vjs8r4z+80wjNcr1YKepWQboSIRi63WsWXhIMN+eWys=»;'
      tmp+=«max-age=604800; includeSubDomains;';»
      echo Write nginx pins.conf
      echo $tmp > /etc/nginx/snippets/pins.conf
    • 0
      Вы каждый раз новые ключи генерируете? В описанном LE.sh одно время пытались всегда обновлять ключи, но для поддержки HKPK оставили опцию.
      PRIVATE_KEY_RENEW="no"
      • 0
        Ну, по крайней мере, это правильно, обновлять и ключи заодно. Поэтому меня три месяца и поднапрягают.
        • +1
          Ну если бы серт был на год — ключи бы не обновлялись год. С LE можно каждые 3 месяца перевыпускать серт, но ключи менять раз в год.

          Хотя не понимаю почему обновлять ключи «правильно».
          • 0
            Перезапускать web севрер для подкладывания нового приватного ключа, не всегда удобно. Мы ведь про let's encrypt, а оно для мелких контор в первую очередь интересно.
            • 0

              Достаточно делать reload

              • 0
                Боюсь, что для apache, это не подходит. Ему подавай: restart
                • 0
                  Разве? А как же грейсфул рестарт:
                  «При получении сигнала USR1 или graceful, родительский процесс призывает дочерние процессы к завершению работы сразу же после обработки своего текущего запроса (или к незамедлительной остановке, если дочерний процесс ничего не обрабатывает). Родительский процесс перечитывает конфигурационные файлы, открывает заново log-файлы (файлы, содержащие журнал работы сервера). После того, как какой-то из дочерних процессов завершает работу, родительский процесс заменяет его дочерним процессом нового поколения, т.е. с новой конфигурацией, который начинает обрабатывать новые запросы незамедлительно.»

                  /etc/init.d/httpd graceful
                  /etc/init.d/apache2 reload
                  apachectl -k graceful
                  • 0
                    На практике, сможете проверить на 2.4? У меня не получилось. :( service apache2 reload — не помогло. reload это тоже самое что и gracefull — в общем случае, в случае ubuntu? Вроде да. По документации — должно всё ок быть. По факту, похоже не может в голове два приватных ключа apache держать…
                    • +1

                      Скажу банальщину, но я бы рекомендовал апач прятать за nginx.
                      Лично у меня так и крутится — апач слушает на 127.0.0.1:80, а nginx на внешний_ip:80,443.
                      Они друг другу не мешают. А за счет того, что апач тоже работает на 80 порту, нет глюков с редиректами.
                      Если апач вешать на 8080, иногда кодом или самим апачом генерируются редиректы на порт 8080.

                      • 0
                        Спасибо! Интересное решение про 127.0.0.1:80, хозяюшке, что называется на заметку. Но конкретно в моём случае, я использую связку: tomcat+apache. И использую проксирование через ajp. Мне необходимо проксировать alfresco. А там очень всё сложно. В том числе надо прокидывать kerberos. — По состоянию на начало 2015 года, nginx, не мог корректно всё что нужно проксировать. apache — работает без нареканий. Так, что выбора у меня боюсь что нету.
  • 0
    К слову сказать, у StartSSL тоже есть (теперь?) API, но сертификаты там на год, а не три месяца, ну и если доплатить, то можно получить wildcard в неограниченном количестве и сроком на два года (LE wildcard не планирует).
    • 0

      У letsencrypt все дело в автоматическом создании и продлении. Если его настроить, то вы и не почувствуете, что сертификат на 3 месяца. Вам больше не придется продлять сертификаты руками и у вас не будет ситуации, что сайт не работает из за истекшего сертификата..

  • 0
    Идея хорошая — добавил в крон и забыл. Но пока у меня опыт отрицательный, за 2 месяца LE немного поменяли формат ответов, чего хватило чтоб сломать letsencrypt.sh.
    Хоть автообновление в крон добавляй.
    • 0
      штатный клиент сам обновляется регулярно, судя по отчетам от крона,
  • 0
    Что-то какая-то устаревшая статья, Let's Encrypt выпустили родного клиента certbot (пока бета), который можно ставить из репозитория например для дебиана ( https://certbot.eff.org/#debianjessie-nginx ). Ну или выбрать свою систему на главной.
    Хотя клиентов конечно море ( https://letsencrypt.org/docs/client-options/ ).

    В общем, используя webroot плагин, обновление сертификатов (котрые истекают не ранее чем, через 30 дней) получается в одну строчку в кроне:
    #certbot renew
    


    если неохота использовать свой сервер nginx для подтверждения домена (обновления сертификата), можно запускать так:

    #certbot renew --standalone --pre-hook "service nginx stop" --post-hook "service nginx start"
    


    В этом случае сервер nginx останавливается, запускается standalne, нас проверяют, выдают сертификат, обратно включается nginx.
    • 0

      Я сначала тоже думал использовать certbot. Но смущает, что certbot ещё бета, а плагин для nginx — "experimental".
      В вашем случае, для того, чтобы работали команды "service ...", нужно или запускать certbot от рута, или давать sudo и писать "sudo service ...", что тоже не радует.

  • +1
    Решил воспользоваться инструкцией, пришлось модифицировать.

    1. Теперь скрипт переименован, называется dehydrated и его репозитарий https://github.com/lukas2511/dehydrated, а статус на странице https://travis-ci.org/lukas2511/dehydrated
    2. В dehydrated изменено умолчание для каталога, куда он помещает проверочные файлы, теперь это /var/www/dehydrated
    3. Стоило указать используемый дистрибутив Linux и уточнить, что скрипту нужен (системный или специальный) конфиг openssl.cnf. В dehydrated по умолчанию конфиг формируется из переменной openssl «openssl directory», и это может оказаться неудачным вариантом.
    4. Если уж использовать отдельного пользователя, нужно закрыть ему возможность модифицировать собственный скрипт и конфиг.

    В итоге установку скрипта я сделал так:
    git clone https://github.com/lukas2511/dehydrated /opt/dehydrated/
    cp  /opt/dehydrated/docs/examples/config /opt/dehydrated/config
    echo "KEY_ALGO=secp384r1" >> /opt/dehydrated/config
    echo "LOCKFILE=/tmp/dehydrated.lock" >> /opt/dehydrated/config
    echo "OPENSSL_CNF=/etc/openssl/openssl.cnf" >> /opt/dehydrated/config
    adduser --system --home /var/www/dehydrated -s /sbin/nologin _dehydrated
    usermod -a -G _dehydrated _nginx
    install -m 750 -o _dehydrated -g _dehydrated -d /opt/dehydrated/certs /opt/dehydrated/accounts /var/www/dehydrated
    echo '#!/bin/sh
    su dehydrated -c "/opt/dehydrated/dehydrated -c"
    if ! ( cmp -s /etc/nginx/nginx/ssl/fullchain.pem /opt/dehydrated/certs/example.org/fullchain.pem \
           && cmp -s /etc/nginx/nginx/ssl/privkey.pem /opt/dehydrated/certs/example.org/privkey.pem ); then
      install -o root -g _nginx -m 640 /opt/dehydrated/certs/example.org/fullchain.pem /opt/dehydrated/certs/example.org/privkey.pem /etc/nginx/nginx/ssl/
      service nginx reload
    fi
    ' >/etc/cron.monthly/dehydrated
    chmod 744 /etc/cron.monthly/dehydrated
    

    Остаётся задать контактный email и домены, например, тем же сопособом, как у вас:
    echo CONTACT_EMAIL="example@example.org" >> /opt/dehydrated/config
    echo "example.org" >> /opt/dehydrated/domains.txt
    

    • 0
      Можно пожалуйста чуть подробнее про 3 и 4 пункты?
      • 0
        Я привёл все свои действия по установке и настройке dehydrated.

        «4. Если уж использовать отдельного пользователя, нужно закрыть ему возможность модифицировать собственный скрипт и конфиг.» — пользователь _dehydrated может писать только в четыре каталога, это /tmp (туда может писать кто угодно, но чужие файлы как правило недоступны) и перечисленное в команде:
        install -m 750 -o _dehydrated -g _dehydrated -d /opt/dehydrated/certs /opt/dehydrated/accounts /var/www/dehydrated

        «3. Стоило указать используемый дистрибутив Linux и уточнить, что скрипту нужен (системный или специальный) конфиг openssl.cnf. В dehydrated по умолчанию конфиг формируется из переменной openssl «openssl directory», и это может оказаться неудачным вариантом.»

        В разных дистрибутивах GNU/Linux разное содержимое того файла конфигурации openssl, который использует бибилиотека openssl.so при отсутствии прямого указания на конфиг. Не для всех случаев значения из этого файла подходят для dehydrated.

        Что-то ещё непонятно?
    • 0
      спасибо, все получилось, но в браузере сертификат недействительный, поскольку нет доверия к центру lets encrypt o_O
      • 0
        Что за браузер? Последний хром давно их признаёт
        • 0
          Да, простите, надо было обновить хром

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.