Let’s Encryptの証明書発行をAzure DNSとacme.shで自動化する

SSL 証明書を利用したい場合、無料で利用可能な Let’s Encrypt が広く使われるようになってきました。公開するサーバの通信を暗号化するのに便利です。

ただ、Let’s Encryptで発行された証明書は、有効期限が90日間しかありません。

Linux OSの場合、certbotツールなどを利用して自動更新も可能ですが、更新の仕組みでLet’s Encryptのサーバから公開するサーバにHTTP通信を行います。Let’s EncryptのサーバIPは、非公開になっているため、ファイアウォールなどで接続元を限定しているような環境下では困ってしまいます。

そこで、DNSサーバのレコード登録を行うことで、証明書発行が行える仕組みを採用してみます。ただし、更新するときもDNSサーバのレコードを一時的に登録しなければならないため、今回は acme.sh というツールを利用します。

DNSレコード登録

まずは、DNSレコードに証明書発行を行うサーバのFQDNを登録します。

Azure VMの場合、公開IPが動的に割り当たっていることもありますが、Azure DNSの「エイリアス」レコードを利用することで対応できます。

対象のDNS ゾーンで、「+レコード セット」から追加します。エイリアスのレコード セットを「はい」にすると、Azure リソースが選択できるようになるので、Azure VMに割り当たっている公開IPアドレスを選択します。

Azure DNS レコード操作用の役割作成

Azure DNS のレコードを操作するための権限を作成します。各種IDが必要になるため、事前に確認しておきます。

テナントIDとサブスクリプションIDの確認

Azure CLIを利用して Azureにログインすると、テナントIDとサブスクリプションIDが確認できます

> az login

To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code BXYG7SP2V to authenticate.
[
  {
    "cloudName": "AzureCloud",
    "id": "96053071-b4e9-4f59-96f2-32d4a433fc47",
    "isDefault": true,
    "name": "Pay-As-You-Go",
    "state": "Enabled",
    "tenantId": "10cb0c90-4524-4ef1-9793-8fbbf1986054",
    "user": {
      "name": "noobient@foobar.com",
      "type": "user"
    }
  }
]

役割定義用jsonファイル

TXTレコードのみを扱える役割を登録するため、jsonファイル「role.json」をテキストエディタ等で作成します。

{
  "Name":"DNS TXT Contributor",
  "Id":"",
  "IsCustom":true,
  "Description":"Can manage DNS TXT records only.",
  "Actions":[
    "Microsoft.Network/dnsZones/TXT/*",
    "Microsoft.Network/dnsZones/read",
    "Microsoft.Authorization/*/read",
    "Microsoft.Insights/alertRules/*",
    "Microsoft.ResourceHealth/availabilityStatuses/read",
    "Microsoft.Resources/deployments/read",
    "Microsoft.Resources/subscriptions/resourceGroups/read"
  ],
  "NotActions":[

  ],
  "AssignableScopes":[
    "/subscriptions/96053071-b4e9-4f59-96f2-32d4a433fc47"
  ]
}

役割の登録

> az role definition create --role-definition role.json

役割の割り当て

役割をDNSゾーンのみに割り当てます。

※リソースグループとDNSゾーンの名前は適宜置き換えてください。

> az ad sp create-for-rbac --name "DnsValidator" --role "DNS TXT Contributor" --scopes "/subscriptions/96053071-b4e9-4f59-96f2-32d4a433fc47/resourceGroups/FooDNSGroup/providers/Microsoft.Network/dnszones/foobar.com"

  Retrying role assignment creation: 1/36
  Retrying role assignment creation: 2/36
The output includes credentials that you must protect. Be sure that you do not include these credentials in your code or check the credentials into your source control. For more information, see https://aka.ms/azadsp-cli
{
  "appId": "a92160c6-023f-4bb9-aa15-d25bff308f71",
  "displayName": "DnsValidator",
  "name": "http://DnsValidator",
  "password": "KfG2u1cQKQ0vuonpH4#bDKsp13lRo3E6",
  "tenant": "10cb0c90-4524-4ef1-9793-8fbbf1986054"
}

赤字のIDとパスワードは後で使用しますので、メモしましょう。

acme.sh で 証明書発行

次に、対象となる Linux 上で acme.sh を利用した証明書発行を行います。

acme.sh のインストール

# git clone https://github.com/Neilpang/acme.sh.git /opt/acme.sh

Azure DNS 操作用 環境変数の登録

# export AZUREDNS_SUBSCRIPTIONID="96053071-b4e9-4f59-96f2-32d4a433fc47"
# export AZUREDNS_TENANTID="10cb0c90-4524-4ef1-9793-8fbbf1986054"
# export AZUREDNS_APPID="a92160c6-023f-4bb9-aa15-d25bff308f71"
# export AZUREDNS_CLIENTSECRET="KfG2u1cQKQ0vuonpH4#bDKsp13lRo3E6"

発行処理をすると、設定ファイルに保存されるため、一時的な環境変数としてセットすればOKです。

ステージング用の証明書発行

# /opt/acme.sh/acme.sh --issue --dns dns_azure --dnssleep 10 --force -d foobar.com --server letsencrypt --staging

サーバを指定しないと、zerossl の証明書が発行されます。

本番用の証明書発行

# /opt/acme.sh/acme.sh --issue --dns dns_azure --dnssleep 10 --force -d foobar.com --serverletsencrypt

ウェブサーバ設定の変更

今回は、OpenLightSpeedのサーバ設定を変更します。

# vi /opt/lsws/conf/vhosts/foobar/vhconf.conf
(変更点)---

keyFile          /opt/lsws/cert/privkey.pem    
certFile         /opt/lsws/cert/fullchain.pem
# vi /opt/lsws/conf/httpd_config.conf
(変更点)---
map *, foobar.com

証明書の配置

# /opt/acme.sh/acme.sh --install-cert -d foobar.com --fullchain-file /opt/lsws/cert/fullchain.pem --key-file /opt/lsws/cert/privkey.pem  --server  letsencrypt --reloadcmd "systemctl restart lsws"

更新処理の登録

certbot用のcron登録解除

# mv /etc/cron.d/certbot /etc/cron.d/.certbot

acme.sh用のcron登録

# vi /etc/cron.d/acme.sh
---
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

0 */12 * * * root /opt/acme.sh/acme.sh --renew --dns dns_azure --dnssleep 10 --force -d foobar.com --server letsencrypt --reloadcmd "systemctl restart lsws"

CDN配信元の変更

配信元の作成と配信グループを作成し、ルールエンジンの配信グループ指定を変更します。

変更後、元の配信グループ、配信元の順で削除します。

タイトルとURLをコピーしました