docker Rust Actix TLS错误->流错误:请求解析错误:提供的标题无效

hiz5n14c  于 2023-10-16  发布在  Docker
关注(0)|答案(1)|浏览(103)

我尝试做一个Rust Actix TLS Web服务器。
项目布局

.
├── .env
├── Cargo.lock
├── Cargo.toml
├── certs
│   ├── cert.pem
│   └── key.pem
└── src
    ├── api_error.rs
    ├── handlers.rs
    └── main.rs

.env

RUST_LOG=debug
PORT=443
CERTIFICATE_PATH=certs/cert.pem
PRIVATE_KEY_PATH=certs/key.pem

Cargo.toml

[package]
name = "https-test"
version = "0.1.0"
edition = "2021"

[dependencies]
actix-web = { version = "4.3.1", features = ["openssl"] }
openssl = { version = "0.10.54", features = ["v110"], optional = true }
anyhow = "1.0.72"
log = "0.4.19"
env_logger = "0.10.0"
dotenvy = "0.15.7"

main.rs

mod api_error;
mod handlers;

use anyhow::{anyhow, Result};
use log::info;

#[actix_web::main]
async fn main() -> Result<()> {
    dotenvy::dotenv()?;
    env_logger::init();
    info!("Starting server");

    let port = std::env::var("PORT")?.parse::<u16>()?;

    let server = actix_web::HttpServer::new(|| {
        actix_web::App::new()
            .wrap(actix_web::middleware::Logger::default())
            .service(actix_web::web::scope("/api/v1").configure(handlers::config_app))
    });

    let server = server.bind_openssl(("0.0.0.0", port), {
        info!("Using TLS");
        let mut builder = openssl::ssl::SslAcceptor::mozilla_intermediate(openssl::ssl::SslMethod::tls())
                .unwrap();
        let private_key_path = std::env::var("PRIVATE_KEY_PATH")?;
        let certificate_path = std::env::var("CERTIFICATE_PATH")?;
        builder
            .set_private_key_file(private_key_path, openssl::ssl::SslFiletype::PEM)
            .unwrap();
        builder
            .set_certificate_chain_file(certificate_path)
            .unwrap();
        builder
    })?;

    server.run().await.map_err(|e| anyhow!(e))
}

handlers.rs

use crate::api_error::ApiError;

pub fn config_app(cfg: &mut actix_web::web::ServiceConfig) {
    cfg.service(actix_web::web::resource("/").route(actix_web::web::get().to(index)));
}

async fn index() -> Result<actix_web::HttpResponse, ApiError> {
    log::debug!("Hitting `index`");
    Ok(actix_web::HttpResponse::Ok().body("Hello world !"))
}

注意:证书是使用我生成的CA自签名的。我把根CA放在我系统的可信CA中,这样我就不会每次在浏览器中看到“不可信证书”错误。
当运行服务器时,我得到预期的日志:

$ cargo run --release
[INFO  https-test] Starting server
[INFO  actix_server::builder] starting 10 workers
[INFO  actix_server::server] Actix runtime found; starting in Actix runtime

然后在浏览器上,我转到https://localhost/,我的浏览器无法连接到服务器,在我得到的日志中:

[ERROR actix_http::h1::dispatcher] stream error: request parse error: invalid Header provided
[ERROR actix_http::h1::dispatcher] stream error: request parse error: invalid Header provided
[ERROR actix_http::h1::dispatcher] stream error: request parse error: invalid Header provided
[ERROR actix_http::h1::dispatcher] stream error: request parse error: invalid Header provided
[ERROR actix_http::h1::dispatcher] stream error: request parse error: invalid Header provided
[ERROR actix_http::h1::dispatcher] stream error: request parse error: invalid Header provided
mqkwyuun

mqkwyuun1#

这个问题似乎与HTTP/1.1解析器检测到请求中的无效标头有关。这可能是由于各种原因造成的,例如:

  1. SSL/TLS设置配置错误
    1.不正确的客户端行为(尽管浏览器不太可能发送格式错误的头)
    1.来自某些代理或防火墙的干扰
    让我们探索一些故障排除步骤:

检查SSL/TLS配置

确保您的SSL/TLS证书已正确加载,并且路径正确。仔细检查是否可以使用openssl CLI检查它们:

openssl x509 -in certs/cert.pem -text -noout
openssl rsa -check -in certs/key.pem

配置环境变量

确保CERTIFICATE_PATHPRIVATE_KEY_PATH环境变量正确加载并指向正确的路径。

检查原始HTTP流量

您可以使用像tcpdump或Wireshark这样的工具来捕获客户端和服务器之间的原始数据包。这可以提供关于头文件错误的进一步线索:

sudo tcpdump -i lo0 'port 443' -w capture.pcap

尝试使用其他客户端

请不要使用浏览器,而是尝试使用curl来查看错误是否仍然存在。确保使用-k标志来接受自签名证书。

curl -k https://localhost:443/api/v1/

增加日志详细度

修改您的.env文件或直接将RUST_LOG设置为trace以获取更详细的日志。这可以提供线索,了解请求的哪一部分导致了错误。

无SSL/TLS测试

尝试在没有SSL/TLS的情况下运行服务器,看看问题是否与SSL/TLS或其他东西有关。如果它在没有SSL的情况下工作正常,则可能是您的SSL配置有问题。
让我知道哪一步给你更多的信息,或者如果你有进一步的问题。

相关问题