Initial question
We make devices which run a webserver and the user can control some functionality of the device by browsing directly to the IP of the device. This can be a fixed IP when a direct WiFi or ethernet connection is used but in most cases this is the IP that the device has received from a DHCP server in the network.
More and more HTTPS is required to access some of the more advanced functionality of a browser. For example to access cache (https://developer.mozilla.org/en-US/docs/Web/API/Cache), to allow the webcam to be used (https://blog.mozilla.org/webrtc/camera-microphone-require-https-in-firefox-68/), Service Workers (https://www.digicert.com/dc/blog/https-only-features-in-browsers/), ... The list keeps growing every day.
I'm all pro to have secure systems but I think there is one major issue. The way HTTPS (TLS) is set up a certificate is only marked as valid if the domain name matches the one in the certificate and the certificate authority is accepted by the client's browser, the chain of trust as it is called. This works beautifully on the web where fixed hostnames are used.
However when users are not using the internet but their local network the hostname is not known beforehand. Sometimes users can use local DNS, mDNS but this is not always the case. Many times users just use the internal IPv4 address. This is where the trouble begins because there are two options with using the devices we make:
- The user does not use HTTPS (we do not enforce it, read on to see why). The major browsers at this time do not give an explicit warning but mark the page as 'Not secure' in light grey. Most users don't even notice it and are very happy.
- The user uses HTTPS on the same device. Altough this makes there connection more secure the browsers are now telling them explicitly to use the device with extreme caution and that the connection is probably hacked and private data could be stolen. The site is now marked 'insecure' in red and the user must press 2 or 3 buttons to allow for a certificate exception.
Option number 2 is the cause that we do not force the devices to be accessed by HTTPS because it simply alarms to many users and floods customer service. Five years ago this was not really an issue because everything could be done without HTTPS. With more and more API's now only working in a 'Secure Context' this is really becoming a problem for us.
Therefore I think the need is becoming very big to come up with a system to use HTTPS without the hostname system, strictly in internal networks. I could imagine that the private IPv4 ranges could be excluded from the warnings or something more clever. This brings me to my question, do you face the same problems and how can this be solved?
Update 1
As pointed out in the first comment the now proposed solution is to use a wildcard certificate and to configure a DNS entry for the device on a public domain. This however has the issue that the client still requires an active internet connection. This is certainly not always the case in these kind of setups.
Update 2
I also found this article on Let's encrypt which talks about the same subject without giving a solution: https://letsencrypt.org/docs/certificates-for-localhost/
Update 3: hypothetical solution idea
After reading the below answers and comments I was thinking of a possible secure solution for the problem. Would the below setup (if it would be allowed) secure?
- 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.
Please comment if I overlook something.
Update 4:
I want to thank everyone for all the help and thinking along. The conclusion for me is that the whole idea behind certificates and the trust chain behind it doesn't allow what I want. This is because there is simply no way for a CA to be sure that the internal IP address I'm pointing to is uniquely owned by the device that I want to reach. An internal IP, for example 192.168.0.10, is owned by thousands devices and thus it is not possible to grant a certificate which allows browsers to show no warning display.
The only option is to do the certificate validation by manual intervention (installing the device certificate, pushing your own device's CA to the user, and the various more complex options as proposed in the answers). This is simply something I need to live with.
Nevertheless I think I'm going to open a ticket with Firefox and Chrome. Because I think that for internal IP-addresses a simple grey non-secure warning, as with HTTP, is more than enough of a warning. The red warnings should only be shown when making use of HTTPS in the use case it was designed for.
Update 5:
I have filed a bug report at Bugzilla: https://bugzilla.mozilla.org/show_bug.cgi?id=1705543 I'm posting this link as a reference so anyone can follow the issue.