-
Notifications
You must be signed in to change notification settings - Fork 592
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Connection reset by peer #1297
Comments
Sounds interesting, but I'd need a bunch more information in order to check if there's an issue in rustls. For my understanding: the error looks like it's using native-tls for the client, is it connecting to a rustls server (if you know what TLS stack the server is running)? Ideally, can you give me an example client key and certificate generated using the process you used here? (Make sure not to send me any key material that you're using for things on the internet.) It might also be useful if you can attach a packet capture of the connection. We'd probably need a plaintext capture, so you'll want to set up an |
By TLS stack, I assume you're referring to TLS details "SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256" - obtained via curl. Unfortunately the key material is meant for production. WRT to the SSLKEYLOGFILE, my experience with other libraries & curl indicates it's a feature of the library or tool. I tried setting up |
@dowusu TLS stack means what TLS library is the server using. OpenSSL? Rustls? Something else? Also, it sounds reasonably likely the server is rejecting your connection, possibly because the client certificate being sent is incorrect in some way. Do you have access to the server logs to see if it states any reason for rejecting connections? I notice in your example code that you're reading the key and cert from |
I can safely assume OpenSSL. I don't have access to the server/server logs, it's a third party server. The I ran curl with option -E to test the concatenated files and it works I intended changing |
In case an example domain/URL is what's missing in this thread, I am seeing similar behavior with rustls + reqwest only when hitting I've verified locally and on remote VPS so my guess is it's some wonky servers causing this?
This request succeeds if i change my - reqwest = { version = "0.11.8", default-features=false, features=["rustls-tls"]}
+ reqwest = { version = "0.11.8" } |
I've created a simple reproduction based off the rust cookbook for HTTP/reqwest to show this behavior. All you have to do is swap the https://gist.github.com/jakswa/866778bd6d207a102c3b85153212e102 Here's the piece you change: reqwest = { version = "0.11.8", default-features=false, features=["rustls-tls", "blocking"]}
# succeeds if you change it to:
# reqwest = { version = "0.11.8", features=["blocking"]} |
Thanks for the example, @jakswa ! According to https://www.ssllabs.com/ssltest/analyze.html?d=itsmarta.com, the only "strong" cipher suites offered by that server are: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 But neither of those is supported by rustls: https://docs.rs/rustls/latest/src/rustls/suites.rs.html#125-143 So I suspect The main fix is that the server should implement some of the suggestions from SSL Labs, like removing weak cipher suites and enabling some other strong ones. There are a variety of reasons a server might issue a connection reset, so there's no guarantee that @dowusu's problem is the same, but your example is a good reminder: @dowusu's problem might not be related to client certificates at all, but might just be that the server doesn't support cipher suites (or TLS versions) that overlap with what rustls supports. @dowusu are you able to run your affected site through the SSL Server Test I linked above? Can you share the hostname and port? |
Thank you, I didn't know how to dig as deep as you just did but it makes sense. This server looks to be running a Microsoft IIS version from 2013 馃槱. Consider my mystery solved! |
I think until we hear more from the original poster about the results of testing the affected site w/ SSL labs we can't take any action on this issue. I'm going to close it for now and we can revisit if there is new information. Thanks! |
Sincere apologies, not sure of how I missed the comments. I checked the endpoint using the ssllabs.com, site supports only TLS1.2 with two |
@dowusu Can you share the hostname and port you're testing against? |
api.elevygh.org, default port 443. |
I notice that when I try to reproduce with
The pcap shows the remote peer sending a TCP reset immediately after the client finishes its portion of the handshake. Potentially this is a firewall? It's not sending any TLS level alert or close notification. When I try to send a client certificate (just a random cert from our test infrastructure), I get a HTTP level 400 bad request result:
To me this indicates the issue is with the @dowusu As a next step, could you try using the |
It looks like my {"message":"Bad Request"}Connection closed So when I use the certificate separate, it works fine let buf = fs::read(config.root_cacert)?;
let cacert = reqwest::Certificate::from_pem(&buf)?;
let cert = fs::read(config.client_cert)?;
let key = fs::read(config.client_key)?;
//let id = reqwest::Identity::from_pem(&key)?;
let id = reqwest::Identity::from_pkcs8_pem(&cert, &key)?; However if I combine the certificate as indicated in my initial submission, that's when the error occurs. |
Aha, great. We're narrowing in on the problem then :-)
I think that might be using the native-tls backend? I see from_pkcs8_pem as gated by |
Yeah, with native_tls, however when I combine the cert and use |
@dowusu I think the issue is likely related to the client certificate and key you're combining to give to I was able to set up a Can you speak to how you combined the files? Did you order it private key and then certificate? Are the input files both PEM encoded? Are you using an RSA client certificate/private key, or a different algorithm? |
It feels very suspicious that your client's Certificate message is only 78 bytes. That is really too short to contain a certificate. I would dig into that message to see precisely what it does contain? |
Thank you for the observation, I had to explicitly add let buf = fs::read(config.root_cacert)?;
let cacert = reqwest::Certificate::from_pem(&buf)?;
let key = fs::read(config.client_key)?;
let id = reqwest::Identity::from_pem(&key)?;
let client = reqwest::ClientBuilder::new()
.use_rustls_tls() //- Had to add this line
.default_headers(headers)
.timeout(Duration::from_secs(10))
.add_root_certificate(cacert)
.identity(id)
.build()?; Thank you for the support. |
This really sounds like a bug in request, I recommend filing an issue there. |
Glad you figured it out :-)
+1 - it seems problematic that your desired config ends up dropped on the floor and no client cert is sent. For what it's worth, when I was using use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), reqwest::Error> {
let buf = include_bytes!("../minica.pem").as_slice();
let cacert = reqwest::Certificate::from_pem(&buf)?;
let client_ident_pem = include_bytes!("../combined.pem").as_slice();
let id = reqwest::Identity::from_pem(&client_ident_pem)?;
let client = reqwest::ClientBuilder::new()
.timeout(Duration::from_secs(30))
.add_root_certificate(cacert)
.identity(id)
.build()?;
client.get("https://api.elevygh.org:4443/").send().await?;
Ok(())
} I didn't need to include
Perhaps the bug is specific to having multiple TLS backends enabled? |
Turning off |
To be clear, it still seems like a bug (which would be worth reporting) that you set an |
I'd agree with that. I'm wondering whether this would have been quicker to debug if we had a |
I'm going to work on taking this upstream and will consider the warn! log on our side in parallel. |
After looking closer it turns out there's an existing upstream issue: seanmonstar/reqwest#903 and a proposed fix: seanmonstar/reqwest#1852 edit: I added a comment to 903 and pinged on 1852 to see if there's anything I can do to help land a fix. |
Running a
There's also existing rustls/rustls/src/server/tls12.rs Line 548 in 9330cd7
rustls/rustls/src/server/tls13.rs Line 911 in 9330cd7
Given that we log the |
I mean adding the logging to the client, not the server. |
Ah, I don't think that would have helped in this case because the code path that sends the empty certificate message in |
Ah! Sorry, I misunderstood. I though the |
Hi 馃憢 , so I combined a client key and client certificate with
cat
to be able to use it withrustls
, when I use nativetls with the individual files, it works but when I combine them to use with rustls viareqwest
, below error is generatedsource: hyper::Error(Connect, Ssl(Error { code: ErrorCode(5), cause: Some(Io(Os { code: 104, kind: ConnectionReset, message: "Connection reset by peer" })) }, X509VerifyResult { code: 0, error: "ok" })) })
I tried this on MacOs and Rocky Linux
The text was updated successfully, but these errors were encountered: