ACME-Client Lego
Der ACME-Client Lego ist ein unabhängiges, kostenloses Open-Source-Projekt, das in der Sprache Go geschrieben ist. Er ist ideal für individuelle Integration und Skripting und wird von Domain-Registraren und DNS-Anbietern breit unterstützt. Lego ist ein flexibler ACME-Client, der sich leicht in eigene Systeme und Skripte integrieren lässt. Neben der HTTP-01-Validierung bietet er eine DNS-Validierung über viele DNS-Anbieter (Liste der unterstützten DNS-Anbieter) zur Ausstellung von WildCard-SSL-Zertifikaten.
Die Anleitung verwendet eine auf Version Lego 5.*.* überprüfte Syntax und ist für Debian/Ubuntu mit Apache 2 und dem ACME-Client Lego gedacht.
Inhalt des Artikels
- Lego-Installation
- Apache, webroot
- Lego-Konfigurationsdateien
- Ausstellung des Zertifikats
- Bereitstellung auf Apache
- Automatische Erneuerung
Grundbegriffe
- ACME – Protokoll für die automatisierte Ausstellung und Erneuerung von SSL/TLS-Zertifikaten.
- HTTP-01 – ACME-Validierungsmethode, die den Domainbesitz mithilfe einer über HTTP erreichbaren temporären Datei überprüft.
- DNS-01 – Validierungsmethode über den DNS-TXT-Eintrag
_acme-challenge. - EAB kid + hmac – External Account Binding (EAB)-Details von der Zertifizierungsstelle. Sie verknüpfen ACME client mit einem Konto oder Produkt.
- Systemd-Dienst - eine Konfigurationsdatei, die dem Linux-System mitteilt, wie eine Anwendung gestartet und auch nach einem Serverneustart am Laufen gehalten wird.
Wenn in den Beispielen die Domain example.com vorkommt, ersetzen Sie sie stets durch Ihre eigene Domain.
Lego-Installation
apt update
apt install -y curl tar
cd /tmp
LEGO_URL=$(curl -s https://api.github.com/repos/go-acme/lego/releases/latest | sed -n 's/.*"browser_download_url": "\(.*linux_amd64.tar.gz\)".*/\1/p' | head -n1)
echo "$LEGO_URL"
curl -L -o lego.tar.gz "$LEGO_URL"
tar -xzf lego.tar.gz
install -m 0755 lego /usr/local/bin/lego
lego --version
Nach einer erfolgreichen Installation empfehlen wir, die temporären Dateien zu entfernen.
rm -f /tmp/lego /tmp/lego.tar.gz /tmp/LICENSE /tmp/CHANGELOG.md
| Befehl / Wert | Was er bewirkt / was zu ersetzen ist |
|---|---|
apt update |
Aktualisiert die Paketliste. |
apt install -y curl tar |
Installiert die Tools zum Herunterladen und Entpacken von Lego. |
LEGO_URL=... |
Ermittelt die URL des neuesten Linux-amd64-Release-Pakets. |
curl -L -o lego.tar.gz |
Lädt das Lego-Archiv herunter. |
tar -xzf lego.tar.gz |
Entpackt das Archiv. |
install -m 0755 lego /usr/local/bin/lego |
Installiert Lego als ausführbaren Systembefehl. |
lego --version |
Überprüft die installierte Version von Lego. |
Apache, webroot
Dieses Vorgehen erstellt eine grundlegende VirtualHost-Konfiguration für die Domain auf Port 80. Es setzt DocumentRoot, die Berechtigungen für das Webverzeichnis, erstellt Apache-Logs, aktiviert die Konfiguration mit a2ensite, überprüft ihre Korrektheit (apache2ctl configtest) und lädt die Änderungen neu. Abschließend überprüft es die Verfügbarkeit der Website mit einer HTTP-Anfrage curl.
Ersetzen Sie vor dem Ausführen den Wert example.com in der Zeile DOMAIN="example.com" durch Ihre eigene Domain. Die Variable $DOMAIN wird dann in den folgenden Befehlen für Pfade, den Apache-vhost und die Testseite verwendet.
cd /var/www
apt update
apt install -y apache2
systemctl enable --now apache2
a2enmod rewrite headers ssl
systemctl reload apache2
# or just updates
apt update
apt install --only-upgrade apache2
systemctl reload apache2
DOMAIN="example.com"
mkdir -p /var/www/$DOMAIN/public
chown -R www-data:www-data /var/www/$DOMAIN
chmod -R 755 /var/www/$DOMAIN
echo "OK $DOMAIN" > /var/www/$DOMAIN/public/index.html
| Befehl / Wert | Was er bewirkt / was zu ersetzen ist |
|---|---|
cd /var/www |
Wechselt in das Verzeichnis, in dem Webdateien üblicherweise gespeichert werden. |
apt update |
Aktualisiert die Paketliste. |
apt install -y apache2 |
Installiert Apache; -y bestätigt die Installation automatisch. |
systemctl enable --now apache2 |
Aktiviert Apache beim Serverstart und startet ihn gleichzeitig. |
a2enmod rewrite headers ssl |
Aktiviert Module für Weiterleitungen, Header und HTTPS. |
DOMAIN="example.com" |
Setzt die Domain-Variable. Ersetzen Sie example.com durch Ihre eigene Domain. |
mkdir/chown/chmod/echo |
Erstellt den webroot, setzt die Berechtigungen für Apache und speichert eine einfache Testseite. |
HTTP-vhost sowohl für den Apex als auch für die Subdomain:
cat > /etc/apache2/sites-available/$DOMAIN.conf <<EOF
<VirtualHost *:80>
ServerName $DOMAIN
ServerAlias www.$DOMAIN
DocumentRoot /var/www/$DOMAIN/public
<Directory /var/www/$DOMAIN/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog \${APACHE_LOG_DIR}/${DOMAIN}_error.log
CustomLog \${APACHE_LOG_DIR}/${DOMAIN}_access.log combined
</VirtualHost>
EOF
a2ensite "$DOMAIN.conf"
apache2ctl configtest
systemctl reload apache2
curl -I "http://$DOMAIN"
curl -I "http://www.$DOMAIN"
Ergebnis: Nach dem Öffnen von http://example.com sollte die Testseite erscheinen.
| Befehl / Wert | Was er bewirkt / was zu ersetzen ist |
|---|---|
cat > ... <<EOF |
Schreibt einen neuen Apache-HTTP-vhost in eine Datei in sites-available. |
ServerName $DOMAIN |
Die Hauptdomain des virtuellen Hosts. |
ServerAlias www.$DOMAIN |
Erstellt die Behandlung für die Subdomain der ersten Ebene. |
DocumentRoot |
Das Verzeichnis, aus dem Apache Inhalte ausliefert. |
a2ensite "$DOMAIN.conf" |
Aktiviert den vhost. |
apache2ctl configtest |
Überprüft die Syntax der Apache-Konfiguration. |
curl -I http://$DOMAIN |
Überprüft die HTTP-Antwort der Domain. |
Lego-Konfigurationsdateien
Der empfohlene Ansatz für Lego v5 ist, die Einstellungen in einer Konfigurationsdatei zu speichern. Der systemd-Dienst muss dann keinen langen Befehl mit Domains und Hooks enthalten.
Konfigurationsdatei lego.yml
Die .yml-Datei ist eine Textkonfigurationsdatei im YAML-Format, die für eine übersichtliche Notation von Einstellungen, Parametern und strukturierten Daten verwendet wird. Ersetzen Sie vor dem Speichern der YAML-Konfiguration example.com durch Ihre eigene Domain, vas@email.cz durch Ihre Kontakt-E-Mail und die Werte KID / HMAC durch die Angaben aus Ihrer ACME-Zertifikatsbestellung.
mkdir /etc/lego/$DOMAIN
nano /etc/lego/$DOMAIN/lego.yml
storage: /etc/lego/example.com
accounts:
certum-account:
server: certum
email: your@email.com # your email address for CA Certum
acceptsTermsOfService: true
eab:
kid: KID
hmacKey: HMAC
servers:
certum:
url: https://acme.certum.pl/directory
challenges:
http-chal:
http:
# Path to your website's document root.
# Lego will temporarily write a file to this directory .well-known/acme-challenge/
webroot: /var/www/example.com/public
certificates:
example-com:
account: certum-account
challenge: http-chal
domains:
- example.com
- www.example.com
renew:
days: 30
hooks:
deploy:
command: systemctl reload apache2
Tipp! Sie können einen fast vollständigen YML-Inhalt direkt auf dem Server generieren und dann nur die korrekte E-Mail, kid und hmacKey ausfüllen. Führen Sie einfach den folgenden Befehl aus und kopieren Sie den Inhalt von der Seite index.html in die Datei lego.yml.
›› Vorbereitetes YML anzeigen/ausblenden.
cat > "/var/www/$DOMAIN/public/index.html" <<EOF
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>${DOMAIN}</title>
<style>
body { font-family: sans-serif; max-width: 900px; margin: 40px auto; }
pre { background:#f4f4f4; padding:1em; overflow:auto; }
</style>
</head>
<body>
<h1>OK – ${DOMAIN}</h1>
<p>Apache is working correctly.</p>
<h2>lego.yml</h2>
<pre><code>storage: /etc/lego/${DOMAIN}
accounts:
certum-account:
server: certum
email: YOUR_EMAIL
acceptsTermsOfService: true
eab:
kid: YOUR_KID
hmacKey: YOUR_HMAC_KEY
servers:
certum:
url: https://acme.certum.pl/directory
challenges:
http-chal:
http:
webroot: /var/www/${DOMAIN}/public
certificates:
${DOMAIN//./-}:
account: certum-account
challenge: http-chal
domains:
- ${DOMAIN}
- www.${DOMAIN}
renew:
days: 30
hooks:
deploy:
command: systemctl reload apache2
</code></pre>
</body>
</html>
EOF
Die Datei lego.yml enthält den EAB-HMAC, daher muss sie eingeschränkte Berechtigungen haben. Verwenden Sie in der Dokumentation nur Platzhalter.
chmod 600 /etc/lego/$DOMAIN/lego.yml
Überprüfen der Berechtigungen und des Besitzers der Datei:
stat -c "%a %U:%G %n" /etc/lego/$DOMAIN/lego.yml
| Befehl / Wert | Was er bewirkt / was zu ersetzen ist |
|---|---|
storage |
Verzeichnis für das Lego-Konto, die Zertifikate und Metadaten. |
accounts |
Definition des ACME-Kontos einschließlich der E-Mail und der EAB-Details. |
servers.certum.url |
Der Certum-ACME-Endpunkt. |
challenges.http-chal |
Validierung über http. |
certificates |
Liste der Zertifikate, die Lego verwalten soll. |
domains |
Die Apex-Domain und die Wildcard-Domain im Zertifikat. |
renew.days |
Wie viele Tage vor Ablauf Lego erneuern soll. |
hooks.deploy.command |
Befehl nach einer erfolgreichen Ausstellung oder Erneuerung, hier das Neuladen von Apache. |
Ausstellung des SSL/TLS-Zertifikats
Überprüfen Sie vor dem Ausführen echo ${DOMAIN} oder setzen Sie die Variable DOMAIN auf den Namen Ihrer Domain DOMAIN="example.com". Das Tool Lego führt die HTTP-01-Validierung mithilfe einer vorübergehend im webroot gespeicherten Datei durch, überprüft den Domainbesitz und erstellt dann ein SSL/TLS-Zertifikat. Das Zertifikat, der private Schlüssel und das Aussteller-Zertifikat (Zwischenzertifikat) werden im Verzeichnis /etc/lego/${DOMAIN}/certificates/ gespeichert.
lego --config /etc/lego/$DOMAIN/lego.yml
Während der Generierung gibt der ACME-Client Lego Informationen über die Anfrage aus:
root@vmiXXXXXXXX:~# echo ${DOMAIN}
example.com
root@:~# lego --config /etc/lego/$DOMAIN/lego.yml
INFO Archive account scope=accountID filepath=/etc/lego/example.com/accounts/acme.certum.pl/certum-acme/
archives=/etc/lego/example.com/archives/accounts/acme.certum.pl_certum-acme_1785270773.zip
INFO Private key saved. filepath=/etc/lego/example.com/accounts/acme.certum.pl/certum-account/certum-account.key
INFO Registering the account (EAB). email=your@email.com
WARN !!!! HEADS UP !!!!
Your account credentials have been saved in your
configuration directory at "/etc/lego/example.com/accounts".
You should make a secure backup of this folder now. This
configuration directory will also contain private keys
generated by lego and certificates obtained from the ACME
server. Making regular backups of this folder is ideal.
INFO Obtaining bundled SAN certificate. domains="example.com, www.example.com"
INFO Use solver. domain=www.example.com type=http-01
INFO Use solver. domain=example.com type=http-01
INFO http01: Trying to solve HTTP-01. domain=www.example.com
INFO The server validated our request. domain=www.example.com
INFO http01: Trying to solve HTTP-01. domain=example.com
INFO The server validated our request. domain=example.com
INFO Validations succeeded; requesting certificates. domains="example.com, www.example.com"
INFO Waiting for certificates. timeout=30s interval=500ms domains="example.com, www.example.com"
INFO Server responded with a certificate. domains="example.com, www.example.com"
INFO Writing file. filepath=/etc/lego/example.com/certificates/acmeapi-online.crt
INFO Writing file. filepath=/etc/lego/example.com/certificates/acmeapi-online.issuer.crt
INFO Writing file. filepath=/etc/lego/example.com/certificates/acmeapi-online.key
INFO Writing file. filepath=/etc/lego/example.com/certificates/acmeapi-online.pem
INFO Writing file. filepath=/etc/lego/example.com/certificates/acmeapi-online.json
Überprüfen Sie die generierten SSL-Zertifikatsdateien
Zeigt den Inhalt des vom Lego-Dienst erstellten certificates-Verzeichnisses an, einschließlich des Zertifikats, des privaten Schlüssels und des Aussteller-Zertifikats für die ausgewählte Domain.
ls -la /etc/lego/$DOMAIN/certificates/
Das Verzeichnis certificates/ enthält das ausgestellte .crt, .key, Zwischenzertifikate der Zertifizierungsstelle und Metadaten.
Bereitstellen des Zertifikats auf Apache
Dieses Beispiel verwendet die Variable ${DOMAIN}, die Sie bereits vom Anfang der Anleitung an gesetzt haben sollten. Vor dem Ausführen der Befehle können Sie sicherstellen, dass die Variable korrekt gesetzt ist, zum Beispiel: echo ${DOMAIN}
Die Variable ${DOMAIN} wird im Namen der Konfigurationsdatei, in den Werten ServerName und ServerAlias sowie im Pfad zum webroot verwendet.
Achtung! - die Pfade zum SSL-Zertifikat und zum privaten Schlüssel verwenden die Domain in der Form example-com. Die Pfade müssen mit der in der Lego-Konfiguration verwendeten Domain übereinstimmen.
cat > /etc/apache2/sites-available/${DOMAIN}-le-ssl.conf <<EOF
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName ${DOMAIN}
ServerAlias www.${DOMAIN}
DocumentRoot /var/www/${DOMAIN}/public
<Directory /var/www/${DOMAIN}/public>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
SSLEngine on
SSLCertificateFile /etc/lego/${DOMAIN}/certificates/${DOMAIN//./-}.crt
SSLCertificateKeyFile /etc/lego/${DOMAIN}/certificates/${DOMAIN//./-}.key
ErrorLog ${APACHE_LOG_DIR}/${DOMAIN}_ssl_error.log
CustomLog ${APACHE_LOG_DIR}/${DOMAIN}_ssl_access.log combined
</VirtualHost>
</IfModule>
EOF
a2ensite ${DOMAIN}-le-ssl.conf
apache2ctl configtest
systemctl reload apache2
curl -I https://${DOMAIN}
curl -I https://www.${DOMAIN}
Ergebnis: Funktionierendes HTTPS.
| Befehl / Wert | Was er bewirkt / was zu ersetzen ist |
|---|---|
cat > ...-le-ssl.conf |
Erstellt den Apache-HTTPS-vhost. |
ServerName / ServerAlias |
Gibt die Apex-Domain und die Subdomain an. |
SSLCertificateFile |
Pfad zum Zertifikat. |
SSLCertificateKeyFile |
Pfad zum privaten Schlüssel. |
a2ensite |
Aktiviert den HTTPS-vhost. |
systemctl reload apache2 |
Lädt die neue Apache-Konfiguration neu. |
curl -I https://... |
Überprüft die HTTPS-Antwort. |
Automatische Erneuerung
Lego kann das Zertifikat automatisch erneuern, erstellt aber nach der Installation nicht selbst die systemd-Units für die regelmäßige Ausführung. Für die automatische Erneuerung müssen daher zwei Units erstellt werden:
- lego-example-com-renew.service – führt die Prüfung und bei Bedarf die Erneuerung des Zertifikats aus.
- lego-example-com-renew.timer – stellt sicher, dass der Dienst täglich zu einer festgelegten Zeit läuft.
Ersetzen Sie vor dem Einfügen bei Bedarf example-com im Namen des Service/Timers durch Ihren eigenen Namen und ersetzen Sie example.com im Konfigurationspfad durch Ihre eigene Domain.
cat > /etc/systemd/system/lego-${DOMAIN//./-}-renew.service <<EOF
[Unit]
Description=Renew ACME Certum SSL for example.com using Lego HTTP-01
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/lego --config /etc/lego/${DOMAIN}/lego.yml
EOF
cat > /etc/systemd/system/lego-${DOMAIN//./-}-renew.timer <<EOF
[Unit]
Description=Daily Lego renewal check for ${DOMAIN}
[Timer]
OnCalendar=*-*-* 03:20:00
RandomizedDelaySec=1800
Persistent=true
[Install]
WantedBy=timers.target
EOF
Überprüfen Sie nach dem Erstellen der Units deren Inhalt:
cat /etc/systemd/system/lego-example-com-renew.service
echo "----------------"
cat /etc/systemd/system/lego-example-com-renew.timer
Laden Sie die neuen Units neu, aktivieren Sie den Timer und überprüfen Sie, ob er läuft:
systemctl daemon-reload
systemctl enable --now lego-${DOMAIN//./-}-renew.timer
systemctl list-timers | grep lego
Ergebnis: Der Timer ist aktiv und systemd hat seinen nächsten Lauf eingeplant.
| Befehl / Wert | Was er bewirkt / was zu ersetzen ist |
|---|---|
lego-example-com-renew.service |
Systemd-Dienst für einen einmaligen Lauf von Lego renew/run. |
Type=oneshot |
Der Dienst startet, erledigt seine Arbeit und beendet sich. |
ExecStart |
Führt Lego gemäß lego.yml aus. |
lego-example-com-renew.timer |
Systemd-Timer, der den Dienst regelmäßig ausführt. |
OnCalendar |
Zeitpunkt der täglichen Prüfung. |
RandomizedDelaySec |
Zufällige Verzögerung, damit die Anfragen nicht alle exakt zur gleichen Zeit starten. |
Persistent=true |
Führt eine verpasste Ausführung nach dem Start des Servers aus. |
systemctl enable --now |
Aktiviert den Timer und startet ihn sofort. |
Sicherer Test des Dienstes:
systemctl start lego-${DOMAIN//./-}-renew.service
systemctl status lego-${DOMAIN//./-}-renew.service --no-pager
journalctl -u lego-${DOMAIN//./-}-renew.service -n 100 --no-pager
Ergebnis: Wenn das Zertifikat nicht kurz vor dem Ablauf steht, meldet Lego möglicherweise, dass keine Erneuerung erforderlich ist. Das ist korrektes Verhalten.
| Befehl / Wert | Was er bewirkt / was zu ersetzen ist |
|---|---|
systemctl start ...service |
Führt den Erneuerungsdienst manuell für einen Test aus. |
systemctl status ... |
Zeigt an, ob der Dienst erfolgreich beendet wurde |
journalctl -u ... |
Zeigt die neuesten Logs des Dienstes. |
Liste der verfügbaren Lego-Units:
ls -l /etc/systemd/system/lego*
systemctl list-timers | grep lego
Ergebnis: Beide Varianten zeigen alle Dienste und Timer, die mit dem ACME-Client Lego zusammenhängen.
Wie geht es weiter?
Zurück zur Infozentrum
Fehler gefunden oder etwas nicht verstanden? Schreiben Sie uns!
