Certificates for hosts on private networks

Someone suggested that I run a DNS server and generate domains on the fly as in somesessionid.myapp.com where somesessionid.myapp.com points to the user’s localhost ip address. If I have a cert for myapp.com then maybe that would work?

Yes this should work AFAIK as you can get certs for domains.

It will work, but it will require that the service be accessible remotely in order to perform the validation. It would not be able to point to the localhost IP.

If Let’s Encrypt implements DNS based validation that would be a way to more easily implement this without requiring external connectivity, but I don’t know if they will be implementing that part of the ACME spec.

1 Like

They will allow DNS based verification:

The Let’s Encrypt CA will look at the domain name being requested and
issue one or more sets of challenges. These are different ways that
the agent can prove control of the domain. For example, the CA might
give the agent a choice of either:

Provisioning a DNS record under example.com, or
Provisioning an HTTP resource under a well-known URI on https://example.com/

https://letsencrypt.org/howitworks/technology/

@rugk: We should probably clarify the language on that page. It’s intended to list DNS provisioning as an example of what a CA “might” do. The current status is that we will launch with only the SimpleHTTP and DVSNI challenges, and most likely support DNS challenges later on.

@greggman: The problem you pose, of issuing meaningful certs for hosts on a local network, is a very hard one that is being thought about a lot, but no one has come up with a satisfactory solution. You are on the right path for one workaround, though. You can indeed set up hostnames like somesessionid.myapp.com and get certificates for them. There are a few tricky things, though:

  • A certificate for myapp.com won’t be valid for somesessionid.myapp.com. You’ll need to get a certificate issued for somesessionid.myapp.com. Also, in order to be secure, your app running on the local network should generate its own private key, and share the public key with your service to get it signed by a CA.

  • In order to be signed by a CA, somesessionid.myapp.com needs to resolve to a server accessible on the public Internet. But in order to be used by the local network app, somesessionid.myapp.com needs to resolve to a local address. You can probably work around this by making somesessionid.myapp.com temporarily point to a public web server for enrollment, and then re-point it to the local address during use. Keep in mind that certs will need periodic renewal, so you will have to account for that somehow.

1 Like

Maybe you can do something like this:

First time use of app, serves an unencrypted welcome portal, Little message about accepting what ever comes next.
After accepting, then have the app always serve encrypted.

Could even get a little creative with icons, like choose your browser, which give visuals on how to permanently accept, depending on if chrome, safari, dolphin etc. I know it would be a pain at first, but it shouldn’t be to hard to get. What do you think?
–…Archer

I think you under estimate how scary and convoluted it is to “click through” on Android and I don’t think most soccer moms are not going to click through after reading how it’s unsafe

see img

1 Like

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.

Thanks!

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).