[SERVER-36669] IP address hostnames are matched against DNS subjectAltNames Created: 14/Aug/18  Updated: 06/Dec/22

Status: Backlog
Project: Core Server
Component/s: Shell
Affects Version/s: 4.0.1
Fix Version/s: None

Type: Improvement Priority: Major - P3
Reporter: Shane Harvey Assignee: Backlog - Security Team
Resolution: Unresolved Votes: 0
Labels: former-quick-wins
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Gantt Dependency
has to be done after SERVER-36895 Test for SAN type "IP Address" in Ope... Closed
Related
is related to PYTHON-1627 Unable to connect with PyMongo 3.7.1,... Closed
Assigned Teams:
Server Security
Participants:
Case:

 Description   

In PYTHON-1627, Dcossey014 reports that his server that was misconfigured with a DNS subjectAltName of '127.0.0.1':

$ openssl x509 -text -noout -in ./mongodb.pem
    ...
  X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:<server1>, DNS:<*.server_domain.com>, DNS:127.0.0.1
    ...

However the mongo shell can still connect:

$ ./mongo --host 127.0.0.1 --port 27017 --ssl --sslCAFile ~/ssl_cert_location/mongodb6.pem
    MongoDB shell version v4.0.1
    connecting to: mongodb://127.0.0.1:27017/
    MongoDB server version: 3.6.5
    WARNING: shell and server versions do not match
  MongoDB Enterprise > use admin
    switched to db admin

PyMongo fails hostname matching to such a server because the hostname, 127.0.0.1, is an IP address and therefor is only compared to iPAddress subjectAltName. As far as I can tell PyMongo (and CPython) are following the relevant RFCs with respect to IP address matching. From RFC 2818

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.

From RFC 6125 :

3.1.3.2. Comparison of IP Addresses

When the reference identity is an IP address, the identity MUST be
converted to the "network byte order" octet string representation
[IP] [IPv6]. For IP Version 4, as specified in RFC 791, the octet
string will contain exactly four octets. For IP Version 6, as
specified in RFC 2460, the octet string will contain exactly sixteen
octets. This octet string is then compared against subjectAltName
values of type iPAddress. A match occurs if the reference identity
octet string and value octet strings are identical.

So I think the mongo shell is performing non-standard subject alt name comparisons between IP addresses and DNS subjectAltNames.



 Comments   
Comment by Spencer Jackson [ 04/Oct/18 ]

I think this ticket has to be done after we've added support for the IP address SAN type. We probably need at least a release with that functionality before we can start restricting this.

Comment by David Cossey [ 15/Aug/18 ]

I went back and checked the original Security Certificate.  It appears the Common Name for the original Certificate was set to '127.0.0.1'.  They did not have our server name set as the Common Name in the original Certificate.  Therefore, Mongo Shell and Robo 3T were connecting with the wildcard altName inside the Domain and outside the Domain, somehow Mongo Shell and Robo 3T were matching '127.0.0.1' from the Common Name in the Certificate or from altName DNS.  See Below:

Original Certificate:

$ openssl x509 -text -noout -in ~/ssl_cert_location/mongodb_old.pem 
     ... 
  ... CN=127.0.0.1 
     ...
  X509v3 Subject Alternative Name: 
     DNS:<server1>, DNS:<*.server_domain.com>, DNS:127.0.0.1

 

New Certificate:

$ openssl x509 -text -noout -in ~/ssl_cert_location/mongodb.pem
    ...
  ... CN=<server0>
    ...
  X509v3 Subject Alternative Name:
    DNS:<server1>, DNS:<*.server_domain.com>, DNS:localhost, IP Address:127.0.0.1, 
        IP Address:0:0:0:0:0:0:0:1

Not sure how Mongo Shell and Robo 3T were able to match '127.0.0.1' from the Common Name or altName DNS of the original certificate, but that appears to be what happened. 

Having the Security Certificate setup properly seems to throw Mongo Shell and Robo 3T for a loop though.  Attempt to connect with new properly set x509 SSL Certificate:

$ ./mongo --ssl --sslCAFile ~/ssl_cert_location/mongodb.pem 127.0.0.1/admin   
  MongoDB shell version v4.0.1   
  connecting to: mongodb://127.0.0.1:27017/admin   
  2018-08-14T17:41:54.191-0400 E NETWORK [js] The server certificate does not match
    the host name. 
  Hostname 127.0.0.1 does not match SAN(s): <server1> <*.server_domain.com>
    localhost   
  2018-08-14T17:41:54.192-0400 E QUERY [js] Error: couldn't connect to server 
    127.0.0.1:27017, connection attempt failed: SSLHandshakeFailed: The server 
    certificate does not match the host name.   
  Hostname: 127.0.0.1 does not match SAN(s): <server1> <*.server_domain.com> 
    localhost :  connect@src/mongo/shell/mongo.js:257:13 @(connect):1:6 
    exception: connect failed
 
$ ./mongo --help
  MongoDB shell version v4.0.1usage: ./mongo [options] [db address] [file names (ending in .js)]
  db address can be:  
    foo                   foo database on local machine
    192.168.0.5/foo       foo database on 192.168.0.5 machine  
    192.168.0.5:9999/foo  foo database on 192.168.0.5 machine on port 9999

 

Generated at Thu Feb 08 04:43:46 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.