blackbeam / rust-mysql-simple

Mysql client library implemented in rust.
Apache License 2.0
663 stars 144 forks source link

How to make a connection to a #297

Closed ArthurZ closed 2 years ago

ArthurZ commented 2 years ago

Hi,

My MySQL server is set to --require_secure_transport=ON (AWS Aurora). How to implement a secure (TLS enabled) connection?

It seems it can be set via the SSL options, but neither works:

the traitFrom<for<'r> fn(&'r SslOpts) -> bool {SslOpts::skip_domain_validation}>is not implemented forstd::option::Option`

Note: using Go mysql driver I can connect when using the ?tls=skip-verify directive prepended to its connection string (this does not work either in rust-mysql)

blackbeam commented 2 years ago

Hi. The error seem strange. Could you please share the code? I mean that SSL may not work for some reason but the code should compile.

ArthurZ commented 2 years ago

Sure Anatoly:

let mut opts = mysql::OptsBuilder::new();
opts.ip_or_hostname(Some("aurora.rds"))  
        .tcp_port(xxxx)
        .db_name(Some("yyy"))
        .user(Some("zzz"))  
        .pass(Some("******"))
        .ssl_opts(mysql::SslOpts::skip_domain_validation);
 let pool = mysql::Pool::new(opts).unwrap();

Outputs:

error[E0277]: the trait bound `std::option::Option<SslOpts>: From<for<'r> fn(&'r SslOpts) -> bool {SslOpts::skip_domain_validation}>` is not satisfied
  --> src\main.rs:20:10
   |
20 |         .ssl_opts(mysql::SslOpts::skip_domain_validation);  // <- enable SSL with default options
   |          ^^^^^^^^ the trait `From<for<'r> fn(&'r SslOpts) -> bool {SslOpts::skip_domain_validation}>` is not implemented for `std::option::Option<SslOpts>`
   |
   = help: the following implementations were found:
             <std::option::Option<&'a T> as From<&'a std::option::Option<T>>>
             <std::option::Option<&'a mut T> as From<&'a mut std::option::Option<T>>>
             <std::option::Option<T> as From<T>>
   = note: required because of the requirements on the impl of `Into<std::option::Option<SslOpts>>` for `for<'r> fn(&'r SslOpts) -> bool {SslOpts::skip_domain_validation}`
blackbeam commented 2 years ago

I see. OptsBuilder::ssl_opts expects an instance of SslOpts. The code should look like this:

let mut ssl_opts  = mysql::SslOpts::default()
    .with_danger_skip_domain_validation(true);
let opts = mysql::OptsBuilder::new()
    .ip_or_hostname(Some("aurora.rds"))  
    .tcp_port(xxxx)
    .db_name(Some("yyy"))
    .user(Some("zzz"))  
    .pass(Some("******"))
    .ssl_opts(Some(ssl_opts));
let pool = mysql::Pool::new(opts).unwrap();
ArthurZ commented 2 years ago

Thank you @blackbeam, It compiled, so that was my issues rather, however, now I am getting TlsHandshakeError { A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider. (os error -2146762487) }

blackbeam commented 2 years ago

You can go multiple directions from here (you'll need the proper certificate bundle from AWS that may be here):

Please note that SSL is quite capricious, so this may require greater effort.

ArthurZ commented 2 years ago

Thank you Anatoly, Perhaps you meant the with_danger_accept_invalid_certs option which worked. I did not see the "allow_invalid" one.