What's new

Lets Encrypt not updating, or?

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

Same here, not working...
Is it possible to generate the Let's Encrypt manually and upload it to the router, at least for now until ASUS has a firmware update, anyone know how?
 
Same problem here. Though I did a feedback report to Asus with the suggestion to upgrade the Acme client.
 
Just to let you guys know that Asus are aware of it, and are working on resolving it for a future firmware update.
 
I also got an e-mail from ASUS tech support today telling me it will be in the next firmware update.
Yep I had a rep say to check back in early 2020 for solution push via firmware update. I am currently looking into a script solution on this matter for temporary fix.

Something like this shell script offers that can be pointed to generate certs to the location of the certificate store via cron job.
https://github.com/Neilpang/acme.sh
 
Last edited:
Yep I had a rep say to check back in early 2020 for solution push via firmware update. I am currently looking into a script solution on this matter for temporary fix.

Something like this shell script offers that can be pointed to generate certs to the location of the certificate store via cron job.
https://github.com/Neilpang/acme.sh
That's what I've been using for certificates for a while, although it takes a bit of tweaking to play nice with asuswrt's defaults. This might be a helpful starting point if you're going to write something, or just use it as is.
Code:
#!/bin/sh

ACME_DIRECTORY='/opt/share/acme'
ACME_LOG='/opt/var/log/acme.log'

# Add user-script entries
# Usage: acme_scripts [TOGGLE]
acme_scripts() {
    local SCRIPT
    if [ "$1" = 'disable' ]; then
        for SCRIPT in 'configs/profile.add' 'scripts/services-start'; do
            if [ -f "/jffs/$SCRIPT" ]; then
                # Remove acme line
                sed -i '/## acme ##/d' "/jffs/$SCRIPT"
                # Remove scripts which do nothing
                if [ "$(grep -cvE '^[[:space:]]*(#|$)' "/jffs/$SCRIPT")" -eq 0 ]; then
                    rm -f "/jffs/$SCRIPT"
                fi
            fi
        done
        # Remove cron job
        crontab -l | grep -v '#acme update#$' | crontab -
        # Remove event script
        rm -f '/jffs/scripts/.acme.event.sh'
    elif [ "$1" = 'enable' ]; then
        # Create event script
        local ACME_ABSDIR ACME_MINUTE
        ACME_ABSDIR="$(readlink -f -- "$ACME_DIRECTORY")"
        ACME_ABSDIR="${ACME_ABSDIR//'/'\\''}"
        ACME_MINUTE="$(awk -v min=0 -v max=59 'BEGIN{srand(); print int(min+rand()*(max-min+1))}')"
        cat > '/jffs/scripts/.acme.event.sh' << EOF
#!/bin/sh

SCRIPT="\$1"
shift
case "\$SCRIPT" in
    'services-start')
        { crontab -l | grep -v '#acme update#$' ; echo '$ACME_MINUTE 0 * * * /jffs/scripts/.acme.event.sh cron #acme update#'; } | crontab -
    ;;
    'alias')
        if [ -x '$ACME_ABSDIR/acme.sh' ]; then
            for ARG in "\$@"; do
                case "\$ARG" in
                    '--install-cert'|'--issue') ACME_ISSUE='yes';;
                    '--renew-hook') ACME_CMD='yes';;
                    '--key-file') ACME_KEY='yes';;
                    '--fullchain-file') ACME_CRT='yes';;
                esac
            done
            if [ "\$ACME_ISSUE" = 'yes' ]; then
                [ "\$ACME_CRT" != 'yes' ] && set -- "\$@" '--fullchain-file' '/jffs/.cert/cert.pem'
                [ "\$ACME_KEY" != 'yes' ] && set -- "\$@" '--key-file' '/jffs/.cert/key.pem'
                [ "\$ACME_CMD" != 'yes' ] && set -- "\$@" '--renew-hook' '/jffs/scripts/.acme.event.sh renew'
            fi
            '$ACME_ABSDIR/acme.sh' --home '$ACME_ABSDIR' --config-home '$ACME_ABSDIR/data' --cert-home '$ACME_ABSDIR/data/cert' "\$@"
        else
            echo "\$0: acme: not found" >&2
            return 1
        fi
    ;;
    'renew')
        if [ -x '/jffs/scripts/acme-renew' ]; then
            /jffs/scripts/acme-renew
        else
            service reload_httpd
        fi
    ;;
    'cron')
        if [ -x '$ACME_ABSDIR/acme.sh' ]; then
            '$ACME_ABSDIR/acme.sh' --cron --home '$ACME_ABSDIR' --config-home '$ACME_ABSDIR/data' --cert-home '$ACME_ABSDIR/data/cert' > /dev/null
        fi
    ;;
esac
EOF
        chmod +x '/jffs/scripts/.acme.event.sh'

        # Add event triggers
        if [ ! -f '/jffs/scripts/services-start' ]; then
            printf '#!/bin/sh\n\n. /jffs/scripts/.acme.event.sh services-start "$@" ## acme ##\n' > '/jffs/scripts/services-start'
            chmod +x '/jffs/scripts/services-start'
        elif ! grep -Fq '## acme ##' '/jffs/scripts/services-start'; then
            printf '. /jffs/scripts/.acme.event.sh services-start "$@" ## acme ##\n' >> '/jffs/scripts/services-start'
        fi
        # Add acme command
        if [ ! -f '/jffs/configs/profile.add' ] || ! grep -qF '## acme ##' '/jffs/configs/profile.add'; then
            echo 'acme() {( /jffs/scripts/.acme.event.sh alias "$@" )} ## acme ##' >> '/jffs/configs/profile.add'
        fi
        # Add cron job
        { crontab -l | grep -v '#acme update#$' ; echo "$ACME_MINUTE 0 * * * /jffs/scripts/.acme.event.sh cron #acme update#"; } | crontab -
    fi
}

acme_install() {

    curl -sL 'https://github.com/Neilpang/acme.sh/archive/master.tar.gz' | tar xzf -
    (
        cd acme.sh-master || return
        chmod +x acme.sh
        mkdir -p "$ACME_DIRECTORY"
        local ACME_ABSDIR
        ACME_ABSDIR="$(readlink -f -- "$ACME_DIRECTORY")"
        sh acme.sh --install --noprofile --nocron --home "$ACME_ABSDIR" --config-home "$ACME_ABSDIR/data" --cert-home "$ACME_ABSDIR/data/cert" --log "$(readlink -f -- "$ACME_LOG")"
    )
    rm -rf acme.sh-master
}

case "$1" in
    'install')
        acme_install
        acme_scripts 'enable'
    ;;
    'uninstall')
        acme_scripts 'disable'
    ;;
esac

Example usage would be something like
Code:
./acme.sh install
# add the acme command to the current shell, or just reconnect
acme() {( /jffs/scripts/.acme.event.sh alias "$@" )}
# issue a certificate
export GANDI_LIVEDNS_KEY="XXXXXXXXXXXXXXXXXXXXXXXX"
acme --issue --dns "dns_gandi_livedns" -d "example.com" -d "*.example.com"

By default it restarts the webserver after renewing, but you can put a script named acme-renew into /jffs/scripts if you want more control.
Code:
#!/bin/sh

logger -t 'acme' "running renew script ($0)"

# Restart WebGUI
service restart_httpd

# Restart nginx
[ -x '/opt/etc/init.d/S80nginx' ] && /opt/etc/init.d/S80nginx restart
 
Looks like bug with non bash shells added in the last commit, for now you can replace master.tar.gz with 6eaf2d67b7588f23f1870c8813d3d6d391820b89.tar.gz in the acme_install function to grab the version before that. Hopefully it'll be fixed or reverted soon.
 
Last edited:
Looks like bug with non bash shells added in the last commit, for now you can replace master.tar.gz with 6eaf2d67b7588f23f1870c8813d3d6d391820b89.tar.gz in the acme_install function to grab the version before that. Hopefully it'll be fixed or reverted soon.
Thanks for the info but now i'm getting

acme.sh: cd: line 115: can't cd to acme.sh-master


Update:

you also need to change the folder to :cd acme.sh-6eaf2d67b7588f23f1870c8813d3d6d391820b89

But now the error i get is
Unknown parameter : --noprofile
 
Last edited:
Yea, that one is my bad, it looks like I browsed the repo at the point of the last commit instead of the merge (Nov 16, 2018 in this case). 6140a3c26ba5cf26bc15a88cb4477c400b207ffa should work.
 
Yea, that one is my bad, it looks like I browsed the repo at the point of the last commit instead of the merge (Nov 16, 2018 in this case). 6140a3c26ba5cf26bc15a88cb4477c400b207ffa should work.
Installation is working :)!

in the GUIpages its still mention updating do i need to put this setting to None in the DDNS section?
 
There shouldn't be any problem either way, but you might as well to stop it from trying while it's broken.

Actually, the Import/Persistent Auto-generated might be better. Just set it to not generate a certificate. You might need to reinstall the cert if the webui overwrites it, and then restart the webui.
Code:
acme --install-cert -d example.com
service restart_httpd
 
Last edited:
There shouldn't be any problem either way, but you might as well to stop it from trying while it's broken.

Actually, the Import/Persistent Auto-generated might be better. Just set it to not generate a certificate. You might need to reinstall the cert if the webui overwrites it, and then restart the webui.
Code:
acme --install-cert -d example.com
service restart_httpd

The only thing i can see is i cannot find the cert folder.... Actually its not there.... I must be doing something wrong
 
You'll need to issue a cert first, there's guides for various DNS providers here, or if yours isn't listed, you can install socat from entware and use standalone mode. Just use acme instead of acme.sh so the alias fills in the paths for you.

There's a gandi example above, standalone mode would be something like
Code:
acme  --issue  -d example.com  --standalone
 
Is there anyway for someone to make this idiot proof(like me)
maybe with some layman explanation as how to install this
Thank you
 
Ok, I think I have a solution for *.asuscomm.com certificates. Add the following script to /opt/share/acme/dnsapi, or wherever you've set it to install to
Code:
#!/bin/sh

dns_asus_add() {
    HOSTNAME="${1#_acme-challenge.}"
    TXTDATA="$2"

    # Reuse the current IP address
   IP="$(nslookup "$HOSTNAME" 'ns1.asuscomm.com' | awk 'NR>2&&/^Address/{print $(NF==2?2:3);exit}')"

    # Router MAC address location is hardware dependent
    for LAN_MAC_NAME in et0macaddr et1macaddr et2macaddr; do
        MAC_ADDR="$(nvram get "$LAN_MAC_NAME")"
        if [ -n "$MAC_ADDR" ] && [ "$MAC_ADDR" != '00:00:00:00:00:00' ]; then break; fi
    done

    # Use openssl to generate the password
    PASSWORD="$(printf '%s' "${MAC_ADDR//:/}${IP//./}" | openssl md5 -hmac "$(nvram get secret_code)" 2>/dev/null | awk '{print toupper($2)}')"

    HTTP_RESULT="$(curl -fs -w '%{http_code}' -o /dev/null -u "${MAC_ADDR//:/}:$PASSWORD" "http://nwsrv-ns1.asus.com/ddns/update.jsp?hostname=$HOSTNAME&acme_challenge=1&txtdata=$TXTDATA&myip=$IP")"
    case "$HTTP_RESULT" in
        200|220|230) return 0;;
    esac
    return 1
}

dns_asus_rm() {
    # txt record is auto-removed by asus on next ddns update
    return 0
}

You should then be able to get a certificate using dns_asus for the dns option, for example
Code:
acme --issue --dns dns_asus -d test.asuscomm.com

EDIT: Without the myip query in the url, the IP address isn't updated, so I've removed the nslookup and used 0.0.0.0 for the password.
EDITEDIT: Actually it just auto detects your IP address.
 
Last edited:
Ok, I think I have a solution for *.asuscomm.com certificates. Add the following script to /opt/share/acme/dnsapi, or wherever you've set it to install to
Code:
#!/bin/sh

dns_asus_add() {
    HOSTNAME="${1#_acme-challenge.}"
    TXTDATA="$2"

    # Reuse the currently set IP
    IP="$(nslookup "$1" 'ns1.asuscomm.com' | awk 'NR>2&&/^Address/{print $(NF==2?2:3);exit}')"

    # Router MAC address location is hardware dependent
    for LAN_MAC_NAME in et0macaddr et1macaddr et2macaddr; do
        MAC_ADDR="$(nvram get "$LAN_MAC_NAME")"
        if [ -n "$MAC_ADDR" ] && [ "$MAC_ADDR" != '00:00:00:00:00:00' ]; then break; fi
    done

    # Use openssl to generate the password
    PASSWORD="$(printf '%s' "${MAC_ADDR//:/}${IP//./}" | openssl md5 -hmac "$(nvram get secret_code)" 2>/dev/null | awk '{print toupper($2)}')"

    HTTP_RESULT="$(curl -fs -w '%{http_code}' -o /dev/null -u "${MAC_ADDR//:/}:$PASSWORD" "http://nwsrv-ns1.asus.com/ddns/update.jsp?hostname=$HOSTNAME&acme_challenge=1&txtdata=$TXTDATA&myip=$IP")"
    case "$HTTP_RESULT" in
        200|220|230) return 0;;
    esac
    return 1
}

dns_asus_rm() {
    # txt record is auto-removed by asus
    return 0
}

You should then be able to get a certificate using dns_asus for the dns option, for example
Code:
acme --issue --dns dns_asus -d test.asuscomm.com

Unfortunately this is Chinese to me
 
What do I miss? In my RT-AC68U it says I have a new an nice cert but when I check it then the old one is used. How to fix this?
 
Last edited:

Similar threads

Latest threads

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top