LetsEncrypt, uhttpd, admin access from outside, security

I had an issue, almost certainly due to some mistake I made, but it brought up something on which I would like a better understanding.

I am using Neil Pang's routine described here: https://github.com/Neilpang/acme.sh/wiki/How-to-run-on-OpenWRT

It works.

My understanding (in case I am wrong) is that this process:

  • Uses the package uHTTPd with open ports 80 and 443 on all interfaces, including outside

  • Depends on iptables to close those ports on the outside except during renewal.

I'm particularly a bit confused by step 5 of his procedure, which seems to use the GUI to open the ports in the underlying config, which seems to have them open all the time?

I was also embarrassed that having done this, it implicitly allowed admin access to my guest network, and I missed it. Fortunately I have had well behaved guests so far.

Now I think, maybe, hopefully I have caught these and closed them appropriately but my questions relate to doing this better:

First, do I understand properly? That uHTTPd has to be listening on the outside interface (and more precisely for this script to work, doing so all the time then blocked by iptables except during the actual renewal)?

WIth a DHCP outside address, how can I avoid listening on my guest interface? My only thought is to, again, use iptables to block it. Unless there's a way to listen on an interface name, not address in the uHTTPd config file (vs gui)? The doc doesn't show that as possible.

I'm particularly confused how the GUI Firewall setup (mentioned in step 5 of the procedure) should be done, and how that relates to the explicit iptables rules. What should I have done in step 5? Doesn't opening 80/443 in that step open it all the time? It almost seems like I should NOT open it there, but let the script open it momentarily itself? What is meant by step 5 there?

Hopefully it goes without saying that I do not want the outside interface to ever show a login dialog, ideally, but at least at no time other than the brief window during renewal. I feel like now I have it working, but not in a robust way -- any error in the script might leave it open?

Is there a more secure way, to block admin access entirely via the outside interface not just by port (sometimes)?

I don’t know about the script, but basically you could add a rule to allow 80 TCP while getting the cert, then remove it.

1 Like
1 Like

This exactly what I do, the rule sits there with the "enable" tick box cleared most of the time, only being enabled when I need to renew the cert(s).

No need, because /etc/init.d/acme invokes /usr/lib/acme/run-acme which automatically manages the firewall rules.

1 Like

@vgaetera, so that's a package you install, as opposed to what I had done which is follow the wiki I posted in the first note.

I take it I should be using the installable package instead of Neil Pang's guidance? I can't find any documentation on the installable.

I installed the acme and luci components didn't see a GUI, rebooted and the GUI appears (mentioning this in case anyone else runs across it). But there's other stuff I do not understand. For example, I wasn't planning to use the DNS API (since my DNS is at Google Domains, which I think is different than gcloud) but I could not save my config without entering a DNS API name, and indeed in the log it pops up "using dns mode" which I don't want. Trying to work through the logs to see what happened, but I'm concerned I am not starting off correctly by lying to it and putting in the gcloud entry.

Is the documentation for the luci gui anywhere? I know where to find acme generic documentation, talking about how to set it up properly on openwrt.

No idea about the documentation, but we have the source code.
It looks like the DNS mode is not exclusive:

Technically, you can combine the two and use the package just to get the script on your router, and then just replace the script path in Neil's instructions to /usr/lib/acme/acme.sh.

*** See following note this one isn't right ***

So I removed the script I had been using, and removed uHTTPd and reinstalled luci so I would get the default configuration, then tried the acme script.

It worked fine (after I edited the config file directly rather than through the interface to remove the dns api name).

Except that I had to put in firewall rules to allow ports 80 (and maybe 443). Without it, the script gets a timeout failure on validation.

And with the port 80 present, the luci interface login will come up on the external interface.

So I don't see that the script is handling the firewall rules. I will look at the code itself a bit later (off on real work for right now).

That's why I was asking about documentation - maybe I'm missing something in terms of the initial setup at might not expose this vulnerability.

So I stand corrected, though I am not at all sure why.

I started looking through the code, and see the area where it resets iptables. So I switched back to staging and decided to try again. First problem is I could not figure out where to put -force in, but I ended up just removing the /etc/acme folders with the valid runs to force a run.

And it worked. Without the port 80 rule.

But... It didn't work before. I have lots of attempts in the log where it failed with a timeout (consistent with the port being blocked).

I have no idea why it didn't work initially. Maybe it needed a reboot (though I had done several). But it does now seem that the routine works great with the ports left blocked normally, and it opens it during the run.

I do think the GUI is wrong in not allowing it to save without a dns api name.

Another puzzle is a lot of the debug output doesn't appear in the log even if debug is set to "1" in the config file. I feel like I'm missing something, like a different way to do configs or where the logs from debug should go (is it just the online log visible in the gui)?

But... at least eventually -- it works nicely to handle the open/close of the port(s).

1 Like

You're absolutely right. I was conflating updating may OpenWrt certs and the ones on servers on my LAN, which need port 80 opened for them.

1 Like