Let's encrypt renew doesn't work on our Mikrotiks

Hello,

we are using Mikrotik v7.15 and the following script to auto generate new Let's Encrypt certificate:

:local dnsName
#Use d for days or w for weeks at the end of variable value
:local Daysbefore 30d 

# Uncomment the line below if you have a public DNS hostname configured
:local dnsName sstp1.czt.si

:if ( [:len $dnsName] = 0 ) do={ 

     # Check IP Cloud #
     :if ( ![/ip cloud/ get ddns-enabled] ) do={
          :log error "[Letsencrypt_OSScript] - IP Cloud not enable - Waiting... "
          /ip cloud set ddns-enabled=yes update-time=yes
          /ip cloud force-update

     }
     :log info "CloudIP"
     :local dnsName [:put [/ip cloud get dns-name]]

}

:do { :local cert [/certificate get [find common-name=$dnsName]] } on-error={ :local cert "" }

:if ( [:len $cert] = 0 || [get $cert expires-after] <  $Daysbefore ||  [get $cert expired] )  do={
      /ip firewall/filter/add chain=input dst-port=80 protocol=tcp action=accept place-before=0 comment="LetsEncrypt_OSScript"
      /ip service enable [find port=80]
     # Get LetsEncrypt certificate #
     :if ( [/certificate enable-ssl-certificate dns-name=$dnsName] = 0 ) do={
          :log info "[Letsencrypt_OSScript] - Certificate Updated"
     } else={
          :log error "[Letsencrypt_OSScript] - Error in certificate generation - Try to open port in firewall and enable service"
          :delay 5000ms;
          /ip firewall/filter/add chain=input dst-port=80 protocol=tcp action=accept place-before=0 comment="LetsEncrypt_OSScript"
          /ip service enable [find port=80]
          :if ( [/certificate enable-ssl-certificate dns-name=$dnsName] = 0 ) do={
              :delay 90s

              /certificate
              :local certName [get [find where common-name=$dnsName] name]

              #Set new certificate in SSTP Profile
              /interface sstp-server server
              set certificate=$certName
              :log info "[Letsencrypt_OSScript] - Certificate Updated - Close doors"
          } else={
              :log error "[Letsencrypt_OSScript] - Unable to generate certification - Close doors"
          }
     }
     # Remove custom firewall roule and disable services #
     /ip firewall/filter/remove [find comment="LetsEncrypt_OSScript"]
     /ip service disable [find port=80];

} else={
        :log info "[Letsencrypt_OSScript] - Nothing to do!"
}

The problem is that the script stopped working, here is the error:
progress: [error] too many certificates (5) already issued for this exact set
of domains in the last 168h0m0s, retry after 2025-02-15 11:36:56
UTC: see Rate Limits - Let's Encrypt
per-exact-set-of-hostnames, type:
urn:ietf:params:acme:error:rateLimited, code: 429

Not sure why the script is not working and why we are exceeding the limit of issued certificates, because we run this script only once a day.

Can you please help me with this?

Thank you!

The script is obviously working just fine to issue certs. What it isn't doing correctly is determining that it already has a cert, so instead it's requesting another one. I doubt anyone here can debug your script, but perhaps someone else knows the syntax of whatever scripting language you're using.

3 Likes

I agree with @danb35 that your script is not properly checking for a valid existing cert.

The above line is possibly the reason. You could add some code to that script to find out why this has you getting a cert every day. It looks like it should work but must not be.

The Mikrotik forum or their support is a better place for advice on that.

2 Likes
:local Daysbefore 80d
:local dnsName example.com

:put("common-name: " . $dnsName)

:local cert [/certificate find where common-name=$dnsName]

:if ( [:len $cert] = 0 || [/certificate get $cert expires-after] <  $Daysbefore ||  [/certificate get $cert expired] )  do={
    :put ("Certificate Expiry: " . [:tostr [/certificate get $cert expires-after]])
} else={
    :put ("sdf")
}

this one is work well..