H
HabNeFritzbox
Guest
War auch nur eine Alternative zum basteln auf der FB selbst. Sollte mit nem RasPI oder so auch gehen, oder ggf. auf einem Gerät von nem Freund.
Zur Automatisierung evtl. noch ein paar Anregungen. Hier ein kleines Powershell script zum Login und hochladen des Zertifikats: (getestet auf FritzOS 6.50 und Fritzbox 7490):
#!/bin/bash
# parameters
USERNAME="<may be empty>"
PASSWORD="<fritzbox/user password>"
CERTPATH="<location of privkey.pem and fullchain.pem>"
CERTPASSWORD="<may be empty>"
HOST=http://fritz.box
# make and secure a temporary file
TMP="$(mktemp -t XXXXXX)"
chmod 600 $TMP
# login to the box and get a valid SID
CHALLENGE=`wget -q -O - $HOST/login_sid.lua | sed -e 's/^.*<Challenge>//' -e 's/<\/Challenge>.*$//'`
HASH="`echo -n $CHALLENGE-$PASSWORD | iconv -f ASCII -t UTF16LE |md5sum|awk '{print $1}'`"
SID=`wget -q -O - "$HOST/login_sid.lua?sid=0000000000000000&username=$USERNAME&response=$CHALLENGE-$HASH"| sed -e 's/^.*<SID>//' -e 's/<\/SID>.*$//'`
# generate our upload request
BOUNDARY="---------------------------"`date +%Y%m%d%H%M%S`
printf -- "--$BOUNDARY\r\n" >> $TMP
printf "Content-Disposition: form-data; name=\"sid\"\r\n\r\n$SID\r\n" >> $TMP
printf -- "--$BOUNDARY\r\n" >> $TMP
printf "Content-Disposition: form-data; name=\"BoxCertPassword\"\r\n\r\n$CERTPASSWORD\r\n" >> $TMP
printf -- "--$BOUNDARY\r\n" >> $TMP
printf "Content-Disposition: form-data; name=\"BoxCertImportFile\"; filename=\"BoxCert.pem\"\r\n" >> $TMP
printf "Content-Type: application/octet-stream\r\n\r\n" >> $TMP
cat $CERTPATH/privkey.pem >> $TMP
cat $CERTPATH/fullchain.pem >> $TMP
printf "\r\n" >> $TMP
printf -- "--$BOUNDARY--" >> $TMP
# upload the certificate to the box
wget -q -O - $HOST/cgi-bin/firmwarecfg --header="Content-type: multipart/form-data boundary=$BOUNDARY" --post-file $TMP | grep SSL
# clean up
rm -f $TMP
Hallo zusammen!
Ich verwende jetzt letsencrypt.sh mit der dns-01 challenge. Vorteil: Ich muß im lokalen Netz keinen Webserver laufen haben.
Hallo zusammen!
Herzlichen Dank dafür! Das hat mir sehr geholfen, dass Aktualisieren des Zertifikats auf meiner Fritzbox zu automatisieren. War bloss die falsche Sprache. Falls es jemanden helfen sollte, hier mein Port des Codes nach bash:
ssl_certificate /etc/ssl/box.mydomain.de.chain.crt;
ssl_certificate_key /etc/ssl/box.mydomain.de.key;
cat $CERTPATH/box.mydomain.de.key >> $TMP
cat $CERTPATH/box.mydomain.de.chain.crt >> $TMP
running dehydrated ...
# INFO: Using main config file /etc/dehydrated/config
Processing www.mydomain.de
+ Signing domains...
+ Generating private key...
+ Generating signing request...
+ Requesting new certificate order from CA...
+ Received 1 authorizations URLs from the CA
+ Handling authorization for www.mydomain.de
+ 1 pending challenge(s)
+ Deploying challenge tokens...
+ Responding to challenge for www.mydomain.de authorization...
+ Cleaning challenge tokens...
+ Challenge validation has failed :(
ERROR: Challenge is invalid! (returned: invalid) (result: ["type"] "http-01"
["status"] "invalid"
["error","type"] "urn:ietf:params:acme:error:unauthorized"
["error","detail"] "Invalid response from http://www.mydomain.de/.well-known/acme-challenge/h_XmpMoWwrhoMCduYPMoU3LqkahnU_SKenWOplJOBcc [77.13.154.186]: \"\u003c?xml version=\\\"1.0\\\" encoding=\\\"iso-8859-1\\\"?\u003e\\n\u003c!DOCTYPE html PUBLIC \\\"-//W3C//DTD XHTML 1.0 Transitional//EN\\\"\\n \\\"http://www.\""
["error","status"] 403
["error"] {"type":"urn:ietf:params:acme:error:unauthorized","detail":"Invalid response from http://www.mydomain.de/.well-known/acme-challenge/h_XmpMoWwrhoMCduYPMoU3LqkahnU_SKenWOplJOBcc [77.13.154.186]: \"\u003c?xml version=\\\"1.0\\\" encoding=\\\"iso-8859-1\\\"?\u003e\\n\u003c!DOCTYPE html PUBLIC \\\"-//W3C//DTD XHTML 1.0 Transitional//EN\\\"\\n \\\"http://www.\"","status":403}
["url"] "https://acme-v02.api.letsencrypt.org/acme/chall-v3/13060478464/JOngRw"
["token"] "h_XmpMoWwrhoMCduYPMoU3LqkahnU_SKenWOplJOBcc"
["validationRecord",0,"url"] "http://www.mydomain.de/.well-known/acme-challenge/h_XmpMoWwrhoMCduYPMoU3LqkahnU_SKenWOplJOBcc"
["validationRecord",0,"hostname"] "www.mydomain.de"
["validationRecord",0,"port"] "80"
["validationRecord",0,"addressesResolved",0] "77.13.154.186"
["validationRecord",0,"addressesResolved",1] "2003:e0:a3bf:29a:c225:6ff:fea6:166d"
["validationRecord",0,"addressesResolved"] ["77.13.154.186","2003:e0:a3bf:29a:c225:6ff:fea6:166d"]
["validationRecord",0,"addressUsed"] "2003:e0:a3bf:29a:c225:6ff:fea6:166d"
["validationRecord",0] {"url":"http://www.mydomain.de/.well-known/acme-challenge/h_XmpMoWwrhoMCduYPMoU3LqkahnU_SKenWOplJOBcc","hostname":"www.mydomain.de","port":"80","addressesResolved":["77.13.154.186","2003:e0:a3bf:29a:c225:6ff:fea6:166d"],"addressUsed":"2003:e0:a3bf:29a:c225:6ff:fea6:166d"}
["validationRecord",1,"url"] "http://www.mydomain.de/.well-known/acme-challenge/h_XmpMoWwrhoMCduYPMoU3LqkahnU_SKenWOplJOBcc"
["validationRecord",1,"hostname"] "www.mydomain.de"
["validationRecord",1,"port"] "80"
["validationRecord",1,"addressesResolved",0] "77.13.154.186"
["validationRecord",1,"addressesResolved",1] "2003:e0:a3bf:29a:c225:6ff:fea6:166d"
["validationRecord",1,"addressesResolved"] ["77.13.154.186","2003:e0:a3bf:29a:c225:6ff:fea6:166d"]
["validationRecord",1,"addressUsed"] "77.13.154.186"
["validationRecord",1] {"url":"http://www.mydomain.de/.well-known/acme-challenge/h_XmpMoWwrhoMCduYPMoU3LqkahnU_SKenWOplJOBcc","hostname":"www.mydomain.de","port":"80","addressesResolved":["77.13.154.186","2003:e0:a3bf:29a:c225:6ff:fea6:166d"],"addressUsed":"77.13.154.186"}
["validationRecord"] [{"url":"http://www.mydomain.de/.well-known/acme-challenge/h_XmpMoWwrhoMCduYPMoU3LqkahnU_SKenWOplJOBcc","hostname":"www.mydomain.de","port":"80","addressesResolved":["77.13.154.186","2003:e0:a3bf:29a:c225:6ff:fea6:166d"],"addressUsed":"2003:e0:a3bf:29a:c225:6ff:fea6:166d"},{"url":"http://www.mydomain.de/.well-known/acme-challenge/h_XmpMoWwrhoMCduYPMoU3LqkahnU_SKenWOplJOBcc","hostname":"www.mydomain.de","port":"80","addressesResolved":["77.13.154.186","2003:e0:a3bf:29a:c225:6ff:fea6:166d"],"addressUsed":"77.13.154.186"}]
["validated"] "2021-05-12T16:12:58Z")
done.
WELLKNOWN
verwendet werden soll (https://github.com/dehydrated-io/dehydrated/blob/master/docs/wellknown.md) nicht in der Konfiguration des HTTP-Servers eingetragen wurde. Das ist aber - angesichts der Infos oben hoffentlich verzeihlich - auch nur geraten von mir.Ja, da steht nämlich: GAR NICHTS.Ohne dehydrated zu kennen, aber anhand des logs hat letsencrypt unter http://www.mydomain.de/.well-known/acme-challenge/h_XmpMoWwrhoMCduYPMoU3LqkahnU_SKenWOplJOBcc was anderes vorgefunden als erwartet.
DNS-Challenge fordert das nicht und spart "gröbste Verrenkungen"wenn explizit gefordert wird den Server unter Port 80 und 443 erreichen zu können
Das sieht das ACME Protokoll bei der HTTP-01 challenge so vor.Portweiterleitungen auf alternative Ports werden von acme/dehydrated konsequent abgelehnt
DNS-Challenge vs. feste Ports auf der FritzBox?DNS-Challenge fordert das nicht und spart "gröbste Verrenkungen"
#!/bin/bash
BASEDIR=/tmp/flash/dehydrated
PRIVATE_KEY=/tmp/flash/dehydrated/private_key.pem
WELLKNOWN=/var/media/ftp/uStor01/webseiten/mydomain/.well-known/acme-challenge/
KEYSIZE=2048
[email protected]
#
RENEW_DAYS="25"
dehydrated
NICHT automatisch konfiguriert (aber die entsprechende Anleitung habe ich ja oben schon einmal verlinkt).server.modules += ("alias")
alias.url += (
"/.well-known/acme-challenge/" => "/var/www/dehydrated/",
)
server.modules += ( "mod_access" )
index-file.names = ( "index.cgi", "index.html", "index.htm", "default.htm", "index.php", "index.rb" )
mimetype.assign = (
".pdf" => "application/pdf",
".sig" => "application/pgp-signature",
".spl" => "application/futuresplash",
".class" => "application/octet-stream",
".ps" => "application/postscript",
".torrent" => "application/x-bittorrent",
".dvi" => "application/x-dvi",
".gz" => "application/x-gzip",
".pac" => "application/x-ns-proxy-autoconfig",
".swf" => "application/x-shockwave-flash",
".tar.gz" => "application/x-tgz",
".tgz" => "application/x-tgz",
".tar" => "application/x-tar",
".zip" => "application/zip",
".mp3" => "audio/mpeg",
".m3u" => "audio/x-mpegurl",
".wma" => "audio/x-ms-wma",
".wax" => "audio/x-ms-wax",
".ogg" => "application/ogg",
".wav" => "audio/x-wav",
".gif" => "image/gif",
".jar" => "application/x-java-archive",
".jpg" => "image/jpeg",
".jpeg" => "image/jpeg",
".png" => "image/png",
".xbm" => "image/x-xbitmap",
".xpm" => "image/x-xpixmap",
".xwd" => "image/x-xwindowdump",
".css" => "text/css",
".html" => "text/html",
".htm" => "text/html",
".js" => "text/javascript",
".asc" => "text/plain",
".c" => "text/plain",
".cpp" => "text/plain",
".log" => "text/plain",
".conf" => "text/plain",
".text" => "text/plain",
".txt" => "text/plain",
".dtd" => "text/xml",
".xml" => "text/xml",
".mpeg" => "video/mpeg",
".mpg" => "video/mpeg",
".mov" => "video/quicktime",
".qt" => "video/quicktime",
".avi" => "video/x-msvideo",
".asf" => "video/x-ms-asf",
".asx" => "video/x-ms-asf",
".wmv" => "video/x-ms-wmv",
".bz2" => "application/x-bzip",
".tbz" => "application/x-bzip-compressed-tar",
".tar.bz2" => "application/x-bzip-compressed-tar",
"" => "application/octet-stream",
)
url.access-deny = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi", ".rb", ".cgi" )
server.port = 80
server.pid-file = "/var/run/lighttpd.pid"
server.username = "wwwrun"
server.groupname = "wwwrun"
connection.kbytes-per-second = 0
server.kbytes-per-second = 0
server.chroot = "/var/media/ftp/uStor01/webseiten/mydomain/"
dir-listing.activate = "disable"
dir-listing.encoding = "utf-8"
server.modules += ( "mod_openssl" )
$SERVER["socket"] == ":443" {
ssl.engine = "enable"
ssl.pemfile = "/tmp/flash/lighttpd/crt.pem"
#ssl.use-compression = "disable"
}
server.document-root = "/websites"
dehydrated
?dehydrated
kümmert sich ausschließlich darum, die notwendigen Dateien zum richtigen Zeitpunkt in einem Verzeichnis zu erzeugen, das ohnehin schon von einem HTTP-Server für Clients (auf der WAN-Seite einer FRITZ!Box, wenn wir schon von einer solchen reden) bereitgestellt wird.dehydrated
IRGENDETWAS ausrichten kann, muß man dafür sorgen, daß bei einem Zugriff aus dem Internet auf die aktuelle IP-Adresse (der Box) am Port 80 auch eine Datei http://<mein_domain_name>/.well-known/acme-challenge/index.html
OHNE jede Angabe von Credentials (Benutzername und/oder Kennwort) einwandfrei gelesen werden kann, wobei man diese Datei index.html
im passenden Verzeichnis selbst erzeugen muß. Erst dann, wenn das problemlos funktioniert, hat der LE-Server überhaupt die Chance, die von dehydrated
an derselben Stelle erzeugten Daten zur Kontrolle der "Herrschaft" über die angegebene Domain auch abzurufen - das alles muß also schon funktionieren, BEVOR man dehydrated
überhaupt aufruft./var/media/ftp/uStor01/webseiten/mydomain
wäre (wie es wohl als chroot
-Jail angedacht ist nach der Konfiguration).server.document-root
am Ende der lighttpd
-Konfiguration, wenn da ein /websites
steht ... denn danach wäre das "Wurzelverzeichnis" für den HTTP-Content ja das Unterverzeichnis /websites
unterhalb des Root-Verzeichnisses /var/media/ftp/uStor01/webseiten/mydomain
- also letztlich das Verzeichnis /var/media/ftp/uStor01/webseiten/mydomain/websites
. ALLES das, was dann über diesen Server ausgeliefert werden könnte und nicht über einen anderen Alias von anderer Stelle käme, stünde unterhalb dieses Verzeichnisses ... bei dehydrated
wäre dann also auch /var/media/ftp/uStor01/webseiten/mydomain/websites/.well-known/acme-challenge
als Verzeichnis für die Response-Daten anzugeben.dehydrated
-Konfiguration auch nicht mehr) wohl doch die schlauere Lösung ... zumal die Challenge-/Response-Daten einer ACME-Validierung ohnehin nur temporären Charakter haben (ein "replay" wäre hier auch tödlich) und daher auch nur an einer temporären Stelle gespeichert werden sollten. Da paßt dann /var/www/something
auch im FRITZ!OS, weil /var
eben beschreibbar ist.index.html
(oder was auch sonst da verwendet wird) problemlos abrufen läßt, gilt das ja noch lange nicht für die WAN-Seite einer FRITZ!Box ... dazu braucht es dann schon noch eine Portfreigabe für TCP-Port 80 (und andere akzeptiert das ACME-Protokoll nicht) auf der WAN-Seite, wobei ich mir ohnehin (basierend auf dem anderen Thread) die Frage stelle, ob diese FRITZ!Box überhaupt direkt am Internet hängt oder ob sie als IP-Client irgendwo in einem LAN steckt und es für das Ausstellen eines LE-Zertifikats ohnehin noch die Portfreigabe von Port 80 an der externen IPv4-Adresse auf die interne IP-Adresse dieser FRITZ!Box bräuchte ... zumal man dann bei einer solchen Portfreigabe ja auch noch externe und interne Portnummer unterschiedlich wählen könnte (weil das der ACME-Server gar nicht bemerkt).ar7.cfg
möglich (oder anderer Dateien) ... und das dann eben auch nicht "on the fly" und nur mal für die Zeit, wo ein LE-Zertifikat erzeugt werden soll. Spätestens wenn dazu noch ein Neustart des dsld
erforderlich sein sollte und der bei PPPoE mit der Vergabe einer neuen externen Adresse einhergeht, wird es schnell komplizierter, als mancher es wahrhaben will.