skip to Main Content

So I’m applying my certificates to my server, but a runtime error is occurring:

thread 'tokio-runtime-worker' panicked at /home/ubuntu/.cargo/registry/src/index.crates.io-6f17d22bba15001f/warp-0.3.7/src/server.rs:550:27:
error binding to 0.0.0.0:443: Identity PEM is missing a private key such as RSA, ECC or PKCS8
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Below is my code:

    let routes = warp::any().map(|| "Hello, World!");

    // Load SSL keys and certs
        let cert_path = "/etc/letsencrypt/live/merivilla.com/cert.pem";
        let key_path = "/etc/letsencrypt/live/merivilla.com/privkey.pem";


    //start warp server
        warp::serve(routes)
        .tls()
        .cert(cert_path)
        .key(key_path)
        .run(([0, 0, 0, 0], 443))
        .await;

I’m using WARP version 0.3.7:
Cargo.toml:

warp = {version = "0.3", features = ["tls"]}

I tried using the fullchain version instead of cert.pem.
I tried using the chain version instead of cert.pem.
The cert was obtained only a couple of months ago, so the age shouldn’t be the issue.

I’m running it using Linux Ubuntu 22 on the command line using sudo, so there shouldn’t be any issues when it comes to permissions.

Can someone explain what the error means by "identity pem?" Should I be looking for a different version of my cert?

2

Answers


  1. Chosen as BEST ANSWER

    The correct way to set the warp server up was:

    warp::serve(routes)
    .tls()
    .cert_path(cert_path)
    .key_path(key_path)
    .run(([0, 0, 0, 0], 443))
    .await;
    

    ... With the original certificate and key. Though, the other key configuration the other answer recommended did also work. I do want to thank him for all his help in figuring this out. I ended up adding many logs to figure out at what point was the user getting stuck when trying to connect so I changed my routes to:

            let routes = 
                warp::any()
                        .and_then(handle_request)
                        .recover(handle_rejection);
    

    and added these functions to handle the requests and rejections:

    async fn handle_rejection(err: warp::Rejection) -> Result<impl warp::Reply, std::convert::Infallible> {
        log::error!("Request was rejected: {:?}", err);
        Ok(warp::reply::with_status("Internal Server Error", warp::http::StatusCode::INTERNAL_SERVER_ERROR))
    }
    async fn handle_request() -> Result<impl warp::Reply, warp::Rejection> {
        log::info!("Received a request");
        Ok("Hello, World!")
    }
    

    Anyways, after I did this, the only log that was showing up was the one that I put above the lines of code of warp::serve... that said starting up server.

    So it got me thinking, if the request itself is not getting through, let alone a rejection, that must mean there is something wrong server-side that isn't allowing the request to come through. So I looked at my security group and one of the rules was: "Direction: Ingress/Egress Ether Type: IPv4/IPv6 IP Protocol: Any, Protocol/Port: Any". So I thought, well, I'll just add a rule allowing HTTPS to come through, just in case, and well it worked.

    TLDR: the issue was I didn't have a rule on my Security Group allowing Ingress/Egress on HTTPS.


  2. The key file you are using is probably in a format incompatible with the HTTPS protocol. As the error message says:

    Identity PEM is missing a private key such as RSA, ECC or PKCS8
    

    You need to convert your key file to one of these formats. Here’s an openssl command to convert your key to PKCS8.

    openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in pkcs1.key -out pkcs8.key
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search