Certificates for hosts on private networks

It might be possible to use a proxy to complete the verification step using a temporarily-publicly-resolvable version of the DNS name that’s later changed to point to a private LAN IP address.

A security problem is that since these names don’t have an inherent independent meaning for the users, it’s not really clear what their browsers are “verifying” when they verify the certificate. Effectively, they’re always trusting the app developer not to MITM them; in some configurations they might also be trusting other users of the service not to do so, too (because the user doesn’t necessarily have a useful way to distinguish between “my instance” and “my neighbor’s instance”).

I think Let’s Encrypt might be able to issue certificates that would work out for this use case, subject to these limitations, if you can proxy the verification step with a public IP address and then update the DNS records afterward.

If it’s your own app then you can (and it would not be a bad idea) add public key pinning to it, so that it only accepts this one certificate.
However - of course - in this case you don’t need to let it sign by a CA at all, you can just use a self-generated certificate.

1 Like

That doesn’t mitigate the ssl warnings you will get from not being signed by a CA

That doesn’t mitigate the ssl warnings you will get from not being signed by a CA

Of course it does. If it’s your own app where you can implement your own HTTPS validation you can of course skip the CA validation and use key pinning (which is much more secure).
At least on Android many apps do the first step - accidentally -, but doesn’t do the second step, so their HTTPS validation is effectively broken.

If it’s not your own app (like the browser) then that’s of course another case, because there you the HTTPS connection is of course CA-validated.

I’m sorry but you are mistaken, by key pinning I assume you mean HPKP?
The purpose of HTTP Public Key Pinning is not to replace the CA system, it is to ensure that after connecting securely once, that any further connections are forced to accept only that legitimate CA signed certificate (with optional backups in case of compromise), even if a different malicious CA signed certificate for the same server is presented to the client.

If you really must use your own self signed certificate, the only way to avoid the SSL warnings you will get on the clients, is to install your custom certificates/certificate chain into each client’s trust store.

I’m sorry but you are mistaken, by key pinning I assume you mean HPKP?

No. :smile:
If I meant this I would have written HPKP. Because HPKP is HTTP Public Key Pinning. Note the HTTP - that indicates that it’s a HTTP header (at least in this case).

So no what I meant is ‘normal’ key pinning: You grab the public key of your cert, put it into your app and allow only HTTPS connections which use this cert. As you control the app and it’s hardcoded public key it’s not possible to use another cert (at least if the implementation has no flaws, of course) and you can skip the CA-check for that cert as it’s neither necessary nor useful in this case.
But as I said this of course only works if you develop an app, which only connects to your own server.

@rugk Well you can excuse me, because as I quote below, the question at hand relates to HTTP and HTTPS, and CERTIFICATES, as in WEBPAGEs sent to a BROWSER, so forgive me for thinking you were talking about HPKP, you are in fact talking about something totally different than the topic at hand.

Not sure what makes you think that HPKP is not ‘normal’ key pinning. Please link me to info on the key pinning you speak of. When you said earlier:

I assumed you meant @greggman 's app that he runs himself on a server. That clients connect to on a web browser.

Ah, no I meant a mobile app. Sorry for the confusion.
Well… HPKP is a kind of kind pinning - I just wanted to show the difference between the app key pinning* and HPKP.
Here are more information:

And yes, you’re right he mentioned that the users use a browser. In this case that’s of course not possible.
My reply should just be a note about the general problem for others. (not especially for him) That’s why I said ‘If it’s your own app’ but it seems this was misinterpreted (because of the ‘native app’ part in the first post, which mean another kind of app). So I meant an mobile app you develop yourself.

* this is not an official name

Take a look at this: https://blog.filippo.io/how-plex-is-doing-https-for-all-its-users/

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