.bind_rustls() 443 次 out/does 未在 public ip 上服务(使用 certbot 证书)
.bind_rustls() on 443 times out/does not serve on public ip (using a certbot certificate)
tl;博士:我的网站在使用 https 的以太本地主机上成功提供服务,或者使用 http 提供 domain/ip,但使用 https 不提供 domain/ip。代码在底部。
我在我的注册商中有 @
(gremy.co.uk) 和 www
的 A
记录,当托管在 http 上时它会正确解析(例如 .bind("0.0.0.0:80")
)
我已经使用 certbot certonly --standalone
为 gremy.co.uk
和 www.gremy.co.uk
生成了证书,并将 rustls::ServerConfig
指向 fullchain.pem
和 privkey.pem
文件。
当运行 .bind("0.0.0.0:80")
我可以按预期成功访问我的网站。更改为 .bind_rustls("0.0.0.0:443", config)?
会使 https://gremy.co.uk
和指向它的 ip 超时(“服务器响应时间太长。”)。控制台不记录任何内容,未尝试连接。转到 localhost 时尝试连接,服务器记录 BadCertificate
错误(这很公平,因为我有 gremy.co.uk 而不是 localhost 的证书)
我能够 运行 mkcert 为本地主机生成一个自签名证书,并且按预期连接并且工作正常。
所以我似乎可以通过 https 在本地主机上为我的网站提供服务,但不能在我服务器的实际 public ip/domain 上提供服务。我的 actix-web 配置可能缺少某些东西吗?
代码:
use rustls::internal::pemfile::{certs, pkcs8_private_keys};
use actix_web::middleware::Logger;
use anyhow::Context;
use actix_web::{middleware::Logger, get, http, web, App, HttpRequest, HttpResponse, HttpServer, http::ContentEncoding, middleware::*};
use actix_cors::Cors;
use actix_files::{Files, NamedFile};
#[actix::main]
async fn main() -> anyhow::Result<()> {
let mut config = rustls::ServerConfig::new(rustls::NoClientAuth::new());
let cert_file = &mut std::io::BufReader::new(std::fs::File::open(&CONFIG.ssl.cert)?);
let key_file = &mut std::io::BufReader::new(std::fs::File::open(&CONFIG.ssl.key)?);
let cert_chain = certs(cert_file).ok().context("no certs")?;
let mut keys = pkcs8_private_keys(key_file).ok().context("no private keys")?;
config.set_single_cert(cert_chain, keys.remove(0))?;
Ok(HttpServer::new(|| {
App::new()
.wrap(Logger::new("%s in %Ts, %b bytes \"%r\""))
.wrap(NormalizePath::default())
.wrap(Cors::permissive()) // seems to be necessary for chrome?
.service(actix_files::Files::new("/public", "public"))
.default_service(web::route().to(reply))
})
// .bind("0.0.0.0:80")? // just works
.bind_rustls("0.0.0.0:443", config)? // just doesn't
.run().await?)
}
fn reply() -> web::HttpResponse {
static REPLY: Lazy<String> = Lazy::new(|| {
let js = minifier::js::minify(&std::fs::read_to_string("public/wasm/client.js").expect("couldn't find the js payload"));
minify::html::minify(&format!(
include_str!("../response.html"),
js = js,
// or localhost/http as appropriate
path = "https://gremy.co.uk/public/wasm/client_bg.wasm",
))
});
web::HttpResponse::Ok().body(&REPLY as &str)
}
有趣的是,如果您要托管服务器,您仍然需要转发默认端口,例如 443。
在路由器中转发 443 之后,为了以防万一,通过 windows 防火墙打开 443,我现在可以通过我的 public ip 在 https 上提供服务。
tl;博士:我的网站在使用 https 的以太本地主机上成功提供服务,或者使用 http 提供 domain/ip,但使用 https 不提供 domain/ip。代码在底部。
我在我的注册商中有 @
(gremy.co.uk) 和 www
的 A
记录,当托管在 http 上时它会正确解析(例如 .bind("0.0.0.0:80")
)
我已经使用 certbot certonly --standalone
为 gremy.co.uk
和 www.gremy.co.uk
生成了证书,并将 rustls::ServerConfig
指向 fullchain.pem
和 privkey.pem
文件。
当运行 .bind("0.0.0.0:80")
我可以按预期成功访问我的网站。更改为 .bind_rustls("0.0.0.0:443", config)?
会使 https://gremy.co.uk
和指向它的 ip 超时(“服务器响应时间太长。”)。控制台不记录任何内容,未尝试连接。转到 localhost 时尝试连接,服务器记录 BadCertificate
错误(这很公平,因为我有 gremy.co.uk 而不是 localhost 的证书)
我能够 运行 mkcert 为本地主机生成一个自签名证书,并且按预期连接并且工作正常。
所以我似乎可以通过 https 在本地主机上为我的网站提供服务,但不能在我服务器的实际 public ip/domain 上提供服务。我的 actix-web 配置可能缺少某些东西吗?
代码:
use rustls::internal::pemfile::{certs, pkcs8_private_keys};
use actix_web::middleware::Logger;
use anyhow::Context;
use actix_web::{middleware::Logger, get, http, web, App, HttpRequest, HttpResponse, HttpServer, http::ContentEncoding, middleware::*};
use actix_cors::Cors;
use actix_files::{Files, NamedFile};
#[actix::main]
async fn main() -> anyhow::Result<()> {
let mut config = rustls::ServerConfig::new(rustls::NoClientAuth::new());
let cert_file = &mut std::io::BufReader::new(std::fs::File::open(&CONFIG.ssl.cert)?);
let key_file = &mut std::io::BufReader::new(std::fs::File::open(&CONFIG.ssl.key)?);
let cert_chain = certs(cert_file).ok().context("no certs")?;
let mut keys = pkcs8_private_keys(key_file).ok().context("no private keys")?;
config.set_single_cert(cert_chain, keys.remove(0))?;
Ok(HttpServer::new(|| {
App::new()
.wrap(Logger::new("%s in %Ts, %b bytes \"%r\""))
.wrap(NormalizePath::default())
.wrap(Cors::permissive()) // seems to be necessary for chrome?
.service(actix_files::Files::new("/public", "public"))
.default_service(web::route().to(reply))
})
// .bind("0.0.0.0:80")? // just works
.bind_rustls("0.0.0.0:443", config)? // just doesn't
.run().await?)
}
fn reply() -> web::HttpResponse {
static REPLY: Lazy<String> = Lazy::new(|| {
let js = minifier::js::minify(&std::fs::read_to_string("public/wasm/client.js").expect("couldn't find the js payload"));
minify::html::minify(&format!(
include_str!("../response.html"),
js = js,
// or localhost/http as appropriate
path = "https://gremy.co.uk/public/wasm/client_bg.wasm",
))
});
web::HttpResponse::Ok().body(&REPLY as &str)
}
有趣的是,如果您要托管服务器,您仍然需要转发默认端口,例如 443。
在路由器中转发 443 之后,为了以防万一,通过 windows 防火墙打开 443,我现在可以通过我的 public ip 在 https 上提供服务。