首页 抖音热门文章正文

Rust Axum:多域名https 443服务器实战

抖音热门 2025年08月16日 00:44 1 admin


Rust Axum:多域名https 443服务器实战


Rust Axum:多域名https 443服务器实战

[package]name = "actixweb443"version = "0.1.0"edition = "2024"[dependencies]actix-web = { version = "4.9", features = ["rustls-0_23"] }rustls = { version = "0.23", features = ["ring"] }tokio-rustls = "0.26"tracing = "0.1"tracing-subscriber = { version = "0.3", features = ["env-filter"] }
use actix_web::{web, App, HttpRequest, HttpResponse, HttpServer};use rustls::{    crypto::ring::{default_provider, sign::any_supported_type},    pki_types::{CertificateDer, PrivateKeyDer},    server::ResolvesServerCert,    sign::CertifiedKey,    ServerConfig,};use std::{    path::PathBuf,    sync::Arc,};use tokio_rustls::rustls::pki_types::pem::PemObject;use tracing::{info, warn};use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};#[actix_web::main]async fn main() -> std::io::Result<()> {    // Set the default crypto provider to ring    default_provider()        .install_default()        .expect("Failed to install default ring crypto provider");    // Initialize tracing for logging    tracing_subscriber::registry()        .with(            tracing_subscriber::EnvFilter::try_from_default_env()                .unwrap_or_else(|_| "actixweb443=debug".into()),        )        .with(tracing_subscriber::fmt::layer())        .init();    // Create a resolver for multiple certificates    let cert_resolver = Arc::new(MultiDomainCertResolver::new(vec![        (            "www.5a8.com",            PathBuf::from("D:\\wwwroot\\www.5a8.com\\certs\\www.5a8.com-key.pem"),            PathBuf::from("D:\\wwwroot\\www.5a8.com\\certs\\www.5a8.com-cert.pem"),        ),        (            "www.9a8.com",            PathBuf::from("D:\\wwwroot\\www.5a8.com\\certs\\www.9a8.com-key.pem"), // Update if path differs            PathBuf::from("D:\\wwwroot\\www.5a8.com\\certs\\www.9a8.com-cert.pem"), // Update if path differs        ),    ]));    // Configure TLS with rustls    let mut rustls_config = ServerConfig::builder()        .with_no_client_auth()        .with_cert_resolver(cert_resolver);    rustls_config.alpn_protocols = vec![b"h2".to_vec(), b"http/1.1".to_vec()];    // Bind to port 4431 for testing    let bind = "0.0.0.0:4431";    info!("HTTPS server listening on {bind}. To contact: curl -k https://localhost:4431");    // Set up Actix Web server    HttpServer::new(|| {        App::new().route("/", web::get().to(handler))    })    .bind_rustls_0_23(bind, rustls_config)?    .run()    .await}async fn handler(_req: HttpRequest) -> HttpResponse {    info!("Handling request: {:?}", _req);    HttpResponse::Ok().body("Hello, HTTPS with Actix Web!")}// Custom certificate resolver for multiple domains#[derive(Debug)]struct MultiDomainCertResolver {    certs: Vec<(String, Arc<CertifiedKey>)>,}impl MultiDomainCertResolver {    fn new(domains: Vec<(&str, PathBuf, PathBuf)>) -> Self {        let certs = domains            .into_iter()            .map(|(domain, key_path, cert_path)| {                // Load private key                let key = PrivateKeyDer::from_pem_file(&key_path)                    .expect(&format!("Failed to read private key for {}", domain));                // Load certificates                let certs = CertificateDer::pem_file_iter(&cert_path)                    .expect(&format!("Failed to read certificate for {}", domain))                    .map(|cert| cert.expect(&format!("Invalid certificate format for {}", domain)))                    .collect::<Vec<_>>();                let signing_key = any_supported_type(&key)                    .expect(&format!("Failed to create signing key for {}", domain));                let certified_key = CertifiedKey::new(certs, signing_key);                (domain.to_string(), Arc::new(certified_key))            })            .collect();        MultiDomainCertResolver { certs }    }}impl ResolvesServerCert for MultiDomainCertResolver {    fn resolve(        &self,        client_hello: rustls::server::ClientHello,    ) -> Option<Arc<CertifiedKey>> {        let server_name = client_hello.server_name().map(|s| s.to_string());        info!("Received SNI: {:?}", server_name);        server_name.clone().and_then(|name| {            self.certs                .iter()                .find(|(domain, _)| domain == &name)                .map(|(_, cert)| cert.clone())        })        .or_else(|| {            warn!("No certificate found for SNI: {:?}", server_name);            None        })    }}

发表评论

泰日号Copyright Your WebSite.Some Rights Reserved. 网站地图 备案号:川ICP备66666666号 Z-BlogPHP强力驱动