Python requests SSL Hostname doesn't match err

2019-07-14 04:40发布

问题:

I have been trying to access an API which is secured using SSL using python requests library as given below

requests.get('https://path/to/url',cert=('cert.pem','key.pem'),verify='ca.pem')

but am getting an error

File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 385, in send
raise SSLError(e)
requests.exceptions.SSLError: hostname '10.10.10.10' doesn't match u'*' # IP address is not real.

If my understanding is right this certificates can be used with any server since they are signed with '*' as domain.

I guess the requests library is making a strict match of hostname verification instead of regular expression matching.

so my question is whether it is a bug with requests library or is this the way it is indented to work?

It is working perfectly fine when I use curl command as given below.

curl https://path/to/url  --cert cert.pem  --key key.pem --cacert ca.pem

So i have two possibilities, either curl library is not performing hostname verification or they are doing it with regular expression.

Where am i going wrong here? Expecting a detailed answer

回答1:

How wildcards are matched is described in RFC 2818, more precisely stated in RFC 6125 and there are also information in the CAB baseline requirements. At the end the browsers implement the following:

  • Only the leftmost label can have a wildcard and a wildcard matches only a single label. That is no wildcards like *, *.*.example.com etc are possible. Also *.example.com matches www.example.com but not sub.www.example.com or example.com.
  • Additionally there are restrictions depending on the public key suffix, i.e no browsers allow wildcards for *.com, some don't allow wildcards for *.co.uk to.
  • And there are restriction where the wildcard can be in the certificate. All support wildcards in the subject alternative name section, but not all allow wildcards in the common name.
  • Apart from that wildcards are only for hostnames. This means IP addresses are not allowed to be matched against a wildcard entry. To have an IP address included into a certificate you must use an iPAdress as subject alternative name (all browsers except IE) or a dNSName (no browsers except IE) or the IP address must be in the CN (all browsers except Safari).

Several languages like python did not do any checks against the hostname at all in the past but with 2.7.9 python also checks the hostname by default and has an implementation which is mostly compatible to what the browsers do.

As for curl: it depends on the version of curl you use. 7.36 should be ok but older versions have flaws in the validation.



回答2:

There are no real, approved standards about how the wildcards are interpreted in certificates. Whether they match one label, or multiple, whether they match ips or not (the ones in SAN extension definitely don't), whether you can match part of a label (prefix-*.example.com), etc. are not well defined.

I'd suggest not using * on it's own, but only as one full label (*.example.com). And don't use it for IPs, just names.