Skip to content

Some TLS handshake failed #163

@linlinjinzhen

Description

@linlinjinzhen

I tested my service using this website: https://myssl.com/
log:
[101.89.87.44:5388] TLS handshake failed: tls handshake eof
[101.89.87.44:5390] TLS handshake failed: tls handshake eof
[101.89.87.44:5392] TLS handshake failed: tls handshake eof
[101.89.87.44:5393] TLS handshake failed: Connection reset by peer (os error 104)
[101.89.87.44:5395] TLS handshake failed: tls handshake eof
[101.89.87.44:5394] TLS handshake failed: tls handshake eof
[101.89.87.44:5398] TLS handshake failed: received corrupt message of type InvalidContentType
[101.89.87.44:5396] TLS handshake failed: Connection reset by peer (os error 104)
[101.89.87.44:5397] TLS handshake failed: tls handshake eof
[101.89.87.44:5401] TLS handshake failed: peer is incompatible: NoCipherSuitesInCommon
[101.89.87.44:5402] TLS handshake failed: peer is incompatible: NoCipherSuitesInCommon
[101.89.87.44:5403] TLS handshake failed: peer is incompatible: Tls12NotOffered
[101.89.87.44:5400] TLS handshake failed: tls handshake eof
[101.89.87.44:5408] TLS handshake failed: peer is incompatible: Tls12NotOffered
[101.89.87.44:5404] TLS handshake failed: received corrupt message of type InvalidContentType
[101.89.87.44:5406] TLS handshake failed: Connection reset by peer (os error 104)
[101.89.87.44:5405] TLS handshake failed: Connection reset by peer (os error 104)
code is :

 use anyhow::Result;
  use hyper::{body::Incoming as IncomingBody, Request, Response};
  use hyper::service::service_fn;
  use rustls::ServerConfig;
  use rustls_pemfile::{certs, private_key};
  use std::fs::File;
  use std::io::BufReader;
  use std::net::SocketAddr;
  use std::sync::Arc;
  use tokio::net::TcpListener;
  use tokio_rustls::TlsAcceptor;

// Load TLS certificates
fn load_certs(path: &str) -> Result<Vec<rustls::pki_types::CertificateDer<'static>>> {
    let file = File::open(path)?;
    let mut reader = BufReader::new(file);
    
    // Use collect to convert iterator to Vec<Result<...>>
    let certs_result: Result<Vec<_>, _> = certs(&mut reader).collect();
    let certs = certs_result.map_err(|e| anyhow::anyhow!("Failed to load certificates: {}", e))?;
    
    Ok(certs)
}

// Load TLS private key
fn load_private_key(path: &str) -> Result<rustls::pki_types::PrivateKeyDer<'static>> {
    let file = File::open(path)?;
    let mut reader = BufReader::new(file);
    
    // Use private_key function instead of pkcs8_private_keys
    let key = private_key(&mut reader)
        .map_err(|e| anyhow::anyhow!("Failed to load private key: {}", e))?
        .ok_or_else(|| anyhow::anyhow!("Private key not found"))?;
    
    Ok(key)
}

// Handle HTTP requests
async fn handle_request(_req: Request<IncomingBody>) -> Result<Response<String>, hyper::Error> {
    Ok(Response::new("Hello, HTTPS World with Latest Deps!".to_string()))
}

#[tokio::main]
async fn main() -> Result<()> {
    // --- 1. Generate self-signed certificate (for development) ---
    // openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

    // --- 2. Load TLS configuration ---
    let certs = load_certs("certs/cert.pem")?;
    let key = load_private_key("certs/key.pem")?;
    
    // Rustls 0.22+ config construction
    let tls_config = ServerConfig::builder()
        .with_no_client_auth()
        .with_single_cert(certs, key)
        .map_err(|e| anyhow::anyhow!("TLS configuration failed: {}", e))?;
    
    let tls_acceptor = TlsAcceptor::from(Arc::new(tls_config));

    // --- 3. Bind to port 443 (requires root privileges) ---
    let addr: SocketAddr = ([0, 0, 0, 0], 443).into();
    let listener = TcpListener::bind(addr).await?;
    println!("HTTPS server started: https://{}", addr);

    // --- 4. Accept connections in a loop (Hyper 1.x new API) ---
    loop {
        let (tcp_stream, peer_addr) = listener.accept().await?;
        let tls_acceptor = tls_acceptor.clone();

        tokio::spawn(async move {
            // TLS handshake
            let tls_stream = match tls_acceptor.accept(tcp_stream).await {
                Ok(stream) => stream,
                Err(e) => {
                    eprintln!("[{}] TLS handshake failed: {}", peer_addr, e);
                    return;
                }
            };

            // Use hyper_util's TokioIo
            // Ensure Cargo.toml has: hyper-util = { version = "0.1", features = ["tokio"] }
            use hyper_util::rt::tokio::TokioIo;
            let io = TokioIo::new(tls_stream);
            
            // Serve the connection
            if let Err(e) = hyper::server::conn::http1::Builder::new()
                .serve_connection(io, service_fn(handle_request))
                .await
            {
                eprintln!("[{}] Connection handling error: {}", peer_addr, e);
            }
        });
    }
}

toml is:

[package]
name = "hyper-rustls-demo"
version = "0.1.0"
edition = "2024"

[dependencies]
anyhow = "1.0.102"
hyper = { version = "1.8.1", features = ["full"] }
rustls = "0.23.37"
rustls-pemfile = "2.2.0"
tokio = { version = "1.50.0", features = ["full"] }
tokio-rustls = "0.26.4"
hyper-util={version = "0.1.20" , features = ["tokio"]}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions