Automatisierte Lets Encrypt Erneuerung (inkl. Portfreigabe + Fritz!Box Integration)

princemaxwell

Benutzer
Mitglied seit
13. Dez 2013
Beiträge
30
Punkte für Reaktionen
1
Punkte
8
Hallo zusammen,

ich habe nun eine vollständig automatisierte Let's Encrypt Erneuerung auf die Beine gestellt, ohne dass ein manuelles Eingreifen nötig ist, denn diese ständigen Portfreigaben und anschließenden Portsperrungen gingen mir ein wenig auf den Nerv.

Folgendes funktioniert nun automatisch:

  1. Aktivierung Portfreigabe von Port 80 auf der Fritz!Box per Python-Skript (über TR-064 Schnittstelle)
  2. Deaktivierung Syno Firewall
  3. Erneuerung Zertifikat
  4. Aktivierung Syno Firewall
  5. Deaktivierung Portfreigabe von Port 80 auf der Fritz!Box per Python-Skript (über TR-064 Schnittstelle)
  6. Einspielung des Zertifikats in die Fritz!Box per Bash-Skript

Das funktioniert alles komplett automatisch, so dass ein Eingreifen von mir nicht mehr nötig ist.

Zu meinem Problem:
Jetzt wollte ich die Aufgabe im Aufgabenplaner anlegen, aber habe als Auswahl nur monatlich oder alle drei Monate.
Bei heutiger (8.3.20) Verlängerung des Zertifikats läuft dieses am 6.6.20 (90 Tage) ab. Bei Auswahl "alle drei Monate" im Aufgabenplaner wäre der nächste Termin aber erst am 8.6.20, also zu spät. Gibt es irgendeine Möglichkeit, den Aufgabenplaner auf 90 Tage einzustellen?? :confused:

Gruß
princemaxwell
 

TeXniXo

Benutzer
Mitglied seit
07. Mai 2012
Beiträge
4.948
Punkte für Reaktionen
94
Punkte
134
Nein, aber wenn du diese Aufgabe 2 x anlegst -1 x heute und 1 x in 90 Tagen und die erste angelegte Aufgabe ruft diesen Befehl in 180 Tagen (also 90 Tagen später nach der 2. Aufgabe). Somit hast du alle 90 Tagen diesen Befehl ausgeführt.
 

ebecker

Benutzer
Mitglied seit
03. Mrz 2015
Beiträge
32
Punkte für Reaktionen
0
Punkte
6
Kannst du diese Automatisierung mal hier mal dokumentieren/hochladen? Würde mich brennend interessieren, bekomme ich aber selbst nicht hin.

Zum Thema: Was passiert denn, wenn du es jeden Monat machst? Viel hilft viel oder geht die Verlängerung nach 1 Monat noch nicht?
 

TeXniXo

Benutzer
Mitglied seit
07. Mai 2012
Beiträge
4.948
Punkte für Reaktionen
94
Punkte
134
Monatliche Durchführung bringt hier in dem konkreten Fall sowieso nichts. Was soll das denn eig. bewirken, wenn die Verlängerung bereits durchgeführt wurde?
 

princemaxwell

Benutzer
Mitglied seit
13. Dez 2013
Beiträge
30
Punkte für Reaktionen
1
Punkte
8
Monatlich ist aber die nächst kleinere Einheit kleiner 90 Tage, die im Aufgabenplaner zur Verfügung steht, da 3-monatlich größer 90 Tage ist.

Nein, aber wenn du diese Aufgabe 2 x anlegst -1 x heute und 1 x in 90 Tagen und die erste angelegte Aufgabe ruft diesen Befehl in 180 Tagen (also 90 Tagen später nach der 2. Aufgabe). Somit hast du alle 90 Tagen diesen Befehl ausgeführt.

Das verstehe ich nicht...und bringt mich doch auch nicht wirklich weiter.
Beispiel:
Verlängerung am 8.3.20, Zertifikat gültig bis 6.6.20.
Task 1 (3-monatlich) wird aber erst am 8.6.20 wieder ausgeführt.
Task 2 (3-monatlich) würde entsprechend der Einstellung am 6.6. ausgeführt. OK.

Danach passt es aber schon wieder nicht.
Verlängerung am 6.6.20, Zertifikat gültig bis 4.9.20.
Task 1 (3-monatlich) lief am 8.6.20 (ohne Erfolg) und dann am 8.9.20 (also wieder +2 Tage zu spät).
Task 2 (3-monatlich) würde entsprechend der Einstellung am 6.9. ausgeführt. Auch zu spät.

Und so weiter und so weiter, durch die 90 Tage liegen wir immer ca. 2 Tage unter 3-monatlich und so verschiebt sich das Datum zur Verlängerung immer nach vorne.

Die Skripte mit Anleitung stelle ich gerne rein, fasse ich später mal zusammen...
 

kev.lin

Benutzer
Mitglied seit
17. Jul 2007
Beiträge
474
Punkte für Reaktionen
6
Punkte
18
Kannst du diese Automatisierung mal hier mal dokumentieren/hochladen? Würde mich brennend interessieren, ...
Da schliesse ich mich an - eine Beschreibung mit den entsprechenden Script-Snippets wäre super!
 

princemaxwell

Benutzer
Mitglied seit
13. Dez 2013
Beiträge
30
Punkte für Reaktionen
1
Punkte
8
Anleitung

Ich habe mal eine kleine Anleitung erstellt, wie Ihr einen völlig automatisierten Prozess zur Let's Encrypt Erneuerung einstellen könnt, ohne dauerhaft Port 80 freigegeben zu lassen, oder diesen immer manuell zu öffnen.

Ich habe das Python Skript nochmal auf Bash umgeschrieben, dann spart man sich die Installation der Python Module über das Paketzentrum.

Folgendes funktioniert fortan automatisch:
  1. Aktivierung Portfreigabe von Port 80 auf der Fritz!Box per Bash-Skript (über TR-064 Schnittstelle)
  2. Deaktivierung Syno Firewall
  3. Erneuerung Zertifikat
  4. Aktivierung Syno Firewall
  5. Deaktivierung Portfreigabe von Port 80 auf der Fritz!Box per Bash-Skript (über TR-064 Schnittstelle)
  6. Einspielung des Zertifikats in die Fritz!Box per Bash-Skript

Vorab prüft ihr mal, ob die Fritz!Box die TR-064 Schnittstelle offen hat:
Bitte in der Fritz!Box (Ansicht: Erweitert) unter "Heimnetz > Netzwerk > Netzwerkeinstellungen" im Bereich "Heimnetzfreigaben" die Option "Zugriff für Anwendungen zulassen" aktivieren (standardmäßig aktiviert)!

Danach sucht Ihr Euch einen Pfad auf der DiskStation aus, wo die Skripte abgelegt werden.
Beispiel: /volume1/data/scripts/

Dort erstellt ihr mit dem Text-Editor der DiskStation zwei Dateien:
> fb_port.sh
Rich (BBCode):
#!/bin/bash

################################################################################

# Bitte in der Fritz!Box (Ansicht: Erweitert) unter "Heimnetz > Netzwerk > Netzwerkeinstellungen" 
# im Bereich "Heimnetzfreigaben" die Option "Zugriff für Anwendungen zulassen" aktivieren (standardmäßig aktiviert)!

# Seit dem neuesten Fritz!OS ist es nur noch möglich, dass lokale Netzwerkgeräte sich selber eine
# Portfreigabe erstellen. Da die DiskStation dies für sich selber tut ist das also kein Problem!

# Getestet mit Fritz!OS 07.12

################################################################################

# Please configure your Fritz!Box (View: Advanced) > Home Network > Home Network Overview"
# in "Network Settings" and activate the option "Allow access for applications" (activated by default)!

# Port mapping entries are only allowed for hosts inside of LAN.
# Furthermore hosts can only add port mapping entries for themselves and not for other hosts in the LAN.
# It is not intended to allow port mapping entries for the guest network or hosts with IP addresses routed into WAN.

# Tested with Fritz!OS 07.12

################################################################################

# http://fritz.box:49000/tr64desc.xml
# https://avm.de/service/schnittstellen/

################################################################################

# variables
# please configure your Fritz!Box IP and login
FBIP="fritz.box"
FBUSER="user"
FBPASS="password"

# please configure your Synology DiskStation IP
SYNOIP="192.168.178.100"

################################################################################


# script, don't change anything here
if [ "$1" == "0" ]
	then
		STATUS="DEACTIVATED!"
elif [ "$1" == "1" ]
	then
		STATUS="ACTIVATED!"
fi

location="/upnp/control/wanpppconn1"
uri="urn:dslforum-org:service:WANPPPConnection:1"
action='AddPortMapping'
SoapParamString="<NewRemoteHost>0.0.0.0</NewRemoteHost>
<NewExternalPort>80</NewExternalPort>
<NewProtocol>TCP</NewProtocol>
<NewInternalPort>80</NewInternalPort>
<NewInternalClient>$SYNOIP</NewInternalClient>
<NewEnabled>$1</NewEnabled>
<NewPortMappingDescription>Lets Encrypt</NewPortMappingDescription>
<NewLeaseDuration>0</NewLeaseDuration>"

if [ "$1" == "0" ] || [ "$1" == "1" ]
	then
		curl -k -m 5 --anyauth -u "$FBUSER:$FBPASS" https://$FBIP:49443$location -H 'Content-Type: text/xml; charset="utf-8"' -H "SoapAction:$uri#$action" -d "<?xml version='1.0' encoding='utf-8'?><s:Envelope s:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/' xmlns:s='http://schemas.xmlsoap.org/soap/envelope/'><s:Body><u:$action xmlns:u='$uri'>$SoapParamString</u:$action></s:Body></s:Envelope>" -s
		printf "Port sharing: $STATUS"
	else
		printf "No expected parameter (0|1) given. Port sharing not activated."
fi

> fb_update_cert.sh
Rich (BBCode):
#!/bin/bash

set -euo pipefail
IFS=$'\n\t'

################################################################################

# parameters
USERNAME="user"
PASSWORD="password"

################################################################################

CERTPATH="/usr/syno/etc/certificate/_archive/$(cat /usr/syno/etc/certificate/_archive/DEFAULT)"
CERTPASSWORD=""
HOST="http://fritz.box"
unset RESPONSE

# make and secure a temporary file. Arrange for automatic cleanup
TMP=""
trap 'rm -f "$TMP"' exit
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>.*$//')
if [ -z "$CHALLENGE" ]
  then
    RESPONSE="Is HOST-name pointing to a Fritz!BOX?"
  else
    # continue with the script on success
    HASH="$(echo -n "$CHALLENGE-$PASSWORD" | uconv -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>.*$//')

    if [[ $SID == "0000000000000000" ]]
      then
        RESPONSE="Failed to authenticate."
      else
        # generate our upload request
        BOUNDARY="---------------------------"$(date +%Y%m%d%H%M%S)
        (
        printf -- "--%s\r\n" "$BOUNDARY"
        printf "Content-Disposition: form-data; name=\"sid\"\r\n\r\n%s\r\n" "$SID"
        printf -- "--%s\r\n" "$BOUNDARY"
        printf "Content-Disposition: form-data; name=\"BoxCertPassword\"\r\n\r\n%s\r\n" "$CERTPASSWORD"
        printf -- "--%s\r\n" "$BOUNDARY"
        printf "Content-Disposition: form-data; name=\"BoxCertImportFile\"; filename=\"BoxCert.pem\"\r\n"
        printf "Content-Type: application/octet-stream\r\n\r\n"
        cat "$CERTPATH"/privkey.pem
        cat "$CERTPATH"/fullchain.pem
        printf "\r\n"
        printf -- "--%s--" "$BOUNDARY"
        ) >> "$TMP"
        
        # upload the certificate to the box
        RESPONSE=$(wget -q -O - "$HOST/cgi-bin/firmwarecfg" --header="Content-type: multipart/form-data boundary=$BOUNDARY" --post-file "$TMP" | grep SSL)
    fi
fi

if [ -z "$RESPONSE" ]
  then
    echo $HOST ": Certificate import failed."
  else
    echo $HOST ": " "$RESPONSE"
fi

(Hinweis: die "fb_update_cert.sh" basiert inhaltlich auf diesem Post: https://www.synology-forum.de/showthread.html?103708-Automatischer-Zertifikats-Export-in-Fritzbox&p=837864&viewfull=1#post837864)

Beide Dateien mit dem Text-Editor auf der DiskStation öffnen und bearbeiten:
> fb_port.sh --- bitte Zeile 32-38 anpassen
> fb_update_cert.sh --- bitte Zeile 9-10 anpassen

Danach in Systemsteuerung > Aufgabenplaner ein "Benutzerdefiniertes Skript" als "Geplante Aufgabe" anlegen.
Den Zeitplan nach eigenen Wünschen definieren.
Unter Aufgabeneinstellungen kann der Haken bei "Ausführungsdetails per E-Mail senden" gesetzt werden.

Unter Befehl ausführen > Benutzerdefiniertes Skript einfügen (Pfad zum Script anpassen):
Rich (BBCode):
bash /volume1/data/scripts/fb_port.sh 1
synofirewall --disable
/usr/syno/sbin/syno-letsencrypt renew-all -v
synofirewall --enable
bash /volume1/data/scripts/fb_port.sh 0
bash /volume1/data/scripts/fb_update_cert.sh

Fertig!
 
  • Like
Reaktionen: n0j0e

B@stler

Benutzer
Mitglied seit
24. Mrz 2021
Beiträge
1
Punkte für Reaktionen
0
Punkte
1
Hallo princemaxwell,
danke für deine Mühe, hat mir sehr weiter geholfen. Ich habe leider das Problem das ich in meiner FB 7490 (OS Vers. 07.21) keine Portweiterleitung mit deinen erarbeiteten Skript (fb_port.sh) anlegen kann. Dabei habe ich im Aufgabenplaner folgende Meldung:
<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<s:Fault>
<faultcode>s:Client</faultcode>
<faultstring>UPnPError</faultstring>
<detail>
<UPnPError xmlns="urn:dslforum-org:control-1-0">
<errorCode>402</errorCode>
<errorDescription>Invalid Args</errorDescription>
</UPnPError>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>Port sharing: ACTIVATED!
Ich hoffe einer von euch kann mir dabei behilflich sein.
Danke für eure Posts.
 

princemaxwell

Benutzer
Mitglied seit
13. Dez 2013
Beiträge
30
Punkte für Reaktionen
1
Punkte
8
Hi B@astler,
das ist schon komisch, bei mir hat es mit 7.21 und nun auch mit 7.25 bisher gut geklappt.
Hast Du alle Anpassungen vorgenommen?

Das Script legt keine Portweiterleitung an, sondern aktiviert und deaktiviert eine vorhandene Poretweiterleitung nur.
Anlegen musst Du sie schon einmalig manuell.
 

thodie

Benutzer
Mitglied seit
26. Jul 2017
Beiträge
11
Punkte für Reaktionen
2
Punkte
3
Seltsam, ich habe nur einen Task angelegt, der unter "root" läuft und folgende Zeile als Script ausführt (wie oben) - damit klappt das seit Jahren ohne irgenwelche Ports zu öffnen unter 6.x und 7.x. Das Ding läuft 2x die Woche, falls es mal nicht klappt - wie gesagt, da sind keine Ports offen. Alles zugenagelt!

/usr/syno/sbin/syno-letsencrypt renew-all
 

Fusion

Benutzer
Mitglied seit
06. Apr 2013
Beiträge
12.382
Punkte für Reaktionen
418
Punkte
359
@thodie das funktioniert nur, wenn du ein Zertifikat für eine synology.me Adresse (oder QuickConnect) benutzt, weil dort die Verifizierung über DNS-01 und die Synology DNS Server läuft.
Mit allen anderen dynDNS Diensten oder Domains die http-01 benutzen kann dies nicht funktionieren (oder es ist doch etwas nicht so zugenagelt wie du denkst).
 
  • Like
Reaktionen: kev.lin

thodie

Benutzer
Mitglied seit
26. Jul 2017
Beiträge
11
Punkte für Reaktionen
2
Punkte
3
Ahhh jetzt bin ich klüger! Danke, habe mich schon gewundert! :)
 
  • Like
Reaktionen: Fusion

Adama

Benutzer
Mitglied seit
05. Mrz 2013
Beiträge
572
Punkte für Reaktionen
43
Punkte
54
  AdBlocker gefunden!

Du bist nicht hier, um Support für Adblocker zu erhalten, denn dein Adblocker funktioniert bereits ;-)

Klar machen Adblocker einen guten Job, aber sie blockieren auch nützliche Funktionen.

Das Forum wird mit einem hohen technischen, zeitlichen und finanziellen Aufwand kostenfrei zur Verfügung gestellt. Wir zeigen keine offensive oder Themen fremde Werbung. Bitte unterstütze dieses Forum, in dem du deinen Adblocker für diese Seite deaktivierst.