Certificates for hosts on private networks

Note: I edited the thread title to reflect more clearly what the thread is about.


Yea that’s looks like it will work for home users on the internet.

Unfortunately my software is also used in a bunch of museums and installations. In that case there is no internet. Users connect to the WiFi, using fake DNS and Captive Portal support they either wait for the captive portal stuff to kick in and get automatically connected to the installation (iOS) OR they type any domain name like h.com and get redirected to the installation (android/winphone).

As there’s no connection to the internet I’m curious if there is a possible solution. It seems like if the browser is going to check certificates and doesn’t need to go online to do it I can include a “private” certificate directly in the app, of course that means anyone can steal it and use it for whatever they want and eventually it will probably get banned/deauthorized etc… not even sure that will work.

Actually could Let’s Encrypt help with the second path I mentioned above.

That second path is as follows

My native app (OSX/Win/Linux) is also used in a bunch of museums and installations. In that case there is no internet. Users connect to the WiFi, using fake DNS and Captive Portal support they either wait for the captive portal stuff to kick in and get automatically connected to the installation (iOS) OR they type any domain name like h.com and get redirected to the installation (android/winphone).

As there’s no connection to the internet I’m curious if there is a possible solution.

Basically instead of me having to provide a certificate museums can get a free one from Let’s Encrypt and install it locally in the app. Maybe they can register it to a domain like “someinstallation001.museumname.myapp.com”. I can then make the app (which is faking DNS) redirect all users to someinstallation001.museumname.myapp.com which is still just the same server but as it would be providing the correct certificate would that work completely disconncted from the internet?

Would that work?

If you can get the museums to make a change to the browser configuration you can issue certs without the involvement of an external CA: you can make your own CA for your application (perhaps just by using a few openssl command line commands, among other possibilities) and then ask the museums to add the CA’s root certificate to the kiosk browsers. Then the browsers will accept the certs that you issue, without needing to involve any outside party.

If you don’t want the museums to have to make a configuration change in their browsers, you could get the certificate from Let’s Encrypt for the name under myapp.com, as you describe, and then deploy it in the museum. The one difficulty about the redirection is that the browsers will need to make an initial HTTP (not HTTPS) connection to the captive portal in order to get redirected to the site. That is probably not a problem. It does mean that the level of security you would get against an attacker who gets onto the network is lower, because the attacker might be able to intercept the initial connection and redirect to the attacker’s machine instead of to your server.

I think the internal CA is probably more appropriate for your application overall, and many organizations do something like that pretty successfully. Then you don’t have to rely on Let’s Encrypt’s policies, mechanisms, or technology, and you can even use the names of your choice (not only names under myapp.com).

No, this won’t work and completely defeats the purpose of any HTTPS connection. Private certs are named private because they are private!
But I think I know what you’re thinking of. You can put the public cert (or a hash of it) into an app you developed yourself and do the validation manually. If this app is the (only) one which connects to the servers.
More information here:

However if the users use a browser then @schoen’s suggestion would be better (and the only possible).

I seem to keep failing to make it clear how my stuff works. The parts are

  1. A web server. I keep calling this an app because it installs on PC/OSX/Linux.

  2. User’s smartphone browser (Safari / Chrome)

  3. A WiFi router

No internet is used. No apps on the phones. It all works now. Users are going to museums and are able to interact with the exhibits.

Google is threatening to ruin that experience by requiring HTTPS in Chrome

Users walk into the museum, whip out their phones and are connected to the installation. Users are not going to install certificates on their phones. Museums aren’t using browsers. Museums are serving web pages to users’ phone browsers. Those phone browsers are connected to the museum’s wifi. That wifi has no internet access. It only accesses the museum’s web server running my software.

In this situation I would recommend you use a public domain you control. For this example, I’ll refer to a single installation for the fictional MOAA, Museum of Awesome Art: moaa.yourdomain.tld

  1. Set up a simple webserver on the public Internet at moaa.yourdomain.tld
  2. Use the Let’s Encrypt client to obtain a certificate for moaa.yourdomain.tld
  3. Move the certificate and the public key to the private server on the MOAA LAN
    1. You can also use a higher security method we can discuss later with more steps
  4. Configure your capture portal to use moaa.yourdomain.tld as the internal address
    1. Your capture portal already acts as an authoritative DNS server, so this should be an available option, otherwise you can use unbound or dnsmasq
  5. Users connecting to your network get redirected to https://moaa.yourdomain.tld/ which serves a certificate for moaa.yourdomain.tld that is trusted by the users’ mobile devices

This sounds like it will work as long as the user’s phone’s browser doesn’t need internet access to verify the certificate/s.

No it does not.
Unless it checks for some revocation information, but I think this is not done or if it does most browsers still allows the connection although the check failed. (which is - principally said - bad of course)

There are some configurations in which either browsers or servers would want Internet access to confirm in some way that the cert hasn’t been revoked. However, it’s not yet common for this to be mandatory when accepting a cert, so the method that @jcjones proposes should currently work fine for this situation. I agree that that method (the moaa.yourdomain.tld idea) should work well and is more appropriate with user-controlled devices than any other. The idea is that the museum’s server “really is” moaa.yourdomain.tld, whereas with other approaches there’s no way to get random visitors’ own devices to agree that the server “really is” the indicated name.

I think the “higher security method” that @jcjones refers to is using a proxy to complete the validation; in that case the certificate and private key only ever exist on the museum’s server and are never stored elsewhere (and needn’t necessarily be possessed by the person who created the web app, if that seems preferable). I don’t think there’s direct support for this in the current version of the Let’s Encrypt client, but it could be implemented in the future. There’s also manual mode, which can be used with a different server completing the verification than the server that possesses the private key.

The one thing to think about when using any form of this suggestion is that the cert eventually expires (probably after 90 days in the initial Let’s Encrypt configuration) and the museum server does need some way to get the renewed cert, which means somebody has to be able to install new data on it. It doesn’t necessarily need full “Internet access” but it needs some way for someone to momentarily give it some updated information, in the form of the renewed cert.

1 Like


I’ll try it out as soon as I get get Let’s Encrypt to issue me a cert. I’ll make it so the museum can easily add their own cert for <somemuseum>.myapp.com and cross my fingers I can get it all to work.

1 Like

@greggman I think the solution @jcjones provided is the best for your needs. However, if you are running this app in more than a couple of museums, it might be very time consuming and labor intensive for you to issue, distribute and and renew different certs for each location.
From what I understand, the reason you’re looking for a cert is not necessarily to protect highly secret data but rather to avoid browser warnings.
In this case, I suggest you create one wildcard cert (like *.yourapp.tld) and use the same cert in all installations. This way each location will still have their own URL like moaa.yourapp.tld, but you’d need to manage and renew only one cert for all locations rather than many different certs.
Just my 2c…

I would just purchase a single *.yourapp.tld certificate and follow @jcjones solution. I say purchase, because a 1-3yr certificate from a different commercial provider will mean no intervention is require to manually update certificates every 90 days!


That suggestion seems sensible to me, but bear in mind that it would require putting the private key on every machine, which would then allow one museum to impersonate another museum.


19 posts were split to a new topic: Certificates for many user-controlled subdomains

This thread has some high Google juice, so here are some instructions on how to get certificates for private IP’s on letsencrypt.

Requirements: a domain name (example.com), access to the DNS server for example.com, root access on a publicly accessible server (server.example.com). And let’s assume you want to create a certificate for named foo.example.com

  1. install certsling on the server.
  2. Add an A record to point foo(.example.com) to
  3. Add an NS record to point _acme-challenge.foo(.example.com) to server.example.com
  4. sudo socat -T15 udp4-recvfrom:53,reuseaddr,fork tcp:localhost:8053 on your server
  5. open port 53 on your server firewall
  6. mkdir myemail@example.com
  7. cd myemail@example.com
  8. certsling -s --dns foo.example.com to get certs from the letsencrypt staging server
  9. When step 8 works, rm -rf *
  10. certsling --dns foo.example.com to get real certs

Your certs will be in "myemail@example.com/foo.example.com/"!

1 Like

Thanks for raising this question really help me out with solution

which top level domains would this support? Would it work with foo.example.local?

LE only provide certs for valid TLDs.
Basically: If you control the domain, and it can be validated from Internet DNS, then you can get a cert for it.[barring restrictions]