#!/bin/bash | |
## this little Gist is for Copy the Letsencrypt Cert from an Linux machine (e.g. Raspberry PI or Synology NAS) | |
## to the router (Fritzbox). | |
## It is usefull to be able to speak to the Router over DDNS without any Cert issue in the Browser. | |
## thanks to https://gist.github.com/mahowi for the perfect Idea | |
## put it in /etc/letsencrypt/renewal-hooks/post so it gets run after every renewal. | |
## since Fritz OS 7.25 it is needed to select a Username, from a security point of view | |
## it is always a good idea to have a non default user name. And as normaly a Fritz Box | |
## is connected to the Internet, the prefered method should be WITH Username. | |
# parameters | |
USERNAME="needed since Fritz OS 7.25" | |
PASSWORD="fritzbox-password" | |
CERTPATH="path to cert eg /etc/letsencrypt/live/domain.tld/" | |
CERTPASSWORD="cert password if needed" | |
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 |
Hi Heikh81,
your right this script is only for uploading a new Cert to Fritzbox. But I duckduck your request and here is what I found:
http://guido.vonrudorff.de/fritzbox-rufumleitung-kommandozeile/
the most important fact is
fritz.box/cgi-bin/webcm
this where we should send the request to and we can activate and/or deactivate it with
telcfg%3Asettings%2FCallerIDActions0%2FActive=STATUS&sid=SID
you now how to transfer this to my wget command and it should work.
Thanks for this script, I added it as a renew-hook to my let's encrypt cron job on my local server so that it get's automatically updated.
/usr/local/bin/certbot-auto renew --renew-hook /path-to/fritz_lets_encrypt.sh
Amazing script! I run it of my Synology Diskstation NAS.
Just had to change iconv
to uconv
in line 16 as the Synology Linux flavour doesn't support it out of the box.
Working like charm! But ....
... only when I run the script using internal IP-addresses.
It didn't work using https://example.com as HOST although this URL does let me login to my Fritz!BOX.
Why? Well, because the certificate wasn't valid any more !!!!
TIP: make sure you run this script using HTTP:// to connect to your Fritz!BOX or make sure your run the script before your certificate becomes invalid.
The response for succesfull processing is : "Import of the SSL certificate was successful."
Non succesfull processing doesn't give you any response.
Thanks, im using this with certbot (0.28) as post hook:
certbot renew --post-hook "fritzbox-cert-update.sh"
@FvdLaar
do you really want to send your private cert through an unencrypted connection?
Please DON'T listen to that "TIP" and upload the certificate manually for the first time.
Working like charm! But ....
... only when I run the script using internal IP-addresses.It didn't work using https://example.com as HOST although this URL does let me login to my Fritz!BOX.
Why? Well, because the certificate wasn't valid any more !!!!
TIP: make sure you run this script using HTTP:// to connect to your Fritz!BOX or make sure your run the script before your certificate becomes invalid.
The response for succesfull processing is : "Import of the SSL certificate was successful."
Non succesfull processing doesn't give you any response.
Thats not the design, the script should only be used in 1 network.
Its not designed for transmittion over the world wide web.
mfg
wikrie
do you really want to send your private cert through an unencrypted connection?
Please DON'T listen to that "TIP" and upload the certificate manually for the first time.
I full agree with @ychromosome : DO NOT send private keys or certificates over unsecured connection except is it is in your own DMZ / private (home) network
That's not the design, the script should only be used in 1 network.
Its not designed for transmittion over the world wide web.
I fully agree with @wikrie
Thank you for this script.
I have put it in /etc/letsencrypt/renewal-hooks/post
so it gets run after every renewal.
Thank you for this script.
👍
I have put it in/etc/letsencrypt/renewal-hooks/post
so it gets run after every renewal.
Many thanks I insert your idea into the script that is much bettern than cronjob ...
Amazing script! I run it of my Synology Diskstation NAS.
Just had to changeiconv
touconv
in line 16 as the Synology Linux flavour doesn't support it out of the box.
Hi,
I also wanna put it onto my DS but am not sure where to put it as the folder /etc/letsencrypt/renewal-hooks/post is not existing (currently).
Thanks for a hint.
I also wanna put it onto my DS but am not sure where to put it as the folder /etc/letsencrypt/renewal-hooks/post is not existing (currently).
On my DS I am calling the script from Task Scheduler on weekly basis, same as the Synology's Let's Encrypt renew script (see /usr/syno/etc/synocron.d/syno-letsencrypt.conf
)
I do a small Update to use it with Synology Diskstation directly check out
Synology Fritzbox Cert Transfer
Thanks for your work.
I changed it a bit to
- use
curl
- provide parameters via environment or command line
- better error processing
The result can be found at
I do a small Update to use it with Synology Diskstation directly check out
Synology Fritzbox Cert Transfer
Awesome! Many thanks for this - works like a charm!
Hi All
i also use this script for a fritzbox 7390, soon i will have a 6590, 7490 or 7590, i don't know which i find used for good price
my question:
the myfritz app on android tries to connect to fritzbox with private IP from private network, i cannot type a DNS name there, even if i have one internal for the fritzbox... the app is kind of no DNS mode only and can only connect to an IP.
So in my LetsEncrypt can i somehow add the private IP of my fritzbox (192.168.1.1) or is that not possible
I was reading and did not find the exact issue online, i think about SAN ALTERNATE NAME or something...
Thanks for ideas...
Hi All
i also use this script for a fritzbox 7390, soon i will have a 6590, 7490 or 7590, i don't know which i find used for good price
my question:
the myfritz app on android tries to connect to fritzbox with private IP from private network, i cannot type a DNS name there, even if i have one internal for the fritzbox... the app is kind of no DNS mode only and can only connect to an IP.
So in my LetsEncrypt can i somehow add the private IP of my fritzbox (192.168.1.1) or is that not possible
I was reading and did not find the exact issue online, i think about SAN ALTERNATE NAME or something...Thanks for ideas...
Hi @ant0nwax,
No, first of all, Lets Encrypt does not offer Certificates for IP-Adresses (but is is theoretically posible eg. 1.1.1.1) and second a SSL verfification does not make sense for internal IP-Adresses. You could however probably generate a self signed Certificate and add that to the Android Certificate Storage.
PS: I would not recommend to use a Cable Fritzbox if you don't need the Cable. (Modem takes Power etc...)
Hi @wikrie,
just found out that the script doesn't work for my 7590 with FRITZ!OS 07.25 - I am getting blocked when getting the SID in L19.
The reason seems to be that with 07.25, one can choose between a named user and a login without a user. However, logging in without a user still requires a user name.
This username can be extracted when retrieving the CHALLENGE
(L17), as on my box the response looks like this:
<?xml version="1.0" encoding="utf-8"?>
<SessionInfo>
<SID>0000000000000000</SID>
<Challenge>2127f7cc</Challenge>
<BlockTime>0</BlockTime>
<Rights></Rights>
<Users>
<User last="1">fritz1416</User>
<User>my_actual_user</User>
</Users>
</SessionInfo>
When using fritz1416
as USERNAME
, I can login again and update the certificate.
On an 7490 with 07.21 the whole <Users>...</Users>
block is not there.
Unfortunately I'm no shell expert so I don't really know if this is something that would be possible to solve automatically.
EDIT: I should try the stuff out. Using fritz1416
as a fixed USERNAME
seems to be working on the 7490 with 07.21 as well.
- you may want to change your default username of your fritzbox now, because of security reasons.
- indeed AVM changed the login to demand a username in certain cases.
- why don't you just use the username for now and everything is fine.
Why should I change the default username? It is not allowed for logging in from the internet and when in the LAN it isn't required anyway.
I'll use the default username for now, but maybe could you add this into the gist?
I have the same problem since I updated my 6490 to 7.25 and my 7490 to 7.26. How the script must be changed to work properly?
Thanks for your script, works like charm!
One question: Is there any chance to fork this script to activate/deactivate call forwards?
Or does it only work for submitting the upload form?
Unfortunately, I don't have advanced programming skills, but I think your script already does the most complicated part by getting the SID.
On my German Fritzbox 7580 running firmware 6.83, it is found at: Telefonie -> Rufbehandlung -> Rufumleitung
There I have 1 call forward, and I'd like to switch on/off the checkbox "Aktiv".
If on/off is not possible, then at least I'd like to toggle this checkbox.
Thanks for your answer,
Heiko (Germany)