Подстановочные сертификаты от letsencrypt в облаке aws

Letsencrypt в настоящее время является очень популярным центром сертификации.

Это стандарт де-факто для большинства ситуаций, когда вам нужен зеленый запечатанный сертификат в вашей среде.
Новая версия API (v2) предоставляет очень удобный способ выпуска подстановочных сертификатов с использованием проверки DNS.

Хотя не рекомендуется размещать учетные данные DNS для чтения/записи в такой среде, могут
исключение, которое вынуждает вас делать это на временной основе.

Обходной путь ниже предлагает способ ограничить область записи учетных данных, когда ваш домен обслуживается AWS Route53.

Предположим, мы хотим создать подстановочный сертификат для нашей промежуточной среды.

*.staging.yourdomain.com

Шаг А – подготовка зоны к проверкам акме

Создайте еще одну общедоступную зону размещения для домена _acme-challenge.staging.yourdomain.com
Я знаю, вы, вероятно, думаете «но это не домен!», но в соответствующем смысле,
на самом деле это все еще домен, просто четырехуровневый.

Маршрут 53 назначит 4 новых сервера имен для этой новой размещенной зоны. Запишите эти серверы.

Вы получите что-то вроде

ns-1918.awsdns-47.co.uk.
ns-1211.awsdns-23.org.
ns-626.awsdns-14.net.
ns-126.awsdns-15.com.

Шаг B — делегирование действий acme в выделенную зону хостинга acme

Вернитесь в исходную зону размещения и создайте запись для _acme-challenge.staging.yourdomain.com типа НС. В качестве значения, которое вы будете использовать для создания этой записи, используйте те 4 сервера имен, которые Route 53 назначил новой размещенной зоне, по одному на строку.

Важный! Не изменяйте ни одну из существующих записей NS ни в одной из зон.

То, что мы реализовали на этом шаге, называется делегированием, т.е. вы делегируете полномочия для staging.yourdomain.com субдомена в другую зону хостинга, которой, как вы заметите, был автоматически назначен совершенно другой набор из 4 серверов Route 53, отличный от тех, которые обрабатывают ваш родительский домен.

Теперь вы можете создать новую запись в корне новой размещенной зоны, и когда вы сделаете DNS-запрос для _acme-challenge.staging.yourdomain.com, возвращенный ответ будет ответом из новой размещенной зоны.

Теперь вы можете дать своему сценарию разрешение только на изменение записей в новой зоне, и он не сможет ничего изменить в родительской зоне, потому что вы не дали ему там никаких разрешений. Итак, мы подходим к следующему шагу

ШАГ C — создание политики с ограниченным доступом

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

{
"Version": "2012-10-17",
"Statement": [
    {
        "Effect": "Allow",
        "Action": [
            "route53:ChangeResourceRecordSets"
        ],
        "Resource": [
            "arn:aws:route53:::hostedzone/{HOSTEDZONEID}"
        ]
    },
    {
        "Effect": "Allow",
        "Action": [
            "route53:ListHostedZonesByName"
        ],
        "Resource": [
            "*"
        ]
    }
]}

и свяжите эту политику с соответствующим пользователем IAM и получите его учетные данные для доступа.

Соответствующий скрипт terraform может быть следующим (всегда сверяйтесь с самой последней документацией
)


data "aws_route53_zone" "acme" {
    name = "_acme-challenge.staging.yourdomain.com."
}

resource "aws_iam_policy" "allow_writing_acme_zone" {
  # ... other configuration ...
  name = "allow_writing_staging_acme_zone"
  policy = "${data.aws_iam_policy_document.allow_writing_acme_zone.json}"
}

data "aws_iam_policy_document" "allow_writing_acme_zone" {

  statement {
    actions   = ["route53:ChangeResourceRecordSets"]
    resources = ["arn:aws:route53:::hostedzone/${data.aws_route53_zone.acme.zone_id}"]
    effect = "Allow"
  }

  statement {
    actions   = ["route53:GetHostedZone"]
    resources = ["arn:aws:route53:::hostedzone/${data.aws_route53_zone.acme.zone_id}"]
    effect = "Allow"
  }

  statement {
    actions   = ["route53:ListResourceRecordSets"]
    resources = ["arn:aws:route53:::hostedzone/${data.aws_route53_zone.acme.zone_id}"]
    effect = "Allow"
  }

  statement {
    actions   = ["route53:ChangeResourceRecordSets"]
    resources = ["arn:aws:route53:::hostedzone/${data.aws_route53_zone.acme.zone_id}"]
    effect = "Allow"
  }


  statement {
    actions   = ["route53:GetChange"]
    resources = ["*"]
    effect = "Allow"
  }

  statement {
    actions   = ["route53:ListHostedZones"]
    resources = ["*"]
    effect = "Allow"
  }
    
}

resource "aws_iam_user" "acme-writer" {
  name = "acme-domain-writer"
}

resource "aws_iam_user_policy_attachment" "acme-writer-policy" {
  user       = "${aws_iam_user.acme-writer.name}"
  policy_arn = "${aws_iam_policy.allow_writing_acme_zone.arn}"
}


ШАГ D — настройка учетных данных aws (для примера с certbot)

Настройка учетных данных AWS
Теперь нам нужно поместить учетные данные AWS на сервер, чтобы плагин мог их использовать.
Я запускаю все свои команды certbot из домашней папки пользователя по умолчанию,
ваша установка может быть другой.

В домашней папке создайте папку .aws и внутри нее создайте текстовый файл с именем
credentials со следующим содержанием.

[default]
aws_access_key_id=XXXXXX
aws_secret_access_key=XXXX/XXXXX

Замените заполнители ключом доступа и секретным ключом доступа, которые вы только что сохранили из AWS, и заполните их.

После создания проверьте, правильно ли он настроен


aws sts get-caller-identity
{
    "Account": "XXX", 
    "UserId": "YYYYYYYYYYYYYY", 
    "Arn": "arn:aws:iam::XXX:user/acme-domain-writer"
}


Следующим шагом будет, естественно, создание сертификата

Пример — создание сертификата с помощью certbot

Установите инструмент по вашему выбору, например, классический certbot (примеры ниже приведены для семейства ubuntu)

sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot python-certbot-nginx python3-certbot-dns-route53

или используя их обновленный скрипт


wget 
chmod a+x ./certbot-auto
sudo ./certbot-auto


certbot certonly -d staging.yourdomain.com -d *.staging.yourdomain.com --dns-route53 --logs-dir ~/letsencrypt/log/ --config-dir ~/letsencrypt/config/ --work-dir /home/username/letsencrypt/work/ -m git@voronenko.info --agree-tos --non-interactive --server 

Если вы видите вывод, как показано ниже, все готово:

Found credentials in shared credentials file: ~/.aws/credentials
Plugins selected: Authenticator dns-route53, Installer None
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for staging.yourdomain.com
dns-01 challenge for staging.yourdomain.com
Starting new HTTPS connection (1): route53.amazonaws.com
Waiting 10 seconds for DNS changes to propagate
Waiting for verification...
Cleaning up challenges
Resetting dropped connection: route53.amazonaws.com
Resetting dropped connection: acme-v02.api.letsencrypt.org

Теперь обеспечим продление нашего домена

certbot renew  --logs-dir ~/letsencrypt/log/ --config-dir ~/letsencrypt/config/ --work-dir ~/letsencrypt/work/

Если вы хотите настроить cron, и вы указали пользовательский журнал, конфиг, рабочие каталоги — сделайте
обязательно укажите полный путь в crontab.

crontab -e

43 6 * * * certbot renew  --post-hook "service nginx restart"  --logs-dir /home/user/letsencrypt/log/ --config-dir /home/user/letsencrypt/config/ --work-dir /home/user/letsencrypt/work/

Ваши сертификаты будут расположены в каталоге конфигурации

ls config/live/staging.yourdomain.com/
README  cert.pem  chain.pem  fullchain.pem  privkey.pem

Пример — создание сертификата с помощью acme.sh

Но лично я предпочитаю чистую оболочку acme.sh.

Acme.sh — это еще один очень крутой инструмент, написанный исключительно в оболочке.
Он поддерживает количество DNS-провайдеров в виде плагинов оболочки (!) /tree/master/dnsapi.

Каждый плагин имеет исчерпывающую документацию по настройке /wiki/dnsapi.

Для Route53 вам нужно будет экспортировать свои учетные данные

export  AWS_ACCESS_KEY_ID=XXXXXXXXXX
export  AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXX

С acme.sh


acme.sh --issue --dns dns_aws -d staging.yourdomain.com -d "*.staging.yourdomain.com"

[середа, 29 травня 2019 19:58:01 +0200] Multi domain='DNS:staging.yourdomain.com,DNS:*.staging.yourdomain.com'
[середа, 29 травня 2019 19:58:01 +0200] Getting domain auth token for each domain
[середа, 29 травня 2019 19:58:03 +0200] Getting webroot for domain='staging.yourdomain.com'
[середа, 29 травня 2019 19:58:03 +0200] Getting webroot for domain='*.staging.yourdomain.com'
[середа, 29 травня 2019 19:58:03 +0200] Adding txt value: GvaPZqTUMceQVt8yFl4IkW0ZqJ22-680Du-7BLfTcVc for domain:  _acme-challenge.staging.yourdomain.com
[середа, 29 травня 2019 19:58:04 +0200] Getting existing records for _acme-challenge.staging.yourdomain.com
[середа, 29 травня 2019 19:58:05 +0200] TXT record updated successfully.
[середа, 29 травня 2019 19:58:05 +0200] The txt record is added: Success.
[середа, 29 травня 2019 19:58:05 +0200] Adding txt value: txy1JYnOGAWpT1rQ8_U99Ird-Pq-P0iWYzixGPPQIvw for domain:  _acme-challenge.staging.yourdomain.com
[середа, 29 травня 2019 19:58:06 +0200] Getting existing records for _acme-challenge.staging.yourdomain.com
[середа, 29 травня 2019 19:58:07 +0200] TXT record updated successfully.
[середа, 29 травня 2019 19:58:07 +0200] The txt record is added: Success.
[середа, 29 травня 2019 19:58:07 +0200] Let's check each dns records now. Sleep 20 seconds first.
...
[середа, 29 травня 2019 19:58:28 +0200] All success, let's return
[середа, 29 травня 2019 19:58:28 +0200] Verifying: staging.yourdomain.com
[середа, 29 травня 2019 19:58:31 +0200] Success
[середа, 29 травня 2019 19:58:31 +0200] Verifying: *.staging.yourdomain.com
[середа, 29 травня 2019 19:58:34 +0200] Success
...
[середа, 29 травня 2019 19:58:39 +0200] Your cert is in  /home/slavko/.acme.sh/staging.yourdomain.com/staging.yourdomain.com.cer 
[середа, 29 травня 2019 19:58:39 +0200] Your cert key is in  /home/slavko/.acme.sh/staging.yourdomain.com/staging.yourdomain.com.key 
[середа, 29 травня 2019 19:58:39 +0200] The intermediate CA cert is in  /home/slavko/.acme.sh/staging.yourdomain.com/ca.cer 
[середа, 29 травня 2019 19:58:39 +0200] And the full chain certs is there:  /home/slavko/.acme.sh/staging.yourdomain.com/fullchain.cer 


Обновление также простое — просто создайте cron, похожий на

0 0 * * * "/home/user/.acme.sh"/acme.sh --cron --home "/home/user/.acme.sh" > /dev/null

Окончательно

Используйте сертификаты на своем веб-сервере

Код

Фрагменты Terraform можно найти по адресу ;
Роль Ansible, которая поможет вам установить на целевой сервер, можно найти здесь:

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *