kube icon indicating copy to clipboard operation
kube copied to clipboard

https socks http connector and rustls now working

Open Masber opened this issue 2 years ago • 3 comments

Current and expected behavior

Background.:

I am trying to upgrade my kube-rs crate to latest version, for this I need to update from native-tls to rustls

Current behavior:

I am getting an error when trying to build a client based on https<socks> connector, I am not sure why, but I got this working with native tls.

This works:

        let connector = {
            let mut http = hyper::client::HttpConnector::new();
            http.enforce_http(false);
            let proxy = hyper_socks2::SocksConnector {
                proxy_addr: std::env::var("SOCKS5").unwrap().parse::<Uri>().unwrap(),
                auth: None,
                connector: http,
            };
            let mut native_tls_builder = native_tls::TlsConnector::builder();
            native_tls_builder.danger_accept_invalid_certs(true);
            native_tls_builder.danger_accept_invalid_hostnames(true);
            native_tls_builder.use_sni(false);

            let tls = tokio_native_tls::TlsConnector::from(config.native_tls_connector()?);
            hyper_tls::HttpsConnector::from((proxy, tls))
        };

        let service = tower::ServiceBuilder::new()
            .layer(config.base_uri_layer())
            .option_layer(config.auth_layer()?)
            .service(hyper::Client::builder().build(connector));

        kube::Client::new(service, config.default_namespace)

This does not work:

        let rustls_config = std::sync::Arc::new(config.rustls_client_config()?);
        let mut http_connector = hyper::client::HttpConnector::new();
        http_connector.enforce_http(false);
        let socks_http_connector = SocksConnector {
            proxy_addr: std::env::var("SOCKS5").unwrap().parse::<Uri>().unwrap(), // scheme is required by HttpConnector
            auth: None,
            connector: http_connector.clone(),
        };
        let https_socks_http_connector = hyper_rustls::HttpsConnector::from((socks_http_connector.clone(), rustls_config.clone()));
        let service = tower::ServiceBuilder::new()
            .layer(config.base_uri_layer())
            .service(hyper::Client::builder().build(https_socks_http_connector));
        kube::Client::new(service, config.default_namespace)

Expected behavior:

I would expect the code above to work and successfully create a connection to a kubeAPI through socks and https

Possible solution

I don't know of a possible solution, I am writing this because I am adopting one of your examples https://github.com/kube-rs/kube/blob/main/examples/custom_client_tls.rs and so far I have been unsuccessful

Additional context

No response

Environment

I build the kubeconfig dynamically/programatically I am using vanilla k8s

Configuration and features

k8s-openapi v0.15.0
├── kube v0.74.0
│   └── mesa v0.6.15 (/home/msopena/polybox/Documents/tests/rust/mesa)
├── kube-client v0.74.0
│   ├── kube v0.74.0 (*)
│   └── kube-runtime v0.74.0
│       └── kube v0.74.0 (*)
├── kube-core v0.74.0
│   ├── kube v0.74.0 (*)
│   └── kube-client v0.74.0 (*)
├── kube-runtime v0.74.0 (*)
└── mesa v0.6.15 (/home/msopena/polybox/Documents/tests/rust/mesa)

and

❯ cat Cargo.toml | grep hyper-rustls
hyper-rustls = "0.23.0"

Affected crates

kube-client

Would you like to work on fixing this bug?

maybe

Masber avatar Jul 02 '23 10:07 Masber

for clarification, the problem here is that it works with native-tls but not rustls, right?

some things that might get you on track);

clux avatar Jul 02 '23 11:07 clux

  • he problem here is that it works with native-tls but not rustls, right? Correct
  • have you tried using the helpers from ConfigExt like rustls_https_connector_with_connector? My understanding is I need to create a HttpsConnector<SocksConnector<HttpConnector>> and rustls_https_connector_with_connector return a HttpsConnector<HttpConnector> ... I just tried creating a SocksConnector<HttpsConnector<HttpConnector>> like:
        log::debug!("SOCKS5 enabled");
        let https_http_connector = config.rustls_https_connector()?;
        let mut http_connector = hyper::client::HttpConnector::new();
        http_connector.enforce_http(false);
        let socks_https_http_connector = SocksConnector {
            proxy_addr: std::env::var("SOCKS5").unwrap().parse::<Uri>().unwrap(), // scheme is required by HttpConnector
            auth: None,
            connector: https_http_connector.clone(),
        };

        let https_socks_http_connector_2 = socks_https_http_connector.clone().with_tls()?;

        let service = tower::ServiceBuilder::new()
            .layer(config.base_uri_layer())
            .service(hyper::Client::builder().build(https_socks_http_connector_2));
        kube::Client::new(service, config.default_namespace)

but still does not work, it complains about:

Err(
    HyperError(
        hyper::Error(
            Connect,
            Connector(
                Custom {
                    kind: Other,
                    error: "Unsupported scheme socks5h",
                },
            ),
        ),
    ),
)
  • is it intentional you're not using the auth_layer for rustls? I was hoping this let https_socks_http_connector = hyper_rustls::HttpsConnector::from((socks_http_connector.clone(), rustls_config.clone())); would configure the certificates part on my behalf using the information injected from kubeconfig...

Masber avatar Jul 02 '23 13:07 Masber

The reason I need a socks5 connector is that my k8s is too old and does not support the proxy settings...

Masber avatar Jul 03 '23 17:07 Masber