MikroTik WebFig Not Working With SSL/TLS enabled

Hello,
I have an issue where webfig won’t work with SSL/TLS enabled. Firefox returns the following error when trying to connect:

Chrome returns a “ERR_CONNECTION_RESET”
We can see in a capture that the connection is not firewalled, the 3-way handshake completes and the client sends a TLS HELLO to the server, but the server responds with a RESET and the connection is terminated before the TLS/SSL handshake can finish:

Webfig is enabled, and a valid LetsEncrypt Certificate is applied

Any ideas as to why the server is closing the connection? This is RouterOS 7.1.1 on a CRS125-24G-1S

You need certificate with private key.

Sob,
Thanks for the reply, it was indeed silly of me to forget to import the private key. I was very optimistic this was the only issue, but alas, it still does not work.

Now it no longer resets the connection instantly, instead it just times out and never replies to the clients HELLO:

Any other thoughts?

I’d try something that shows a bit more info, for example openssl is commonly available:

openssl s_client -connect hostname.domain.tld:443

Or https://testssl.sh/ is good. But looking at those captured packets, server seems too passive, I don’t know why it would do that.

openssl s_client -connect hostname.domain.tld:443

This says “CONNECTED” then hangs forever, it’s not really surprising since the server never sends a SERVER HELLO in response to the client. Interestingly, a few minutes later (after the connect attempt) the router will crash and reboot. This cycle can be repeated. Disabling the webfig-ssl service prevents the crashing.

For now I have given up and left it disabled. I might try to delete all the certs, files, get the cert re-issued and try the whole thing from scratch once more, but other then that i’m stumped. To troubleshoot further I think i’d need a root shell.

Apart from desperate variations of “turn it off and on again”, so literally that (but crash and reboot already took care of that), reimporting certificates, reconfiguring www-ssl, … you can try to upgrade, there’s already 7.1.3 and I can confirm that it works there for me.

Sob,
I did try an upgrade to 7.1.3 and it didn’t help, but ultimately with some more time I did figure this one out.

The LetsEncrypt intermediate cert cn=R3 and the CA cn=ISRG Root X1 both reference CRLs, these are respectively:

http://x1.c.lencr.org/
http://crl.identrust.com/DSTROOTCAX3CRL.crl

By default I had “Use CRL” and “CRL Download” unchecked in the settings. Personally I think it is a bug that with “Use CRL” unchecked the CRL still seems to matter. But I did notice that, after checking both of those options one of the 2 CRLs continued to show as invalid - the 2nd one. The logs indicated that it was invalid because the router could not verify the signature and that it was signed by the expired DST Root CA X3. Since this certificate expired back in September 2021 LetsEncrypt no longer hands it out as part of the certificate chain and it has since been removed from their websites. After some googling I was able to find a copy of the expired cert, I imported it and the 2nd CRL was marked as valid, after that it worked. So now the certificates are as follows including the expired old CA:

So again i’m not really sure who’s issue this is, LetsEncrypt for having a CRL signed with an expired CA but referenced in their current CA or MikroTiks for the “Use CRL” option doing seemingly nothing at all. But it seems at the end of the day because of that CRL you need the old expired CA on the router for it to work.

This definitely doesn’t sound right.

Certificates are tricky. AFAIK LE made bit of a mess, because in order to support old Android devices that don’t have their new root CA, they kept sending the expired intermediate certificate. It’s possible that they still do it, I’m not sure. The protocol supports multiple certificate paths and client can choose from them. But default one was with this expired certificate, for backward compatibility I assume. And then it gets somehow messed up, because even if some certificates are different (signed by different CAs), they may actually have same key, so certificate signed by one can be verified by other, also servers should (but not always do) send intermediate certificates, and clients may or may not use intermediate certificates they have from before to verify end certificate, so it all gets mixed up and it works for some and doesn’t for others. I got lost in it myself. But if you don’t need to support prehistoric clients, you shouldn’t need the expired certificate at all. But I can’t tell you what exactly needs to be done for that.

I’ve been using getssl as the ACME client (https://github.com/srvrco/getssl) it may have an option to choose the newer path which does not include anything to do with the expired CA that I just never bothered with. I will look into it later on today. That could be another way to resolve this issue.

delete all certificates,
import only your certificate (and do not name it letsencrypt, but use your dns name, for example)
two time for import also the private key
and import only Let’s Encrypt R3
67add1166b020ae61b8f5fc96813c04c2aa589960796865572a3c7e737613dfd
after that rename it (for be clear what is) Let’s Encrypt R3
on general tab of the Let’s Encrypt R3 select “trusted” if already is not checked
on settings CRL download and use CRL are useless and leave it disabled (until you do not use your router to generate [invalid for the others] certificates)
NOT import isg root or other certificates
only now go to www-ssl and select your certificate

If you use elliptic certificate instead of “classic” RSA, you can go on trouble with some (non-routeros) devices.

You can use this:
https://www.ssllabs.com/ssltest/
for test if is all installed correctly

I think Mikrotik had expired intermediate certificates for Let’s Encrypt in some of the 7.1rc’s, but maybe never in 7.1.x line. So maybe upgrading to 7.2rc4 would get you need missing certs?

(edit: OP did try 7.1.3)

Sorry I missed this part…

But in V7, you can generate the certificate on the Mikrotik itself using

/certificate/enable-ssl-certificate

which will use a DNS name from IP Cloud, but you can add a “dns-name=” to specify the DNS name you want.

It’s true that v7 can get LE certificates, but so far I’m not impressed by it, it seems to be more manual thing than the usual “set it & forget it” you’d expect from LE. Last time I tried, intermediate certificate had to be imported manually, LE client didn’t add it. Having to keep http port open all the time for automatic renewals is not ideal either. Although renewals may be missing something too. Coincidently, the certificate I got while testing it expires tomorrow, so I’ll see what happens then. But I’d expect renewal to happen much earlier. You can probably run the whole thing from scheduler and handle everything yourself, including access to http port, but it’s far from great.

Unless you’re going to access WebFig via a public DNS name resolving to a public Internet IP, I’m not seeing what Let’s Encrypt buys over the existing on-device certificate generation.

The solution to the problem of self-signed certificates not being accepted by TLS clients is easy to solve: import the MT box’s root CA public key into your OS’s key store as trusted, so anything it signs is no longer “self-signed” by this logic. On Windows and macOS, you merely have to double-click the key file after downloading it and follow a few simple steps to do this. From then on, you can use HTTPS only and be happy.

I don’t care about WebFig myself. It’s just for admins, so most likely only few people, and they can handle importing custom CA. And unlike with LE, there’s no moving part that could break. I wouldn’t use CA in RouterOS, because it’s tied to one device and it’s problematic to move it elsewhere is needed. In fact, I wouldn’t use publicly accessible WebFig, even with https, but it could be good enough with some IP filter.

Publicly trusted certificate is useful for SSTP. Even non-technical users can manage to run one or two PowerShell commands to configure VPN client, but importing certificates is too much for some.

@Sob is right Mikrotik’s LE has some flaws. More just suggesting it still might be easier than using ACME on another box and transferring files.

How easy depends on how many clients and what kinda of clients you have.

For stuff like the REST API, LE support has been handy. Although it’s annoying that’s actually not that automatic… you have to either leave port 80 open, or script renew in a schedule that opens port 80 only during validation. Still easier and safer than modifying the trust store of each device (which depending on your admin level, may not even be possible to do). YMMV.

I believe they will eventually get there and make it good. Only with all the other stuff they have to solve, it may take a while.

Hi All,
Thanks for all the great suggestions and conversation in this topic, I have not had a chance to try all the suggestions made here, but I plan to try a few more variations like the one @rextended suggested. With regards to my specific implementation I also wasn’t impressed with the support for LE added thus far, it seemed simpler just to use a ACME client a I was already using and push the certs, then a script via the API or even just the CLI to install them. I leave webfig on TCP/443 open but firewalled to a few IP addresses/subnets I may need to administer the router from. The port 80 webfig is explicitly disabled and TCP/80 on the router is forwarded to a sandbox on a machine behind the router which takes care of the authentication token and nothing else. I was originally going to use dyndns to do the token instead, but the port forward seemed simpler to implement in my mind.

Really what was surprising here was how difficult it was, even after the certs were on there to do something that would typically be quite simple with something like Nginx or Apache. Once you have the certs just copy the cert/key and intermediate if required to the correct file and reload..all done. I expected it to “just work” on the Mikrotik and it sure didn’t. At the very least hopefully someone at Mikrotik will see this thread and revist how LE certs work on these devices.

Old thread but this has helped me solve the problem.

It seems like a Mikrotik/RouterOS issue for not being able to trust the Let’s Encrypts new CA ISRG Root X1. I was having issues with not able to access Mikrotik’s webfig from behind a NGINX reverse proxy neither through the router’s gateway ip address nor domain name, from both private and public networks. I had other services with different domain names hosted in my private network that were accessible from everywhere.

Please see https://letsencrypt.org/docs/dst-root-ca-x3-expiration-september-2021/

After importing old CA DST Root CA X3 from https://ssl-tools.net/subjects/6ff4684d4312d24862819cc02b3d472c1d8a2fa6 solved the problem. Finally I can access the router admin console using SSL.

BTW I’m on latest software 7.13.3

Some settings to note

  • Rewrite DNS - point the domains to the correct local ip addresses in Adguard (or whatever DNS server in use)
  • Port forward 80 and 443 to NGINX proxy on the WAN interface
  • Have hairpin NAT rule. I added x.x.x.x/24 to x.x.x.x/24 for all ports
  • Generated Let’s Encrypts certificates through NGINX. Then exported and imported into Router OS as well as DST Root CA X3