Let's EncryptでSSL証明書の新規作成と自動更新(dns-01編)

検証環境

想定サーバー・ドメイン

DNSコンテンツサーバー側

SSLサーバー側

インストール

DNSコンテンツサーバー側の設定

named.conf の設定(一部)例

include "ダイナミックアップデートキーファイル名";

zone "example.jp" {
    type master;
    file "example.jpゾーンファイル名";
};

zone "_acme-challenge.www.example.jp" {
    type master;
    file "_acme-challenge.www.example.jpゾーンファイル名";
    update-policy {
        grant ダイナミックアップデートキー名 name _acme-challenge.www.example.jp. TXT;
    };
};

example.jp ゾーンファイルの設定例

$TTL               300

@                       IN SOA ns.example.jp. domain.example.jp. (
                               2017032201 ; serial
                               7200       ; refresh (2 hours)
                               900        ; retry (15 minutes)
                               2419200    ; expire (4 weeks)
                               86400      ; minimum (1 day)
                               )
                        IN NS ns
_acme-challenge.www     IN NS ns

_acme-challenge.www.example.jp ゾーンファイルの設定例

$TTL               300

@                       IN SOA ns.example.jp. domain.example.jp. (
                               2017032201 ; serial
                               7200       ; refresh (2 hours)
                               900        ; retry (15 minutes)
                               2419200    ; expire (4 weeks)
                               86400      ; minimum (1 day)
                               )
                        IN NS ns

ダイナミックアップデートキーファイルの設定例

key "キー名" {
    algorithm hmac-sha256;
    secret "シークレットキー(BASE64表現)";
};

上記ファイルは以下のコマンドにより生成することができる。

tsig-keygen -a hmac-sha256 キー名 > ダイナミックアップデートキーファイル名
chmod 0400 ダイナミックアップデートキーファイル名

本例における具体的設定例

key "ns-www." {
    algorithm hmac-sha256;
    secret "PfzeGvXiOqtPOwQJY/iNFrvlD3/eKAHRZ0TbyK5GYII=";
};

SSLサーバー側の設定

/etc/periodic.conf

weekly_dehydrated_enable="YES"

自動更新設定(YES=自動更新する)。 periodic(8)にある通り、毎週土曜日3時に実行される。

なお今回、weekly_dehydrated_deployscript は指定しない(後述の HOOK 設定参照のこと)。

/usr/local/etc/dehydrated/ns-www.key

これは先に tsig-keygen コマンドで作成されたファイルである。 DNSコンテンツサーバーと同一になるように設定すること。

/usr/local/etc/dehydrated/config

alias openssl="/usr/bin/openssl"

CHALLENGETYPE="dns-01"
HOOK="${BASEDIR}/hook.sh"
RENEW_DAYS="30"
KEY_ALGO="rsa" KEYSIZE="2048"
#KEY_ALGO="prime256v1"
CONTACT_EMAIL="メールアドレス"
#テスト発行したい場合、以下の2行を有効にすること。
#CA="https://acme-staging.api.letsencrypt.org/directory"
#CA_TERMS="https://acme-staging.api.letsencrypt.org/terms"

/usr/local/etc/dehydrated/domains.txt

example.org www.example.org
example.com www.example.com wiki.example.com

本ファイルの設定については コモンネームの設定に準拠するものとする(例)。

/usr/local/etc/dehydrated/hook.sh

TTL="300"
DNSSERVER="ns.example.jp"
alias nsupdate="/usr/local/bin/nsupdate -k ${BASEDIR}/ns-www.key"

function deploy_challenge {
    local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}"
    printf 'server %s\nupdate add _acme-challenge.%s. %d TXT "%s"\nsend\n' "${DNSSERVER}" "${DOMAIN}" "${TTL}" "${TOKEN_VALUE}" | nsupdate
}

function clean_challenge {
    local DOMAIN="${1}" TOKEN_FILENAME="${2}" TOKEN_VALUE="${3}"
    printf 'server %s\nupdate delete _acme-challenge.%s. TXT\nsend\n' "${DNSSERVER}" "${DOMAIN}" | nsupdate
}

function deploy_cert {
    /usr/sbin/service apache24 restart && /usr/local/bin/dehydrated -gc
}

function unchanged_cert {
    # NOTHING TO DO #
}

function invalid_challenge() {
    # NOTHING TO DO #
}

function request_failure() {
    # NOTHING TO DO #
}

function exit_hook() {
    # NOTHING TO DO #
}

HANDLER=$1; shift; $HANDLER $@

HOOK ファイルのひな形として、/usr/local/etc/dehydrated/hook.sh.example を参照すること。

/usr/local/etc/dehydrated/deploy.sh

参考文献