GRPC client connectivity problem (tls/cert issue)

I'm trying to connect a gRPC client written in Rust to a certain service, which is also written in Rust.
This service is running on Kubernetes, and its ingress is controlled by Nginx. The service is accessible via HTTPS (on the default port 443). I'm trying to configure the communication channel in various ways so that the client can connect to the service, but I keep getting the error as below:

Error: tonic::transport::Error(Transport, hyper::Error(Connect, Custom { kind: InvalidData, error: InvalidCertificate(UnknownIssuer) }))

I've tried pointing to various certificates that should be trusted, but it changes nothing. The dynamic certificate received by the ingress controller (based on Nginx) is issued by Let's Encrypt. It is a wildcard certificate, and the HTTPS connection is made based on it. I can connect to this service without any problem, for example, from code written in .NET; however, in Rust, this is a challenge (probably to make things not too simple or too normal as in other programming languages). Of course, there is no possibility to directly use configurations from rustls::ClientConfig, which would make things much easier (as in the code below):

    // Add  root certificates to the root store
    let mut root_store = rustls::RootCertStore::empty();
    root_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned());

    // Create a TLS config
    let tls_config = rustls::ClientConfig::builder()
        .with_root_certificates(root_store) // .with_native_roots()?
        .with_no_client_auth();

Below is the code I've tried to use to force the client to connect to the service.
This can't be that difficult! I must be making a mistake somewhere.

When I dump the certificate data, it is as follows (retrieved using openssl):

subject=CN = *.my-service.eu
issuer=C = US, O = Let's Encrypt, CN = R3


Does anyone know any working method to configure the client to connect to a service
running on TLS (HTTPS)?



    let service_cert_str =      r#"-----BEGIN CERTIFICATE---...ThanQ==-----END CERTIFICATE-----"#;
    let lets_encrypt_cert_str = r#"-----BEGIN CERTIFICATE-----MIIF...oq7hHwg==-----END CERTIFICATE-----"#;
    let isrg_root_cert_str =    r#"-----BEGIN CERTIFICATE-----MIIFa...reGCc=-----END CERTIFICATE-----"#;
    
    // let pem = pem::parse(service_cert_str)?;
    let pem = pem::parse(lets_encrypt_cert_str)?;
    // let pem = pem::parse(isrg_root_cert_str)?;
    
    let ca_certificate = Certificate::from_pem(pem.contents());

    let tls_config = ClientTlsConfig::new()
        .ca_certificate(ca_certificate)
        .domain_name("some.my-service.eu");

    let channel = tonic::transport::channel::Channel::from_static("https://some.my-service.eu")
        .tls_config(tls_config)?
        //.tls_config(Default::default())?
        .connect()
        .await?;

    let mut client = SomeMyServiceClient::with_interceptor(channel, move |mut req: Request<()>| {
            req.metadata_mut().insert("authorization", token.clone());
            Ok(req)
        })
        .send_compressed(CompressionEncoding::Gzip)
        .accept_compressed(CompressionEncoding::Gzip);

1 Like

Does anyone have a similar issue?

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.