Scenario:
We have a device similar to a WiFi router that has UI and API exposed
The device will run on any LAN out of our control, just like a WiFi router runs on any house.
The device doesn't belong to any domain and is accessed through its IP address (i.e. 192.168.1.100) with a browser.
The protocol shall be HTTPS
The software used is .net Core/Kestrel on Windows
Currently we have warnings in all browsers telling that the device has an invalid certificate.
Constraint: The device shall be accessible by any machine (desktop/tablet) and cannot install or configure anything in the client machines.
The question is:
What it the best way to remove the warning? We read that there cannot be regular certificates for private/local IPs.
Self-signed certificates seem to work for few days and then the error shows up again.
There is no way to issue SSL certificate for an IP address; you have to have an actual name which you create the certificate for. In order to get such a name, you need a DNS. Since you don’t have access to the internal DNS of that local network, you will have to use a public DNS server for this.
This assumes that devices within that network do actually have internet access. If they don’t, then you’re completely out of luck.
If there is internet access, then you can simply make a public (sub-)domain point to your local IP address. Basically, configure the DNS for a domain that you own so that there is an A entry on the domain or one of its subdomains, that points to your local IP address 192.168.1.100.
That way, you can communicate that public domain to others, and when they try to resolve the domain, they will hit the DNS which will give the local IP address. So devices within that network can then get to your device and access it. Since they are accessing it then through that domain, a certificate for that exact domain would be generally accepted.
In theory, this works pretty well. In practice this can be a bit complicated or expensive though. Server certificates expire, so you will have to include the certificate (securely!) inside your device and also provide some means to update it eventually when it would expire. Free certificates, like from letsencrypt, will expire within a few weeks, but money will be able to buy you certificates that expire less quickly.
But in the end, it will still be somewhat painful. But not because of the domain name, but rather because of the certificate – at least if you want a certificate that is automatically trusted. Otherwise, you would be back at the beginning.
So If I understand it corretly, without internet access and without
access to internal DNS, there is no way to allow clients (within local
network) to access a REST api listening on "some" device within the
local network over HTTPS. Right?
That is not correct. You can use a wildcard certificate, generated with e.g. openssl and communicate securely over TLS encryption. Just the signing is not trusted, so modern Browsers will show the big warning "Not secure". That is awfully wrong. It is way more secure compared to plain http, because it is not sure you're talking to the server you're expecting but you talk securely encrypted.
In plain http it will be enough to just listen the packets flying by. With https you need to pretend to be the server and issue a certificate and the right endpoints. So a much bigger effort and for most use cases in local networks a sufficient level of security.
Generate Certificate
#!/bin/bash
CONFIG="
HOME = /var/lib/cert
[ req ]
default_bits = 4096
default_md = sha256
distinguished_name = req_distinguished_name
prompt = no
x509_extensions = v3_req
[ req_distinguished_name ]
countryName= YourCountryCode
stateOrProvinceName= YourState
localityName= YourTown
organizationName= YourCompany
organizationalUnitName= YourUnit
commonName= *
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = email:whatever#localhost
"
openssl genrsa -out /var/usr/cert/name.key 4096
openssl req -x509 -new -nodes -key /var/usr/cert/name.key \
-config <(echo "$CONFIG") -days 365 \
-out /var/usr/cert/name.crt
Apply it to your service.
For browsers it'll show this big ugly message
For apps connecting to services you'll often need to set a flag, disabling signing checks like:
curl -k or --insecure
influx -ssl -unsafeSsl
(google helps for your application)
Related
I'm setting up a webserver is for development and testing purposes, strictly local, no access from the Internet, but needs to be conform the production environment as close as possible, including SSL.
So I have set up a local CA on the server, created a server request using SubjectAltNames for several nodes running on them, and signed it using the just created CA, and instructed apache to user this setup.
CN in both CA as server is tdc.nl - which is the 'domain' I'm using locally. It has sites manage.tdc.nl, www.tdc.nl, so in the server-request, I defined:
[ v3-req ]
...
subjectAltNames = #alt_names
...
[ alt_names ]
DNS.1 = tdc.nl
DNS.2 = manage.tdc.nl
DNS.3 = www.tdc.nl
DNS.4 = mail.tdc.nl
All names (except mail.tdc.nl) are registered in \Windows\System32\drivers\etc\hosts on the workstation that I use to access each of these servers, and in the server itself. I installed the CA certificate on my workstation as trusted base certificate as prompted in many descriptions.
Then I access https://manage.tdc.nl with different browsers.
Chrome signals NET::ERR_CERT_COMMON_NAME_INVALID, Edge signals DLG_FLAGS_SEC_CERT_CN_INVALID. Though both allow me to continue, I want to get on without error messages. However, it's weird that Firefox seems to be happy, even without installing the CA certificate, just accepts the link, and I can proceed without message.
I checked the server certificate and that notes the alternate names, but these are missing in the CA certificate. Should the subjectAlternateNames also be specified in the CA? The documentation I read doesn't show anything on that.
Doublechecked config for CA and docs I used: found I was missing
copy_extensions = copy
Redone signing, now subjectAltNames are in server certificate
After restarting Apache, it worked.
We have an Microsoft Active Directory Domain with a large pool of domain controllers (DC) that are are setup with LDAP. These are all setup with LDAPS and uses Certificate Services via a template to setup a certificate with the domain name (i.e. test.corp) in the Subject Alternate Name (SAN) for the LDAPS server to serve.
Since these are DC's, DNS is setup in a pool for each these systems to respond to requests to test.corp in a round robin fashion.
Each of these DC's have multiple templates and multiple certificates in the Local Computer\Personal Certificate Store.
Upon testing, using a nodejs module, ldapjs when making a LDAPS request using the domain name, test.corp we notice that a handful of servers fail with the following message:
Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match
certificate's altnames: Host: test.corp. is not in the cert's
altnames: othername:, DNS:.test.corp
As we investigated we found that these handful of LDAPS servers are serving the incorrect certificate. We determined this by using the following command
openssl s_client -connect .test.corp:636
If you take the certificate section of the output and put it in a file and use a tool such as the Certificate manager or certutil to read the file, you can see the certificate is not the correct one. (It does not have the domain "test.corp" SAN). We also verified this by comparing the Serial Numbers
As we investigated, since we have DC's that have multiple certificates in the Local Computer\Personal Certificate store, we came across the following article:
https://social.technet.microsoft.com/wiki/contents/articles/2980.ldap-over-ssl-ldaps-certificate.aspx
It suggests putting the certificate from the local computer\Personal certificate store to the Active Directory Domain Service\Personal store. We followed the steps outlined but we found the same results.
Upon further investigation, it was suggested to use a tool called ldp or adsiedit. We then proceeded to use these tools and spoofed the local machine's host file we were doing the test from, to point the domain (test.corp) to the ip's of one of the DC's that are giving us trouble. After a restart to clear any cache we tested the "ldp" and "adsiedit" tools to connect to test.corp. These systems did not report any errors.
We found this odd, we then ran the openssl command to see what certificate it was serving from this same system and we found it was still serving the incorrect certificate.
Upon further research, it appears that the "ldp" upon selecting the SSL checkbox and "adsiedit" tools were not compliant with RFC6125, specifically B.3
https://www.rfc-editor.org/rfc/rfc6125#appendix-B.3
, which basically states the identity of the certificate must match the identity of the request otherwise the handshake would fail. This identity verification is done by using the certificate common name (CN) or the SAN.
Based on this appears the tools "ldp" and "adsiedit" are not conforming to the RFC6125 standard.
All this to say, we need to first fix the handful of domain controllers that are serving the correct certificate. We are open to suggestions since we have been working on this problem for the past few months. Second, is there a way to get the MS tools in question to work to the RFC6125 standard?
This has been moved to:
https://serverfault.com/questions/939515/ldaps-microsoft-active-directory-multiple-certificates-rfc6125
RFC6125 specifically states that it does not supersede existing RFCs. LDAP cert handling is defined in RFC4513. Outside of that, RFC6125 has significant flaws. See also https://bugzilla.redhat.com/show_bug.cgi?id=1740070#c26
LDP will supposedly validate the SSL against the client store if you toggle the ssl checkbox on the connection screen.
That said, I'm not surprised that neither it nor ADSI edit enforce that part of the standard given they are often used to configure or repair broken configurations. Out of the box and without Certificate Services they use self signed certs on LDAPS. I would wager 80% of DCs never get a proper certificate for LDAP. If they enforced it most wouldn't be able to connect. A better design decision would have been to toggle off the validation.
I use a similar openssl command to verify my own systems. I think it's superior to LDP even if LDP were to validate the certificate. To save you some effort, I would suggest using this variant of the openssl command:
echo | openssl s_client -connect .test.corp:636 2>/dev/null | openssl x509 -noout -dates -issuer -subject -text
That should save you having to output to a file and having to read it with other tools.
I've found LDAPS on AD to be a huge pain for the exact reasons you describe. It just seems to pick up the first valid cert it can find. If you've already added it to the AD DS personal store, I'm not sure where else to suggest you go other than removing some of tother certs from the DCs computer store.
I'm looking for a service online, able to simulate an expiring SSL certificate. I know about badssl.com, but that only seems to include an expired certificate. What I'm looking to do is to call an endpoint with a certificate expiring in something like 5 days. Possible?
I do not know about an online service tailored to your needs (you could also try to contact badssl.com and ask them if they would be willing to add your test case, as it may profit others too), but locally you can run openssl s_server and configure it to use any local certificate you would have created to be in the situation you need to test.
From its manual:
The s_server command implements a generic SSL/TLS server which listens for connections on a given port using SSL/TLS.
and:
s_server can be used to debug SSL clients. To accept connections from a web browser the command:
openssl s_server -accept 443 -www
can be used for example.
Otherwise, if you are outside of the world wide web world:
If a connection request is established with an SSL client and neither the -www nor the -WWW option has been used then normally any data received from the client is displayed and any key presses will be sent to the client.
(and follows a list of special keys for special operations).
I plan to deploy my own hardware device maybe in form of a RaspberryPi running a NodeJs server which should include HTTPS communication. It is intend to run as an intranet device and it will always named with the same computername (or same IP address if necessary). Let us say stephan.box.
What is the best practice to equip such devices with encryption to ensure secure wireless lan HTTP communication?
Is it possible to self sign a a SSL certificate for a static IP or domain name to avoid browser warning?
You can only avoid browser warnings if the issuer of the certificate or the certificate itself is trusted by the browser. If you create a certificate which is self-signed or if you use a private CA you must import this CA into ALL browsers which should access the system or accept the warning once in ALL browsers. The only way to avoid this is a CA which is already trusted by the browsers, that means buying a certificate (some CAs give also simple certificates away without costs).
I've got a domain purchased from godaddy (example.com), as well as an ssl certificate from them for that same domain. I have a single machine running a web server and a static ip, the domain from godaddy points to that static ip. The ssl cert is installed on that machine, and everything works fine.
Now I need to start hosting from a different machine, which has a different static IP address. I believe all I have to do is change the IP address for my domain in godaddy's control panel, and the ssl certificate should still be valid, even though it's a new IP address.
Is there any way to test this beforehand? Is my assumption correct that just changing the IP address in the domain record is all I have to do?
Thanks
SSL certificates are (almost always) associated with domain names, not IP addresses. Assuming you have a standard configuration for your SSL cert, you're fine.
But! You want to test this beforehand. OK:
openssl x509 -in yourcert.crt -text -noout
This command will allow you to examine your certificate. In particular, look for your hostname. Mine says something like:
X509v3 Subject Alternative Name:
DNS:mail.cternus.net, DNS:cternus.net
If your hostname is in there (and your IP address is not), you're golden.