8/18/2025
MikroTik + Let's Encrypt — automatic SSL on a router
TL;DR: MikroTik RouterOS 7.x supports Let’s Encrypt through built-in certificate management. Certificate is issued and renewed automatically. HTTPS on the admin panel without any external server.
Accessing the MikroTik panel over HTTP is a security problem — the admin password travels over the network in plaintext. A self-signed certificate causes browser warnings and doesn’t build trust. RouterOS 7.x solves this elegantly: the built-in ACME client issues and renews a Let’s Encrypt certificate without any external scripts.
Requirements
Before you start: you need a public IP address assigned to the router (static or dynamic with current DNS), a domain pointing to that IP (e.g. router.yourcompany.com), and port 80 open from the internet. Let’s Encrypt HTTP-01 challenge requires accessibility via port 80 — this is temporary, only during certificate issuance.
Key requirement: RouterOS 7.x. Version 6 doesn’t support the built-in ACME client. Check your version: /system resource print → version field.
Configuration via Winbox/CLI
Via the RouterOS terminal (SSH or Winbox Terminal):
# Issue certificate
/certificate enable-ssl-certificate domain-name=router.yourcompany.com
# Wait for completion — may take 1-2 minutes
# Check status
/certificate print
After successful issuance, the certificate will appear in the list with the name router.yourcompany.com_certificate. Then assign it to the www-ssl service:
/ip service set www-ssl certificate=router.yourcompany.com_certificate
/ip service set www-ssl disabled=no
/ip service set www disabled=yes
The last line disables unencrypted HTTP — if you prefer to keep HTTP as a fallback, leave it enabled, but think twice about it.
Renewal script
Let’s Encrypt certificates are valid for 90 days. RouterOS Scheduler lets you automate renewal:
/system scheduler add \
name="renew-ssl-cert" \
interval=30d \
on-event="/certificate enable-ssl-certificate domain-name=router.yourcompany.com"
The scheduler runs every 30 days — giving a 60-day buffer before expiration. If renewal fails (e.g. port 80 is temporarily blocked), you have two more attempts before the certificate expires.
Optionally, you can add renewal status logging:
/system scheduler add \
name="renew-ssl-cert" \
interval=30d \
on-event=":local result [/certificate enable-ssl-certificate domain-name=router.yourcompany.com]; :log info (\"SSL renewal: \" . \$result)"
Verification
From an external device (or via VPN outside the LAN):
curl -I https://router.yourcompany.com
# Expected result: HTTP/2 200 and no certificate warning
Checking the expiry date from within RouterOS:
/certificate print detail where name=router.yourcompany.com_certificate
In the invalid-after field you’ll see the expiry date — it should be ~90 days from the last issuance.
The hairpin NAT problem
This is a classic trap for home networks and small offices. Let’s Encrypt during HTTP-01 challenge sends a request to your public IP. If the router tries to verify its own domain from the LAN, the request goes to the public IP, which is the router’s own address — and a routing loop begins.
Workaround: temporarily disable hairpin NAT (masquerade rule for traffic src=LAN dst=public-IP) during the first certificate issuance. The easiest approach is to do this at night when no one is using the network. Scheduled renewals via the scheduler don’t have this problem if the certificate is issued via a request going from the router outbound to the ACME server (not through the LAN).
Alternatively: use DNS-01 challenge instead of HTTP-01 — requires your DNS provider’s API and is more complex to configure, but doesn’t require port 80 to be open.
Summary
RouterOS 7.x ACME integration is one of those features that works exactly as it should — one command, certificate issued, scheduler renews. For anyone managing a MikroTik remotely over the public internet, HTTPS with Let’s Encrypt is a mandatory security step. The only pitfall is hairpin NAT during first issuance — plan for it in advance.