Skip to content

Instantly share code, notes, and snippets.

@wikrie
Forked from FvdLaar/fritzbox-cert-update.sh
Last active October 22, 2023 13:26
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wikrie/5ce6417b322d75b8674699dc39cf7335 to your computer and use it in GitHub Desktop.
Save wikrie/5ce6417b322d75b8674699dc39cf7335 to your computer and use it in GitHub Desktop.
Fritzbox Fritz!Box AVM SSL Letsencrypt automatically update
#!/bin/bash
# parameters
USERNAME=""
PASSWORD="fritzbox-password"
CERTPATH="/usr/syno/etc/certificate/system/default/" ##this is the default Path for Synology Cert
CERTPASSWORD=""
HOST=http://192.168.178.1 ## I use IP instead of fritz.box for synology updates
# 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>.*$//'`
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
# continue with the script on success
# 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
RESPONSE=`wget -q -O - $HOST/cgi-bin/firmwarecfg --header="Content-type: multipart/form-data boundary=$BOUNDARY" --post-file $TMP | grep SSL`
fi
fi
# clean up
rm -f $TMP
if [ -z "$RESPONSE" ]
then
echo $HOST ": Certificate import failed."
else
echo $HOST ": " $RESPONSE
fi
@wikrie
Copy link
Author

wikrie commented Jul 6, 2020

Thanks to @FvdLaar I use your version to build a running synology Version

Update to get it working from Synology DS directly
1st: Path = /usr/syno/etc/certificate/system/default/
2nd: Host = I do not know why but it only works for me if I change fritz.box to IP of FB
3rd: line 22 change not exiting iconv to uconv on Synology NAS

After that it is working directly

last open thing add script to post hook or create scheduler for it

@DaCHack
Copy link

DaCHack commented Aug 24, 2021

Thanks for this awesome contribution!
I took this with slight adjustments for my own setup.

Just a note (primarily to myself for future reference) but of value to others:
Since FritzOS version 7.25 you MUST add a username. There is a standard username automatically generated for you in the user settings. For me it worked simply using this name with the known admin password that I used without a user before.

@jdvmanen
Copy link

jdvmanen commented Oct 26, 2021

This is exactly where I'm looking for, but I don't get it operational..

Here is my script:

#!/bin/bash

parameters

USERNAME="MY_USERNAME"
PASSWORD="MY_PASSWORD"
CERTPATH="/usr/syno/etc/certificate/system/default/"
##this is the default Path for Synology Cert
CERTPASSWORD=""
HOST=http://192.168.2.1 ## I use IP instead of fritz.box for synology updates

make and secure a temporary file

TMP="$(mktemp -p /tmp -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
# continue with the script on success
# 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
RESPONSE=wget -q -O - $HOST/cgi-bin/firmwarecfg --header="Content-type: multipart/form-data boundary=$BOUNDARY" --post-file $TMP | grep SSL
fi
fi

clean up

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

clean up

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

I've removed the empty lines because it was complaining about them - weird enough.

But it looks that the line 'TMP="$(mktemp -p /tmp -t XXXXXX)"' is failing, because the 'chmod 600 $TMP' is failing with error 'File not found'. And the file termination seems to be failty.

Code execution and result:
user@NAS: /etc/fritz_cert$ sh cert_to_fritz.sh
chmod: cannot access '/tmp/3Ne9uQ'$'\r\r': No such file or directory
cert_to_fritz.sh: line 57: syntax error near unexpected token fi' cert_to_fritz.sh: line 57: fi '

Any advice?

@wikrie
Copy link
Author

wikrie commented Oct 28, 2021

What happens if you try to run the temple creation on shell directly?

Here is an output of my system:

chris@ds918plus:~$ mktemp -p /tmp -t XXXXXX
/tmp/phbkNC

for me the Message sounds like a broken or missformated File. Please use Notepad++ copy the raw Content again and modify it in Notepad++ .

br
chris

@wikrie
Copy link
Author

wikrie commented Oct 28, 2021

to make it even better use save linked fiele option under the RAW Button
image

@jdvmanen
Copy link

Works! Many thanks.

I don't know where the difference in is. I already used Notepad++.

Nevertheless, thanks!

@jdvmanen
Copy link

o yes there was an issue with permissions in /usr/syno/etc/certificate/system/default.
I've issued sudo chmod 777 -R /usr/syno/etc/certificate/system/default to solve that issue but maybe it is a bit too open now..
Any advice to keep this as secure as possible?

@wikrie
Copy link
Author

wikrie commented Oct 30, 2021 via email

@bomale
Copy link

bomale commented Nov 10, 2021

Hello I have resolved issue with letsencrypt "http challenge" but now the script don't work.
I have new file as image
immagine

@wikrie
Copy link
Author

wikrie commented Nov 10, 2021

Hi Bomale, What is your issue and what do you solved?
My script only transfer existing Certs from somewhere to a Router from AVM (Fritzbox), so its just a simple copy routine to get a Fritzbox up and running with a valid cert.

@bomale
Copy link

bomale commented Nov 11, 2021

Hi Bomale, What is your issue and what do you solved?

After renewal letsencrypt certificate fullchain.pem and privkey.pem are missing.
the script give error on:
cat $CERTPATH/privkey.pem >> $TMP
cat $CERTPATH/fullchain.pem >> $TMP

@PaulMerk
Copy link

PaulMerk commented Dec 25, 2021

I had to change lines 41 and 42 to RSA-privkey.pem and RSA-fullchain.pem respectively

chmod 600 for the temp file and the certificate files was insufficient. What is recommended instead of 755 ?
EDIT: changed to 644

general remark for using Notepad++:
make sure, that line ends are formatted as UNIX

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment