ClickHouse / clickhouse-rs

Official pure Rust typed client for ClickHouse DB
https://clickhouse.com
Apache License 2.0
322 stars 92 forks source link

Cannot use custom CA or ignore self-sign verification #164

Closed ausrasul closed 1 month ago

ausrasul commented 1 month ago

Describe the bug

I'm trying to connect to a local clickhouse server running https with self signed certificate. Using "native-tls" or "rustls-tls" features, I couldn't find an option to turn of server certificate validation or provide the custom CA. I get the following error:

I tried to browse to https://localhost:8444/play and it works despite the self-signed warnings.

Steps to reproduce

  1. Start clickhouse-server in a docker container with self-signed certs
  2. Compile and run the rust code to connect.

Expected behaviour

Connection should be made.

Code example

main.rs

use tokio;
use clickhouse as ch;

async fn connect() -> Result<(), Box<dyn std::error::Error>> {
    let client = ch::Client::default()
        .with_url("https://localhost:8444");  // The container exposed port is mapped to 8444
    println!("Connected to Clickhouse");
    client.query("CREATE DATABASE IF NOT EXISTS db1 ON CLUSTER mycluster;").execute().await?;
    println!("Connected to Clickhouse db1");
    Ok(())
}

#[tokio::main]
async fn main() {
    connect().await.unwrap();
}

Cargo.toml

[package]
name = "my_app"
version = "0.1.0"
edition = "2021"

[dependencies]
tokio = { version = "1.20.0", features = ["full"] }
clickhouse = { version = "0.13.0", features = ["rustls-tls"] }
serde = { version = "1.0", features = ["derive"] }

Error log

Using rustls-tls:

Connected to Clickhouse
thread 'main' panicked at my_app/src/main.rs:16:21:
called `Result::unwrap()` on an `Err` value: Network(hyper_util::client::legacy::Error(Connect, Custom { kind: Other, error: Custom { kind: InvalidData, error: InvalidCertificate(UnknownIssuer) } }))
stack backtrace:
   0:        0x100bad2d0 - std::backtrace_rs::backtrace::libunwind::trace::hbebc8679d47bdc2c
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/../../backtrace/src/backtrace/libunwind.rs:116:5
   1:        0x100bad2d0 - std::backtrace_rs::backtrace::trace_unsynchronized::h3a2e9637943241aa
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:        0x100bad2d0 - std::sys::backtrace::_print_fmt::he430849680584674
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sys/backtrace.rs:65:5
   3:        0x100bad2d0 - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h243268f17d714c7f
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sys/backtrace.rs:40:26
   4:        0x100bc45a0 - core::fmt::rt::Argument::fmt::h0d339881c25f3c31
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/fmt/rt.rs:173:76
   5:        0x100bc45a0 - core::fmt::write::hb3cfb8a30e72d7ff
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/fmt/mod.rs:1182:21
   6:        0x100baabc8 - std::io::Write::write_fmt::hfb2314975de9ecf1
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/io/mod.rs:1827:15
   7:        0x100bae3ac - std::sys::backtrace::BacktraceLock::print::he14461129ccbfef5
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sys/backtrace.rs:43:9
   8:        0x100bae3ac - std::panicking::default_hook::{{closure}}::h14c7718ccf39d316
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:269:22
   9:        0x100badfd0 - std::panicking::default_hook::hc62e60da3be2f352
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:296:9
  10:        0x100baee70 - std::panicking::rust_panic_with_hook::h09e8a656f11e82b2
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:800:13
  11:        0x100bae7c0 - std::panicking::begin_panic_handler::{{closure}}::h1230eb3cc91b241c
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:674:13
  12:        0x100bad75c - std::sys::backtrace::__rust_end_short_backtrace::hc3491307aceda2c2
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sys/backtrace.rs:168:18
  13:        0x100bae488 - rust_begin_unwind
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:665:5
  14:        0x100bd51f4 - core::panicking::panic_fmt::ha4b80a05b9fff47a
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/panicking.rs:74:14
  15:        0x100bd55d8 - core::result::unwrap_failed::h441932a0bca0dd7f
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/result.rs:1679:5
  16:        0x100781764 - core::result::Result<T,E>::unwrap::h6ff0976ec032a697
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/result.rs:1102:23
  17:        0x100781764 - my_app::main::{{closure}}::h0591d03477f74f5f
                               at /Users/aus/proj/inspire/my_project/my_app/src/main.rs:16:5
  18:        0x100784898 - tokio::runtime::park::CachedParkThread::block_on::{{closure}}::h3b0c545bc8aa655b
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/park.rs:281:63
  19:        0x100783d40 - tokio::runtime::coop::with_budget::h288866ac9ff4acff
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/coop.rs:107:5
  20:        0x100783d40 - tokio::runtime::coop::budget::h6cd2d5e219202333
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/coop.rs:73:5
  21:        0x100783d40 - tokio::runtime::park::CachedParkThread::block_on::h292f895722ad1ed5
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/park.rs:281:31
  22:        0x100785e8c - tokio::runtime::context::blocking::BlockingRegionGuard::block_on::h3b49234cef273c56
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/context/blocking.rs:66:9
  23:        0x10078a3dc - tokio::runtime::scheduler::multi_thread::MultiThread::block_on::{{closure}}::h42628e444668ec64
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/scheduler/multi_thread/mod.rs:87:13
  24:        0x10078980c - tokio::runtime::context::runtime::enter_runtime::hc2f965e4189be48e
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/context/runtime.rs:65:16
  25:        0x10078a340 - tokio::runtime::scheduler::multi_thread::MultiThread::block_on::h4abb5c0ef80c7d9d
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/scheduler/multi_thread/mod.rs:86:9
  26:        0x10078aa34 - tokio::runtime::runtime::Runtime::block_on_inner::h02fdff220fff1fc9
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/runtime.rs:363:45
  27:        0x10078ac34 - tokio::runtime::runtime::Runtime::block_on::h77f5e9918975bc7d
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/runtime.rs:335:13
  28:        0x100789224 - my_app::main::h79acd247a32377e2
                               at /Users/aus/proj/inspire/my_project/my_app/src/main.rs:16:5
  29:        0x1007822a4 - core::ops::function::FnOnce::call_once::ha1ee6f354ea84431
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/ops/function.rs:250:5
  30:        0x100789380 - std::sys::backtrace::__rust_begin_short_backtrace::hd597aeb17669f98e
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sys/backtrace.rs:152:18
  31:        0x100785d88 - std::rt::lang_start::{{closure}}::hd4b959f0dbb4298f
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/rt.rs:162:18
  32:        0x100ba7aa0 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h4f74490c6170ea16
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/ops/function.rs:284:13
  33:        0x100ba7aa0 - std::panicking::try::do_call::h2f36d2f1f1af8d28
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:557:40
  34:        0x100ba7aa0 - std::panicking::try::ha6af9029a7d93c94
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:521:19
  35:        0x100ba7aa0 - std::panic::catch_unwind::ha4f738ae2ba7c3a4
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panic.rs:350:14
  36:        0x100ba7aa0 - std::rt::lang_start_internal::{{closure}}::hf216622dc2c733e3
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/rt.rs:141:48
  37:        0x100ba7aa0 - std::panicking::try::do_call::haa691957db1dd55f
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:557:40
  38:        0x100ba7aa0 - std::panicking::try::ha0c1a49b9fabc98e
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:521:19
  39:        0x100ba7aa0 - std::panic::catch_unwind::h68ad032c646bb0ab
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panic.rs:350:14
  40:        0x100ba7aa0 - std::rt::lang_start_internal::hdd117cb81a316264
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/rt.rs:141:20
  41:        0x100785d54 - std::rt::lang_start::hd2864ca01fae269f
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/rt.rs:161:17
  42:        0x1007892ac - _main

Using native-tls:

Connected to Clickhouse
thread 'main' panicked at my_app/src/main.rs:16:21:
called `Result::unwrap()` on an `Err` value: Network(hyper_util::client::legacy::Error(Connect, Error { code: -67843, message: "The certificate was not trusted." }))
stack backtrace:
   0:        0x100c24904 - std::backtrace_rs::backtrace::libunwind::trace::hbebc8679d47bdc2c
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/../../backtrace/src/backtrace/libunwind.rs:116:5
   1:        0x100c24904 - std::backtrace_rs::backtrace::trace_unsynchronized::h3a2e9637943241aa
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:        0x100c24904 - std::sys::backtrace::_print_fmt::he430849680584674
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sys/backtrace.rs:65:5
   3:        0x100c24904 - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h243268f17d714c7f
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sys/backtrace.rs:40:26
   4:        0x100c3b848 - core::fmt::rt::Argument::fmt::h0d339881c25f3c31
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/fmt/rt.rs:173:76
   5:        0x100c3b848 - core::fmt::write::hb3cfb8a30e72d7ff
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/fmt/mod.rs:1182:21
   6:        0x100c22260 - std::io::Write::write_fmt::hfb2314975de9ecf1
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/io/mod.rs:1827:15
   7:        0x100c259e0 - std::sys::backtrace::BacktraceLock::print::he14461129ccbfef5
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sys/backtrace.rs:43:9
   8:        0x100c259e0 - std::panicking::default_hook::{{closure}}::h14c7718ccf39d316
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:269:22
   9:        0x100c25604 - std::panicking::default_hook::hc62e60da3be2f352
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:296:9
  10:        0x100c264a4 - std::panicking::rust_panic_with_hook::h09e8a656f11e82b2
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:800:13
  11:        0x100c25df4 - std::panicking::begin_panic_handler::{{closure}}::h1230eb3cc91b241c
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:674:13
  12:        0x100c24d90 - std::sys::backtrace::__rust_end_short_backtrace::hc3491307aceda2c2
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sys/backtrace.rs:168:18
  13:        0x100c25abc - rust_begin_unwind
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:665:5
  14:        0x100c4b524 - core::panicking::panic_fmt::ha4b80a05b9fff47a
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/panicking.rs:74:14
  15:        0x100c4b908 - core::result::unwrap_failed::h441932a0bca0dd7f
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/result.rs:1679:5
  16:        0x1009ec364 - core::result::Result<T,E>::unwrap::h22217017fa87c4d4
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/result.rs:1102:23
  17:        0x1009ec364 - my_app::main::{{closure}}::h8b823f154ecf3835
                               at /Users/aus/proj/inspire/my_project/my_app/src/main.rs:16:5
  18:        0x1009eaee4 - tokio::runtime::park::CachedParkThread::block_on::{{closure}}::h43e619f60a3ca2ff
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/park.rs:281:63
  19:        0x1009eaa08 - tokio::runtime::coop::with_budget::h8820af725725b2af
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/coop.rs:107:5
  20:        0x1009eaa08 - tokio::runtime::coop::budget::h61b9cbfec44a626e
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/coop.rs:73:5
  21:        0x1009eaa08 - tokio::runtime::park::CachedParkThread::block_on::h53f1a25d4c76cd34
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/park.rs:281:31
  22:        0x1009edf90 - tokio::runtime::context::blocking::BlockingRegionGuard::block_on::h6e6f37cccc8578bd
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/context/blocking.rs:66:9
  23:        0x1009e49a4 - tokio::runtime::scheduler::multi_thread::MultiThread::block_on::{{closure}}::ha56105e9a7bef4f9
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/scheduler/multi_thread/mod.rs:87:13
  24:        0x1009e9814 - tokio::runtime::context::runtime::enter_runtime::h583628e8c611fefc
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/context/runtime.rs:65:16
  25:        0x1009e48b4 - tokio::runtime::scheduler::multi_thread::MultiThread::block_on::h7d1e0e7c761ee0b8
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/scheduler/multi_thread/mod.rs:86:9
  26:        0x1009e4bc4 - tokio::runtime::runtime::Runtime::block_on_inner::hd6eb13cb0c61522b
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/runtime.rs:363:45
  27:        0x1009e4dc4 - tokio::runtime::runtime::Runtime::block_on::hba5b2a9d09350998
                               at /Users/aus/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.40.0/src/runtime/runtime.rs:335:13
  28:        0x1009ee0c4 - my_app::main::hd2a86a4102b20faa
                               at /Users/aus/proj/inspire/my_project/my_app/src/main.rs:16:5
  29:        0x1009e4f58 - core::ops::function::FnOnce::call_once::h3045808816eb5fa6
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/ops/function.rs:250:5
  30:        0x1009e4ea8 - std::sys::backtrace::__rust_begin_short_backtrace::he6ff5e28d8d705ad
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/sys/backtrace.rs:152:18
  31:        0x1009e867c - std::rt::lang_start::{{closure}}::h8107bfb275e2833f
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/rt.rs:162:18
  32:        0x100c1f150 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h4f74490c6170ea16
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/core/src/ops/function.rs:284:13
  33:        0x100c1f150 - std::panicking::try::do_call::h2f36d2f1f1af8d28
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:557:40
  34:        0x100c1f150 - std::panicking::try::ha6af9029a7d93c94
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:521:19
  35:        0x100c1f150 - std::panic::catch_unwind::ha4f738ae2ba7c3a4
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panic.rs:350:14
  36:        0x100c1f150 - std::rt::lang_start_internal::{{closure}}::hf216622dc2c733e3
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/rt.rs:141:48
  37:        0x100c1f150 - std::panicking::try::do_call::haa691957db1dd55f
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:557:40
  38:        0x100c1f150 - std::panicking::try::ha0c1a49b9fabc98e
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panicking.rs:521:19
  39:        0x100c1f150 - std::panic::catch_unwind::h68ad032c646bb0ab
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/panic.rs:350:14
  40:        0x100c1f150 - std::rt::lang_start_internal::hdd117cb81a316264
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/rt.rs:141:20
  41:        0x1009e8648 - std::rt::lang_start::hc675e20d47d9c096
                               at /rustc/eeb90cda1969383f56a2637cbd3037bdf598841c/library/std/src/rt.rs:161:17
  42:        0x1009ee14c - _main

Configuration

Environment

ClickHouse server

loyd commented 1 month ago

I couldn't find an option to turn of server certificate validation or provide the custom CA

You should be able to use native-tls or rustls-tls+rustls-tls-native-roots and install your custom certificate into your OS storage (I don't use macOS, so I cannot help here, sorry).

If you're absolutely sure you want to provide certs directly in the application (for testing, because it's dangerous for production), you can create a custom HTTP client and provide it to Client::with_http_client() (a good start here is the default impl).


We can implement a more straightforward way to provide certs of custom CA, but it's definitely a feature request, not a bug cc @slvrtrn

ausrasul commented 1 month ago

Thanks Loyd, I wanted an option during development like dangerously disable certificate validation.

But even in rustls, I started to get the notion that disabling verification is removed and discouraged. Even during development. So I won't ask for it :)

I opted to toggle to http during dev. Installing the server's CA on the OS or in a custom client isn't practical/portable in our environment but it's good to know.

loyd commented 1 month ago

disabling verification is removed and discouraged

Yep, so I was talking about providing a custom certificate, not disabling verification.

Anyway, reqwest provides a method to add a custom certificate, I think we can do the same

isn't practical/portable in our environment

Would you like to provide more details here?

ausrasul commented 1 month ago

Yes I checked reqwest, I could put the effort to implement clickhouse HttpClient. But it would be nice to have in the default client.

Currently we're doing a proof of concept, the cluster is created with docker-compose. A script takes number of shards, replicas and cluster name and generats server's configs, CA, and a docker-compose file.

So I start with clean slate cluster every time I want to try something new. This is done on a remote machine so I don't have direct access to the CA file. Additional reason for this is that the whole project can be replicated on a colleague's env without manual steps.

However I can change this and commit the test CA so it stays the same. Then I can add it in a custom client if env = dev. But this as bad as (may be less) disabling verification, only more verbose.

How would you go about it?