I am trying to connect to localhost over https so that I can use service workers. I have tried many solutions such as chrome flags as described in posts such as this, but none have worked. Finally, I used OpenSSL to make myself a certificate authority and sign my own certificate. However, despite everything running correctly Chrome (and other browsers) still rejected my certificate.
This was due to the lack of subject alternative names. I then added my IP address as an alternate name, but it was not accepted either - chrome told me that the "domain came from [IP address]", along with the error message ERR_CERT_COMMON_NAME_INVALID
What other subject alternative names can I use to prove my identity over localhost? (or alternatively, are there any other solutions?) I am using Apache with XAMPP.
The SAN must match the domain in the URL you use. If you use https://localhost then there must be a SAN of type DNS with value localhost. If you use https://127.0.0.1 then there must be a SAN of type IP with value 127.0.0.1. Not the importance of the correct type and not only of the value.
I use localhost as the common name. From my understanding the SAN must be different but still refer to the same domain ...
No. The CN is actually irrelevant and will usually not even be looked at if a SAN is given (or in case of Chrome: it will never look at the CN and requires always SAN). So just make sure that the SAN is correct.
Related
The SSL/TLS certificates used to secure websites allow for specifying a subdomain wildcard:
*.example.com will be valid for www.example.com, subdomain.example.com etc.
Is it possible to use wildcards for IP-addresses? In particular, I want an SSL-certificate for local development like this:
192.168.1.*, which would then be valid for any of the 256 different IP-addresses that are reachable inside the NAT-network of my WiFi router.
Instead of just using localhost, 127.0.0.1, 0.0.0.0, ::1 as alternate names for my certificate, I also want to be able to connect my mobile phone to test the development version of my website which would be available at lets say 192.168.1.40. But then the same certificate could not be reused from a different development machine - since it would get a different IP on the same network.
Let's encrypt doesn't support using IP-addresses - which means I would instead use self-signed or locally trusted certificates instead.
No. RFC 2818 section 3.1 specifies wildcard matching for dNSName items; although it isn't clear here, this is universally implemented to allow the wildcard only as the leftmost DNS label, which is the least significant because DNS names are right-to-left. It specifies that if iPAddress is used the match must be exact (no wildcard), and even if it allowed wildcard, because IP addresses are left-to-right, only a wildcard at the right, like the one you proposed, would be useful.
However, if you're only using a /24 of 192.168.x.0 or less, as many people do, and likely only some of the addresses in that range, it's not hard to just list all the addresses you need in the cert. For example, if you're using DHCP-assigned addresses, often those cover only half or less of the range nominally available from the netmask.
No CA operating under CA/Browser forum rules, and thus acceptable to major browsers, will issue a cert for a private (RFC 1918) address; see the Baseline Requirements at https://wwww.cabforum.org . They won't do local or 'fake' domainnames like .local .localdomain .dev .test either, for the same reason.
BTW 127.0.0.1 and ::1 are real addresses, albeit not routable and thus usable only locally. 0.0.0.0 and ::0 are different; they aren't addresses at all, and you can't connect() to them; in fact they are used to represent the state of not being connected. You can use them in bind() but that actually means bind to all configured addresses (and interfaces).
I am getting the bad certificate error while accessing the server using IP address instead DNS name.
Is this functionality newly introduced in tls1.1. and tls 1.2? It would be good if someone would point out OpenSSL code where it fails and return the bad certificate error.
Why do we get bad certificate error while accessing the server using IP address instead dns name?
It depends on the issuing/validation policies, user agents, and the version of OpenSSL you are using. So to give you a precise answer, we need to know more about your configuration.
Generally speaking, suppose www.example.com has a IP address of www.xxx.yyy.zzz. If you connect via https://www.example.com/..., then the connection should succeed. If you connect using a browser via https://www.xxx.yyy.zzz/... then it should always fail. If you connect using another user agent via https://www.xxx.yyy.zzz/... then it should succeed if the certificate includes www.xxx.yyy.zzz; and fail otherwise.
Issuing/Validation Policies
There are two bodies which dominate issuing/validation policies. They are the CA/Browser Forum, and the Internet Engineering Task Force (IETF).
Browsers, Like Chrome, Firefox and Internet Explorer, follow the CA/B Baseline Requirements (CA/B BR).
Other user agents, like cURL and Wget, follow IETF issuing and validation policies, like RFC 5280, Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile and RFC 6125, Representation and Verification of Domain-Based Application Service Identity within Internet Public Key Infrastructure Using X.509 (PKIX) Certificates in the Context of Transport Layer Security (TLS). The RFCs are more relaxed that CA/B issuing policies.
User Agents
Different user agents have different policies that apply to DNS names. Some want a traditional hostname found in DNS, while others allow IP addresses.
Browsers only allow DNS hostnames in the Subject Alternate Name (SAN). If the hostname is missing from the SAN, then the match will not occur. Putting the server name in the Common Name is a waste of time and energy because browsers require host names in the SAN.
Browsers do not match a public IP address in the SAN. They will sometimes allow a Private IP from RFC 1918, Address Allocation for Private Internets.
Other user agents allow any name in the Subject Alternate Name (SAN). They also will match a name in both the Common Name (CN) and the Subject Alternate Name (SAN). Names include a DNS name like www.example.com, a public IP address, a private IP address like 192.168.10.10 and a local name like localhost and localhost.localdomain.
OpenSSL Version
OpenSSL version 1.0.2 and below did not perform hostname validation. That is, you had to perform the matching yourself. If you did not perform hostname validation yourself, then it appeared the connection always succeeded. Also see Hostname Validation and TLS Client on the OpenSSL wiki.
OpenSSL 1.1.0 and above perform hostname matching. If you switch to 1.1.0, then you should begin experiencing failures if you were not performing hostname matching youself or you were not strictly following issuing policies.
It would be good if someone would point out OpenSSL code where it fails and return the bad certificate error.
The check-ins occurred in early-2015, and they have been available in Master (i.e., 1.1.0-dev) since that time. The code was also available in 1.0.2, but you had to perform special actions. The routines were not available in 1.0.1 or below. Also see Hostname Validation on the OpenSSL wiki. I don't have the Git check-ins because I'm on a Windows machine at the moment.
More information of the rules for names and their locations can be found at How do you sign Certificate Signing Request with your Certification Authority and How to create a self-signed certificate with openssl. There are at least four or six more documents covering them, like how things need to be presented for HTTP Strict Transport Security (HSTS) and Public Key Pinning with Overrides for HTTP.
This question already has answers here:
Is it possible to have SSL certificate for IP address, not domain name? [closed]
(7 answers)
Closed 11 months ago.
I wonder why I am getting certificate error if I try to access a site with ip address instead of domain name. Lets say for example nslookup says google.com is 173.194.43.96, so I tried to browse https://173.194.43.96 and I got certificate error saying that the security certificate presented by this website was issued for a different website's address. Why is that so?
This is because an SSL certificate is issued for a particular domain name. If the certificate name doesn't match the visited domain, the browser will show an error.
One of the main functions of SSL is to prove to the user that they are really connecting to the site they requested, and not to an attacker masquerading as the end site. Without linking the domain name to the certificate this would not be possible.
It is conceivable that the browser certificate system could have been designed to include the IP address in the certificate, but this would make it difficult to use DNS load balancing or even to change hosting providers, as a new certificate would have to be issued each time this happened. If the certificate included just the IP address and not the domain, this would leave the user defenseless against DNS spoofing attacks. So the only way forward really was to use the domain alone.
As a matter of interest, it is possible to obtain an SSL certificate for an IP address - and as Google is their own certificate authority, they could issue themselves a certificate for 173.194.43.96 and thus make it possible to browse google securely by ip address, so long as they used SNI to serve up the correct certificate. It seems implausible that this would be worth the additional complexity however...
This is a nice introduction to SSL if you want to read more:
https://timnash.co.uk/guessing-ssl-questions/
On MAC High Sierra and Python 3.6.4, I tried the solution: requests toolbelt:HostHeaderSSLAdapter 1st, unfortunately, it doesn't work for me, then I tried
forcediphttpsadapter, got it works finally.
The author explains everything in the readme part and has provided a sample script and it can be followed easily.
1.Install the library by pip install requests[security] forcediphttpsadapter
2.run the sample script:
import requests
from forcediphttpsadapter.adapters import ForcedIPHTTPSAdapter
session = requests.Session()
session.mount("https://example.com", ForcedIPHTTPSAdapter(dest_ip='1.2.3.4'))
response = session.get(
'/some/path', headers={'Host': 'example.com'}, verify=False)
Note: For some cases, you may need to remove the prefix: 'www' from the url.
What happens is that the certificate is issued to www.google.com, and not to its IP address. Hence, your browser won't be able to verify the certificate, which lists www.google.com as entity.
For more info, see: www.digicert.com/ssl-support/certificate-name-mismatch-error.htm
The Common Name is typically composed of Host + Domain Name and will look like www.yoursite.com or yoursite.com. SSL Server Certificates are specific to the Common Name that they have been issued to at the Host level. The Common Name must be the same as the Web address you will be accessing when connecting to a secure site. For example, a SSL Server Certificate for the domain domain.com will receive a warning if accessing a site named www.domain.com or secure.domain.com, as www.domain.com and secure.domain.com are different from domain.com.
I hit a compatibility issues with Oracle Weblogic and an SSL certificate which uses wildcard DNS names in in the Subject Alternate Names (SAN) extension. Seems that none of the modern browsers have a problem with that, but according to Thawte and Oracle for example this is not allowed and Weblogic's wildcard hostname verifier miserably fails - apparently by design:
http://docs.oracle.com/cd/E29542_01/apirefs.1111/e13941/weblogic/security/utils/SSLWLSWildcardHostnameVerifier.html
"DNSNames obtained from the peer certificate's SubjectAlternativeNames extension may not be wildcarded"
Other CAs seem to be perfectly alright with issuing such certs.
RFC 5280 seems to leave implementation in this case up in the air:
"Finally, the semantics of subject alternative names that include wildcard characters (e.g., as a placeholder for a set of names) are not addressed by this specification. Applications with specific requirements MAY use such names, but they must define the semantics."
With the obvious security considerations aside are there any rules which apply?
PS
Now I can really appreciate having standards...
SAN with wildcards are perfectly valid for HTTPS. RFC5280 ist probably not the right RFC for this stuff since it leaves these details out. Better look at RFC6125 and RFC2818.
But of course wildcards have restrictions. You can only use them in the leftmost label (no *.*.com) and they only match a single label, that is *.example.com matches www.example.com but not www.foo.example.com.
A PCI Compliance scanner is balking that the self signed SSL certificate protecting secure access to Plesk Panel contains a name mismatch between the location of the Plesk Panel and the name on the certificate, namely the self-signed cert's name is "Parallels" and the domain to reach Plesk is 'ip address:8443'.
So I figured I would go ahead and get a free SSL certificate to try to fiddle with this error. But when I generated the certificate I used my server domain name as the site name when I generated the certificate. So if I visit 'domain name:8443' all is fine, no ssl warning. But if I visit 'ip address:8443' (which I believe is what the scanner does) I get the certificate name mismatch error, Digicert's ssl checker says that the certificate name should be the ip address.
Can I even generate a certificate whose common name is the ip address? I am tempted to say I should just do what the PCI scanner accepts, but what is really the correct common name to use? Anybody run into this issue before?
You can try a Subject Alternative Name extension for the IP address. Also, you can keep "Parallels" as the Common Name, and add a Subject Alternative Name extension for the DNS name, which should be the preferred match (i.e. higher precedence than Common Name.)
Can I even generate a certificate whose common name is the ip address?
No, you shouldn't. While this may work with some browser, this will fail with clients that are compliant with the HTTPS specification:
In some cases, the URI is specified as an IP address rather than a hostname. In this case, the iPAddress subjectAltName must be present in the certificate and must exactly match the IP in the URI.
If you want to use an IP address in a certificate, you must have it in as a Subject Alternative Name (of type IP address, not DNS). You can check this question for details on how to do this.
However, more importantly, it sounds like in your case you don't need to use the IP address at all.
The purpose of certificate name verification is to check that the identity in the certificate matches the identity as requested by the client. (Reverse lookups or other names don't matter.)
The fact that you've already configured your system for your domain name and that it works when using the name means that it's already configured properly. It sounds like your giving your scanning tool the IP address of what you're trying to scan (which isn't what the clients would normally use): make it use your host name instead. That's what the scanning tool should try to compare anyway.
Can I even generate a certificate whose common name is the ip address?
(Thanks Bruno for pointing to right solution) There is enough to set subjectAltName in CSR.
IFAIK there is no such option in Plesk, but here good instruction for openssl http://apetec.com/support/GenerateSAN-CSR.htm