I'm not really sure about the category. I'm asking this question based on the discussion I started on serverfault ( security - SSL for devices in local network - Server Fault). I'm looking for a way to make devices accessible in a local network for non-technical people without the all the red flags a browser gives about untrusted certificates.
In my topic on serverfault I had proposed the following hypothetical solution:
Request an intermediate CA certificate from a trusted root CA which has Name Constraints which only allows it to create multiple intermediate CA's which can only create certificates for a single fixed hostname '*.mydevice.local' or something similar and which allows all private IPv4 addresses to be used in the SAN.
Every deployed device would be factory installed with a unique intermediate CA created by the intermediate CA I was talking about in step 1. This on-device CA would than be name constrained on '.mydevice.local'.
Every time that the device changes IP-address (boot, DHCP change, ...) it would than be able to generate a certificate with it's on-device intermediate CA.
I think this would solve the problem completely and have the following advantages:
No browser warnings because the chain of trust relays back to the trusted root CA.
Every device would have a unique certificate.
Compromise of a single intermediate CA would not be that big of an issue because it can only be used to create trusted certificate's for the device's specific fixed hostname.
Would this be safe if allowed by for example let's encrypt?
Hello @griffin, thank you for your prompt reply. I was not aware of the CAB rules but I already had a feeling this would be hard to accomplish.
At the moment we are deploying most of the devices with optional HTTPS because most non-technical customers are spooked with all the red flags a browser gives when browsing to a local device without a trusted certificate. Therefore they use HTTP which is actually less secure than using the untrusted (self-signed) certificate. This is the problem I'm trying to solve.
You could always satisfy dns-01 challenges instead of http-01 challenges to acquire Let's Encrypt certificates as long as the DNS servers for the intended (sub)domain(s) are publicly accessible (even if the A and/or AAAA records of the (sub)domain(s) point to local IP addresses).
If you don't want to give control of DNS to other entities, you could delegate individual subdomains to other DNS zones to satisfy their challenges using something like acme-dns.
@griffin This sounds very interesting and would be a possible solution if the device can at least phone home every time the certificate should be renewed.
So in practice could the following process be followed:
I set up a domain for my devices .mydevice.mycompany.com and make it point to the local IP address of the device.
I satisfy the dns-01 challenge and acquire a certificate fore the device.
The user can now browse to .mydevice.mycompany.com and access their local device with a trusted certificate.
Suppose the client doesn't have internet access. Is it allowed for the private IP address to be in the SAN field of a Let's encrypt certificate? This way when the users browses to the IP address directly this would also work?
At present, Let's Encrypt only allows FQDNs as SANs, so no IP addresses, but no publicly trusted CA will ever issue a certificate for a private IP address since it is impossible to verify that you control every such address on every network.
The challenge here is that typically browsers will not trust a certificate that does not match the host requested in the address bar of the browser.
Since the acquisition of certificates using dns-01 challenges only requires making requests to the DNS servers of mycompany.com, the devices themselves would not even be required to be involved with acquiring the certificates. It mainly comes down to management of pushing the certificate(s) (and especially their private keys) to the appropriate device(s).
@griffin Thank you for the help. It is certainly a partial solution to my problem but as I understand there is currently no technical solution to create devices to which a user can surf to it's IP-address and don't get any security warnings.
I think this is a shortcoming, not of Let's Encrypt, but of the current technical SSL system
If you're pinning that specific name constrained intermediate in your devices anyway, there's absolutely no added benenfit of using a publically trusted CA, as you're explicitely giving trust to that intermediate anyway. A private CA set up by yourself would be equal and much more easy to set up.
The challenge might be that the browsing devices might not be private to the network and thus trust might need to be established (via pinning as you've identified). I think @dpape is probably hoping for more organic trust, perhaps? Maybe not though.
Thank you and @griffin for the very fast and detailed help. The private CA option gives about the same result as using device unique self-signed certs that we use now.
As @griffin points out I'm indeed hoping for a kind of more organic trust. I'm been made aware that this may not be possible with the way SSL/trust is currently set up and many 'solutions' exist. But any proposed solution involves the user to install certificates or to have some name resolution system in place.
In reality this is not the case and the user doesn't know anything about trust, SSL, networking, ... The only thing that a users sees is the following:
When using HTTP (for ex. http:192.168.0.10): light grey warning 'Not Secure'. No intermediate warning screen is displayed. The user is used to ignoring this and can browse and use the device without issues. Altough the connection is not encrypted.
When using HTTPS (for ex. https:192.168.0.10): a red warning screen is shown and the user must click 'Advance settings' and then 'Accept the risk', ... and then while browsing a red 'Not Secure' warning is shown. This let's customers call the customer service.
I know that the chain of trust cannot be assured and this is the reason that browsers alert the users. But I think that using the HTTP option is even less secure and I could imagine that if executed well browsers should give the light grey 'Not Secure' warning in the case HTTPS is used when browsing to a private IP.
I know this community doesn't have any influence on this but I wanted to share my opinion on the subject en maybe there was a solution that I was not aware of. It is now clear that such a solution does not yet exist unfortunately.
Well... you could instruct users to have a local host file entry that maps the subdomain name in the browser's address bar to a particular local IP address, thus giving you the offline name-resolution you desire.
The challenge would be updating said mappings if the IP addresses change. That's what DNS is normally used for (with caching flushed/ignored, of course). You could always set up a local DNS server inside your network to map.
Using TLS without any trust is also subject to MitM-attacks, just as HTTP without any TLS. Unless you instruct the user to look up the certificate fingerprint and compare that fingerprint with a securely distributed list of known trusted certificates. I.e.: human based certificate pinning
The best option for corporate systems is to securely distribute a private CAs root certificate, so your private CA is trusted, so no warnings ensue. I'm pretty sure commonly used corporate systems (Active Directory, that sort of stuff) have methods for doing this.
For smaller companies with a small user base, you can instruct your users to install the private CA root once. After that, no errors any longer.
The other option is to use publically available hostnames indeed, which can resolve to private IPs, and use the dns-01 challenge.
If it's an intermediate CA from a trusted root CA, you don't need to install it on the devices. Getting such a certificate is expensive.
You can create your own root CA and install the root certificate on those devices. You'd have to create a root certificate with a very long validity (like 10 or 20 years) and then generate intermediates every couple of years, keeping the root private key offline in a safe. Those intermediates get used to issue the actual certificates.
I think you are aiming above the clouds, above the sky, above the limits of what is acceptably possible.
If you want a cert that is signed from an Internet trusted root, then how can this ever be satisfied?:
[Without Internet access the signer can't be verified.]
This is by far you're best chance at coming close to what I think you are asking for:
The name or IP in the URL will always show a RED warning when the issuer is not trusted (i.e. self-signed certs).
The fact that it is an IP (and not a name) changes nothing.
If you are to build your own trust, then you can manage it any way you like (use names, IPs, names & IPs). You're only real challenge is then how to add your CA to each client's trusted root list.
[and also updating the list for any intermediate certs throughout the life of the system - which potentially can be very many years]
I would start with a single CA (no intermediates) in a very small lab and run through the motions until you get that right and then try to scale it up/out from there.
For clients with Internet access, you can easily provide the instructions and your CA cert online.
For clients without Internet access, you will have to provide instructions on how to copy the files from the Internet to the offline clients (i.e. USB sticks) and possibly also to the device you manage/provide.
No, it really doesn't, and for one important reason: once your client devices trust that CA's cert--a one-time thing--they'll trust anything signed by that cert. You won't get errors in the browser the way you do with a self-signed cert (every time, even if you do bypass the warning). Firefox will still tell you if you look:
But to all appearances, it's business as usual:
I'd been using Let's Encrypt for certs for just about everything on my LAN, but more recently I set up a local CA following this guide:
It has a lot of nice touches--the root private key is stored offline, it uses a YubiKey as a poor man's HSM, it incorporates a hardware true random number generator, and it can validate using ACME (among other things), so most existing ACME clients can instead be pointed to your local CA rather than Let's Encrypt. Of course, it doesn't have to run on a Raspberry Pi, but that's a cheap way to put it on a completely independent device--all in, this system costs a little over US$100.