Skip to content

Instantly share code, notes, and snippets.

@alexandrusavin
Last active July 25, 2024 09:28
Show Gist options
  • Save alexandrusavin/69b26846d6593d6f217219b5bd8882c4 to your computer and use it in GitHub Desktop.
Save alexandrusavin/69b26846d6593d6f217219b5bd8882c4 to your computer and use it in GitHub Desktop.
Add letsencrypt certificate to dd-wrt web interface
#!/bin/sh
if [ `nvram get https_enable` -gt 0 ] ; then
# get the absolute directory of the executable
SELF_PATH=$(cd -P "$(dirname "$0")" && pwd -P)
echo SELF_PATH: ${SELF_PATH}
# extract the mount path
MOUNT_PATH=`echo ${SELF_PATH} | cut -d / -f1-2`
echo MOUNT_PATH: ${MOUNT_PATH}
# do binds
for BIND_PATH in '/jffs' ; do
echo Binding ${BIND_PATH}
if [ "${MOUNT_PATH}" != "${BIND_PATH}" ]; then
grep -q -e "${BIND_PATH}" /proc/mounts || mount -o bind ${MOUNT_PATH}${BIND_PATH} ${BIND_PATH}
fi
done
HTTPS_RESET=0
if [ `pidof httpd` -gt 0 ]; then
echo Stopping httpd
stopservice httpd
HTTPS_RESET=1
fi
echo Binding HTTPS certifcate
grep -q -e "/etc/cert.pem" /proc/mounts || mount -o bind ${MOUNT_PATH}/etc/cert.pem /etc/cert.pem
grep -q -e "/etc/key.pem" /proc/mounts || mount -o bind ${MOUNT_PATH}/etc/key.pem /etc/key.pem
grep -q -e "/etc/privkey.pem" /proc/mounts || mount -o bind ${MOUNT_PATH}/etc/privkey.pem /etc/privkey.pem
if [ "$HTTPS_RESET" = "1" ]; then
echo Starting httpd
startservice httpd
unset HTTPS_RESET
fi
fi

Inspired from this blog post.

  1. Prepare the router

    1. Use portfw to forward port 80 and 445 to the ip of the computer where you have certbot installed

    2. Enable Secure Shell from Services tab

    3. Enable JFFS2 Support form Administration tab

  2. Create the certificate files

    1. Install certbot

      brew install certbot

    2. Go to a folder where you will configure certbot

    3. Execute certbot to create the certificate

      certbot certonly --standalone --config-dir . --logs-dir . --work-dir .

      If it says it cannot bind to port 80 it means you need to add sudo to the above command. If the case then you'll need to change ownsership (chow) of the live and ../../archive folders to get access in the next steps.

    4. cd to ./live/[your.domain]

    5. Create rsa key from private key

      openssl rsa -in privkey.pem -out key.pem

  3. Put the certificate files into the router

    1. cd to jffs

      cd /jffs

    2. create startup folder

      mkdir startup && cd startup

    3. create the script (binds_on_mount.sh) that binds certificate files and make it executable

      chmod +x binds_on_mount.sh

    4. create etc folder in jffs and cd in it

      mkdir /jffs/etc && cd /jffs/etc

    5. create the certificate files from local certbot files

      1. paste contents of key.pem, cert.pem and privkey.pem into their respective file in /jffs/etc
  4. Remove portfw and enable Web GUI Management remote access from Administration tab

    1. Web Access

      1. Protocol: Check https and Uncheck http
    2. Remote Access

      1. Web GUI Management: Enable

      2. Web GUI Port: 443

  5. Test by executing the script and then try to access the web gui. If the browser has a green lock next to the address than everything is correct.

  6. Add command to execute the script on startup

    1. save this command as Startup in Administration > Commands

      cd /jffs/startup && ./binds_on_mount.sh > ./log

@ultrazeus
Copy link

Hello mate.
I think that i just did everything correctly according your very easy how to but i do get a couple of errors when i run ./ the script.

sh: 2228: unknown operand
mount: mounting /jffs/etc/privkey.pem on /etc/privkey.pem failed: No such file or directory``

any ideas ?

Did you manage to solve this?

@larivierec
Copy link

larivierec commented Apr 14, 2020

this worked for me:
mount -o bind /jffs/etc/ssl/fullchain.pem /etc/cert.pem
mount -o bind /jffs/etc/ssl/privkey.pem /etc/key.pem

privkey.pem doesn't seem to be bindable on dd-wrt.
also, keep in mind that since most browsers comme with CA certs, this means we will be shown with a legitimate https cert.

However, since most dd-wrt routers (including mine) dont come with CA certs they are still actually illegitimate.

Just something to keep in mind..
Cheers,

@ultrazeus
Copy link

this worked for me:
mount -o bind /jffs/etc/ssl/fullchain.pem /etc/cert.pem
mount -o bind /jffs/etc/ssl/privkey.pem /etc/key.pem

privkey.pem doesn't seem to be bindable on dd-wrt.
also, keep in mind that since most browsers comme with CA certs, this means we will be show with a legitimate https cert.

However, since most dd-wrt routers (including mine) dont come with CA certs they are still actually illegitimate.

Just something to keep in mind..
Cheers,

Yes this is actually working, thank you for reaching out.

@larivierec
Copy link

Hello mate.
I think that i just did everything correctly according your very easy how to but i do get a couple of errors when i run ./ the script.

sh: 2228: unknown operand
mount: mounting /jffs/etc/privkey.pem on /etc/privkey.pem failed: No such file or directory``

any ideas ?

@sitcomgr see below!
@ultrazeus no problem! 👍

@IvoKvesic
Copy link

IvoKvesic commented May 19, 2022

Hello mate. I think that i just did everything correctly according your very easy how to but i do get a couple of errors when i run ./ the script.

sh: 2228: unknown operand
mount: mounting /jffs/etc/privkey.pem on /etc/privkey.pem failed: No such file or directory``

any ideas ?

After step 1.iii above (Enabling Internal Flash Storage) you also have to enable Clean Internal Flash Storage, hit Apply Settings and then reboot the router. Then you will have mounted the jffs folder. The confirmation of that is that below the two elements of the Administration/JFFS2 Support section, you will see something like Total / Free Size 30.06 MB / 30.03 MB.

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