Skip to content

got error all instances of 'tlsInsecure' and 'tlsAllowInvalidCertificates' must be consistent when parse uri to options with parameters ssl=true&tlsInsecure=true&tlsAllowInvalidCertificates=true #1452

@KnairWang

Description

@KnairWang

I am trying use rust mongodb driver (v3.2.4) to connect to a mongodb replicaset with self-signed certificate.

At the very beginning, then connection string was like

mongodb://user:pass@IP1:27017,IP2:27017,IP3:27017/?replicaSet=myreplica&authSource=admin&ssl=true&tlsInsecure=true

and then I got error complaining about the invalid certificate.

Error: Kind: Server selection timeout: No available servers. Topology: { Type: ReplicaSetNoPrimary, Set Name: myreplica, Servers: [ { Address: IP1:27017, Type: Unknown, Error: Kind: I/O error: invalid peer certificate: UnknownIssuer, labels: {} }, { Address: IP2:27017, Type: Unknown, Error: Kind: I/O error: invalid peer certificate: UnknownIssuer, labels: {} }, { Address: IP3:27017, Type: Unknown, Error: Kind: I/O error: invalid peer certificate: UnknownIssuer, labels: {} } ] }, labels: {}

and the debug output of client options are like:

ClientOptions { hosts: [Tcp { host: "IP1", port: Some(27017) }, Tcp { host: "IP2", port: Some(27017) }, Tcp { host: "IP3", port: Some(27017) }], app_name: None, connect_timeout: None, credential: Some(Credential("REDACTED")), direct_connection: None, driver_info: None, heartbeat_freq: None, load_balanced: None, local_threshold: None, max_idle_time: None, max_pool_size: None, min_pool_size: None, max_connecting: None, read_concern: None, repl_set_name: Some("myreplica"), retry_reads: None, retry_writes: None, server_monitoring_mode: None, selection_criteria: None, server_api: None, server_selection_timeout: None, default_database: None, srv_service_name: None, tls: Some(Enabled(TlsOptions { allow_invalid_certificates: Some(false), ca_file_path: None, cert_key_file_path: None })), write_concern: None, srv_max_hosts: None, .. }

I notice the allow_invalid_certificates is Some(false), so I manually set the TLS with code, and it works.

    options.tls = Some(Tls::Enabled(
        TlsOptions::builder()
            .allow_invalid_certificates(true)
            .build(),
    ));

I thought it was caused by lacking query parameter tlsAllowInvalidCertificates (official docs), then I updated the connection string to:

mongodb://user:pass@IP1:27017,IP2:27017,IP3:27017/?replicaSet=myreplica&authSource=admin&ssl=true&tlsInsecure=true&tlsAllowInvalidCertificates=true

But this time, I got different error:

Error: Kind: An invalid argument was provided: all instances of 'tlsInsecure' and 'tlsAllowInvalidCertificates' must be consistent (e.g. 'tlsInsecure' cannot be true when 'tlsAllowInvalidCertificates' is false, or vice-versa), labels: {}

By check the source code, I found the code is raising this error on inconsistent way with the error description, by line let allow_invalid_certificates = if k == "tlsinsecure" { !val } else { val };:

// src/client/options.rs, start on line 2067 at tag v3.2.4
...
...
            k @ "tlsinsecure" | k @ "tlsallowinvalidcertificates" => {
                let val = get_bool!(value, k);

                let allow_invalid_certificates = if k == "tlsinsecure" { !val } else { val };

                match self.tls {
                    Some(Tls::Disabled) => {
                        return Err(ErrorKind::InvalidArgument {
                            message: "'tlsInsecure' can't be set if tls=false".into(),
                        }
                        .into())
                    }
                    Some(Tls::Enabled(ref options))
                        if options.allow_invalid_certificates.is_some()
                            && options.allow_invalid_certificates
                                != Some(allow_invalid_certificates) =>
                    {
                        return Err(ErrorKind::InvalidArgument {
                            message: "all instances of 'tlsInsecure' and \
                                      'tlsAllowInvalidCertificates' must be consistent (e.g. \
                                      'tlsInsecure' cannot be true when \
                                      'tlsAllowInvalidCertificates' is false, or vice-versa)"
                                .into(),
                        }
                        .into());
                    }
            ...
            ...
            }
...
...

According to the source code, when parsing the URL and if it receives tlsinsecure, it sets tlsallowinvalidcertificates to the opposite value. But the error message says these two value should be consistent.

I am not sure what is the expected behavior, but now the error message is not match the code behavior.
My humble opinion it that, tlsincesure should set tlsallowinvalidcertificates to same value like what the error message says.

Metadata

Metadata

Labels

tracked-in-jiraTicket filed in Mongo's Jira system

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions