Kehittäjät → Oppaat

Wildcard-varmenteet DNS-01:llä ja certbotilla

DNS-01-haaste todistaa, että hallitset verkkotunnusta, TXT-tietueen avulla verkkosivun sijaan. Se on ainoa tapa saada wildcard-varmenne, ja se toimii myös palvelimille, joihin ei pääse internetistä. Tämän hookin avulla certbot julkaisee tietueen NameOcean API:n kautta.

NameOcean myöntää itse ilmaisen wildcard-varmenteen jokaiselle NameOcean DNS:ää käyttävälle verkkotunnukselle, uusii sen ja antaa latauslinkin (SSL tai POST /ssl/example.com). Käytä tätä ohjetta, kun palvelimesi pitää hankkia ja uusia oma varmenteensa.

Mitä tarvitset

  • Verkkotunnuksen DNS NameOceanissa (nimipalvelimet ns1.nameocean.net – ns4.nameocean.net).
  • certbot, dig (dnsutils tai bind-utils) ja nameocean CLI palvelimella.
  • API-avain, jolla on oikeudet dns:read ja dns:write. Rajaa se mahdollisuuksien mukaan palvelimen IP-osoitteeseen.

1. Asenna hook

root@server
# curl -fsSL https://nameocean.net/install.sh | sh
# curl -fsSL https://nameocean.net/developers/guides/letsencrypt-dns-01/nameocean-hook.sh \
    -o /etc/letsencrypt/nameocean-hook.sh
# chmod 700 /etc/letsencrypt/nameocean-hook.sh
# echo 'NAMEOCEAN_API_KEY=no_live_…' > /etc/letsencrypt/nameocean.env
# chmod 600 /etc/letsencrypt/nameocean.env

Avain säilytetään tiedostossa, jota vain root voi lukea; certbotin tallentamat uusimisasetukset eivät koskaan sisällä sitä.

2. Hae varmenne

root@server
# certbot certonly --manual --preferred-challenges dns \
    --manual-auth-hook "/etc/letsencrypt/nameocean-hook.sh auth" \
    --manual-cleanup-hook "/etc/letsencrypt/nameocean-hook.sh cleanup" \
    -d example.com -d "*.example.com"

Jokaiselle nimelle hook etsii NameOcean-vyöhykkeistäsi vyöhykkeen, johon nimi kuuluu, lisää _acme-challenge-TXT-tietueen ja odottaa, kunnes kaikki neljä nimipalvelinta palauttavat sen, yleensä kymmenessä sekunnissa. Tarkistuksen jälkeen siivousvaihe poistaa täsmälleen lisäämänsä tietueen. Sekä example.com että *.example.com käyttävät nimeä _acme-challenge.example.com; molemmat arvot julkaistaan rinnakkain.

3. Uusiminen

certbot tallentaa hookit varmenteen yhteyteen, joten sen ajastin uusii varmenteen samalla tavalla. Testaa tämä kerran:

root@server
# certbot renew --dry-run

Jokainen hookin lisäämä ja poistama tietue näkyy kohdassa Hallintapaneeli → Toiminta yhdessä sen tehneen avaimen kanssa, ja niistä lähetetään dns.record.created- ja dns.record.deleted-webhook-tapahtumat.

Hook

Lue se ennen kuin suoritat sen rootina. Se kutsuu vain nameocean CLI:tä ja digiä.

/etc/letsencrypt/nameocean-hook.sh
#!/bin/sh
# certbot DNS-01 hooks for NameOcean DNS:
#   --manual-auth-hook "/etc/letsencrypt/nameocean-hook.sh auth"
#   --manual-cleanup-hook "/etc/letsencrypt/nameocean-hook.sh cleanup"
# Needs the nameocean CLI and an API key with dns:write, in /etc/letsencrypt/nameocean.env:
#   NAMEOCEAN_API_KEY=no_live_...
set -e
[ -f /etc/letsencrypt/nameocean.env ] && . /etc/letsencrypt/nameocean.env && export NAMEOCEAN_API_KEY

# the zone CERTBOT_DOMAIN is in: the longest of your zones it ends with
zone="$NAMEOCEAN_ZONE"
if [ -z "$zone" ]; then
  for z in $(nameocean dns ls --json | sed -n 's/.*"name": *"\([^"]*\)".*/\1/p'); do
    case "$CERTBOT_DOMAIN" in "$z" | *".$z") [ ${#z} -gt ${#zone} ] && zone="$z" ;; esac
  done
fi
[ -n "$zone" ] || { echo "no NameOcean DNS zone for $CERTBOT_DOMAIN" >&2; exit 1; }
name="_acme-challenge"
[ "$CERTBOT_DOMAIN" = "$zone" ] || name="_acme-challenge.${CERTBOT_DOMAIN%.$zone}"

case "$1" in
auth)
  id=$(nameocean dns add "$zone" TXT "$name" "$CERTBOT_VALIDATION" --ttl 5m --json \
    | sed -n 's/.*"id": *\([0-9][0-9]*\).*/\1/p' | head -n 1)
  [ -n "$id" ] || { echo "could not add the TXT record" >&2; exit 1; }
  echo "$id" # certbot passes this to the cleanup hook as CERTBOT_AUTH_OUTPUT
  # wait until all four nameservers answer with it (usually a few seconds)
  for i in $(seq 1 60); do
    n=0
    for ns in ns1 ns2 ns3 ns4; do
      dig +short TXT "$name.$zone" "@$ns.nameocean.net" | grep -q -- "$CERTBOT_VALIDATION" && n=$((n + 1))
    done
    [ "$n" -eq 4 ] && exit 0
    sleep 2
  done
  echo "the TXT record is not on every nameserver after 2 minutes" >&2
  exit 1
  ;;
cleanup)
  [ -z "$CERTBOT_AUTH_OUTPUT" ] || nameocean dns rm "$zone" TXT "$CERTBOT_AUTH_OUTPUT"
  ;;
*)
  echo "usage: $0 auth|cleanup" >&2
  exit 2
  ;;
esac

Ilman CLI:tä

Hook tekee kaksi API-kutsua, jotka voit tehdä mistä tahansa ACME-asiakasohjelmasta tai ohjelmointikielestä:

curl
$ curl -X POST https://nameocean.net/api/v1/dns/example.com/records \
    -H "Authorization: Bearer $NAMEOCEAN_API_KEY" -H "Content-Type: application/json" \
    -d '{"type": "TXT", "hostname": "_acme-challenge", "text": "<validation>", "ttl": "5m"}'
{"id": 4190, "type": "TXT", "hostname": "_acme-challenge", …}
$ curl -X DELETE https://nameocean.net/api/v1/dns/example.com/records/TXT/4190 \
    -H "Authorization: Bearer $NAMEOCEAN_API_KEY"