mirror of
https://git.asonix.dog/asonix/pict-rs
synced 2024-12-21 10:51:25 +00:00
Enable serving over TLS
This commit is contained in:
parent
0c8d4588a6
commit
50fd3e6182
10 changed files with 280 additions and 54 deletions
119
Cargo.lock
generated
119
Cargo.lock
generated
|
@ -4,11 +4,11 @@ version = 3
|
|||
|
||||
[[package]]
|
||||
name = "actix-codec"
|
||||
version = "0.5.1"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8"
|
||||
checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bitflags 2.4.2",
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
|
@ -44,6 +44,7 @@ dependencies = [
|
|||
"actix-codec",
|
||||
"actix-rt",
|
||||
"actix-service",
|
||||
"actix-tls",
|
||||
"actix-utils",
|
||||
"ahash",
|
||||
"base64 0.21.7",
|
||||
|
@ -53,6 +54,7 @@ dependencies = [
|
|||
"derive_more",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"h2",
|
||||
"http",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
|
@ -146,6 +148,25 @@ dependencies = [
|
|||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "actix-tls"
|
||||
version = "3.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "929e47cc23865cdb856e59673cfba2d28f00b3bbd060dfc80e33a00a3cea8317"
|
||||
dependencies = [
|
||||
"actix-rt",
|
||||
"actix-service",
|
||||
"actix-utils",
|
||||
"futures-core",
|
||||
"impl-more",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tokio-rustls 0.24.1",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
"webpki-roots 0.25.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "actix-utils"
|
||||
version = "3.0.1"
|
||||
|
@ -168,6 +189,7 @@ dependencies = [
|
|||
"actix-rt",
|
||||
"actix-server",
|
||||
"actix-service",
|
||||
"actix-tls",
|
||||
"actix-utils",
|
||||
"ahash",
|
||||
"bytes",
|
||||
|
@ -261,9 +283,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.4"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
|
||||
checksum = "2faccea4cc4ab4a667ce676a30e8ec13922a692c99bb8f5b11f1502c72e04220"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
|
@ -885,9 +907,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
|||
|
||||
[[package]]
|
||||
name = "eyre"
|
||||
version = "0.6.11"
|
||||
version = "0.6.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799"
|
||||
checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec"
|
||||
dependencies = [
|
||||
"indenter",
|
||||
"once_cell",
|
||||
|
@ -1095,7 +1117,7 @@ dependencies = [
|
|||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"indexmap 2.1.0",
|
||||
"indexmap 2.2.1",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
|
@ -1286,6 +1308,12 @@ dependencies = [
|
|||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "impl-more"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d"
|
||||
|
||||
[[package]]
|
||||
name = "indenter"
|
||||
version = "0.3.3"
|
||||
|
@ -1304,9 +1332,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.1.0"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
|
||||
checksum = "433de089bd45971eecf4668ee0ee8f4cec17db4f8bd8f7bc3197a6ce37aa7d9b"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.3",
|
||||
|
@ -1384,9 +1412,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.152"
|
||||
version = "0.2.153"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
|
@ -1620,7 +1648,7 @@ checksum = "1e32339a5dc40459130b3bd269e9892439f55b33e772d2a9d402a789baaf4e8a"
|
|||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"indexmap 2.1.0",
|
||||
"indexmap 2.2.1",
|
||||
"js-sys",
|
||||
"once_cell",
|
||||
"pin-project-lite",
|
||||
|
@ -1838,7 +1866,9 @@ dependencies = [
|
|||
"reqwest",
|
||||
"reqwest-middleware",
|
||||
"reqwest-tracing",
|
||||
"rustls 0.21.10",
|
||||
"rustls 0.22.2",
|
||||
"rustls-channel-resolver",
|
||||
"rustls-pemfile 2.0.0",
|
||||
"rusty-s3",
|
||||
"serde",
|
||||
|
@ -1857,7 +1887,7 @@ dependencies = [
|
|||
"tokio-postgres-rustls",
|
||||
"tokio-uring",
|
||||
"tokio-util",
|
||||
"toml 0.8.8",
|
||||
"toml 0.8.9",
|
||||
"tracing",
|
||||
"tracing-actix-web",
|
||||
"tracing-error",
|
||||
|
@ -1871,18 +1901,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pin-project"
|
||||
version = "1.1.3"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422"
|
||||
checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0"
|
||||
dependencies = [
|
||||
"pin-project-internal",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-internal"
|
||||
version = "1.1.3"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
|
||||
checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2148,7 +2178,7 @@ dependencies = [
|
|||
"time",
|
||||
"tokio",
|
||||
"tokio-postgres",
|
||||
"toml 0.8.8",
|
||||
"toml 0.8.9",
|
||||
"url",
|
||||
"walkdir",
|
||||
]
|
||||
|
@ -2174,7 +2204,7 @@ checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15"
|
|||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata 0.4.4",
|
||||
"regex-automata 0.4.5",
|
||||
"regex-syntax 0.8.2",
|
||||
]
|
||||
|
||||
|
@ -2189,9 +2219,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.4"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b7fa1134405e2ec9353fd416b17f8dacd46c473d7d3fd1cf202706a14eb792a"
|
||||
checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
|
@ -2212,9 +2242,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
|||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.23"
|
||||
version = "0.11.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41"
|
||||
checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"bytes",
|
||||
|
@ -2239,6 +2269,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"system-configuration",
|
||||
"tokio",
|
||||
"tokio-rustls 0.24.1",
|
||||
|
@ -2365,6 +2396,16 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-channel-resolver"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de0a6bf546dc283b4c1413532d2bf53a64b3a006ee57f7ca0f4984f35841cacb"
|
||||
dependencies = [
|
||||
"nanorand",
|
||||
"rustls 0.21.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-pemfile"
|
||||
version = "1.0.4"
|
||||
|
@ -2491,9 +2532,9 @@ checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.195"
|
||||
version = "1.0.196"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02"
|
||||
checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
@ -2509,9 +2550,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.195"
|
||||
version = "1.0.196"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c"
|
||||
checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2520,9 +2561,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.111"
|
||||
version = "1.0.113"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4"
|
||||
checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -3022,9 +3063,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.8"
|
||||
version = "0.8.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35"
|
||||
checksum = "c6a4b9e8023eb94392d3dca65d717c53abc5dad49c07cb65bb8fcd87115fa325"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
|
@ -3043,11 +3084,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.21.0"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03"
|
||||
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
|
||||
dependencies = [
|
||||
"indexmap 2.1.0",
|
||||
"indexmap 2.2.1",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
|
@ -3447,9 +3488,9 @@ checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b"
|
|||
|
||||
[[package]]
|
||||
name = "wasm-streams"
|
||||
version = "0.3.0"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7"
|
||||
checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"js-sys",
|
||||
|
@ -3677,9 +3718,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
|||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.34"
|
||||
version = "0.5.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16"
|
||||
checksum = "818ce546a11a9986bc24f93d0cdf38a8a1a400f1473ea8c82e59f6e0ffab9249"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
|
|
@ -18,7 +18,7 @@ io-uring = ["dep:tokio-uring", "sled/io_uring", "actix-web/experimental-io-uring
|
|||
|
||||
[dependencies]
|
||||
actix-form-data = "0.7.0-beta.6"
|
||||
actix-web = { version = "4.0.0", default-features = false }
|
||||
actix-web = { version = "4.0.0", default-features = false, features = ["rustls-0_21"] }
|
||||
async-trait = "0.1.51"
|
||||
barrel = { version = "0.7.0", features = ["pg"] }
|
||||
base64 = "0.21.0"
|
||||
|
@ -48,6 +48,9 @@ reqwest-middleware = "0.2.2"
|
|||
reqwest-tracing = { version = "0.4.5" }
|
||||
# pinned to tokio-postgres-rustls
|
||||
rustls = "0.22.0"
|
||||
rustls_021 = { package = "rustls", version = "0.21" }
|
||||
# pinned to rustls
|
||||
rustls-channel-resolver = "0.1.0"
|
||||
# pinned to rustls
|
||||
rustls-pemfile = "2.0.0"
|
||||
rusty-s3 = "0.5.0"
|
||||
|
|
2
dev.toml
2
dev.toml
|
@ -2,6 +2,8 @@
|
|||
address = '[::]:8080'
|
||||
api_key = 'api-key'
|
||||
max_file_count = 10
|
||||
certificate = "./data/pictrs.crt"
|
||||
private_key = "./data/pictrs.key"
|
||||
|
||||
[upgrade]
|
||||
concurrency = 512
|
||||
|
|
14
pict-rs.toml
14
pict-rs.toml
|
@ -37,6 +37,20 @@ max_file_count = 1
|
|||
# default: The system's advertised temporary directory ("/tmp" on most linuxes)
|
||||
temporary_directory = "/tmp"
|
||||
|
||||
## Optional: path to server certificate to enable TLS
|
||||
# environment variable: PICTRS__SERVER__CERTIFICATE
|
||||
# default: empty
|
||||
#
|
||||
# Note that both certificate and private_key must be set to enable TLS
|
||||
certificate = "/path/to/server.crt"
|
||||
|
||||
## Optional: path to server key to enable TLS
|
||||
# environment variable: PICTRS__SERVER__PRIVATE_KEY
|
||||
# default: empty
|
||||
#
|
||||
# Note that both private_key and certificate must be set to enable TLS
|
||||
private_key = "/path/to/server.key"
|
||||
|
||||
## Client configuration
|
||||
[client]
|
||||
## Optional: time (in seconds) the client will wait for a response before giving up
|
||||
|
|
9
scripts/setup-tls.sh
Executable file
9
scripts/setup-tls.sh
Executable file
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -xe
|
||||
|
||||
mkdir -p ./data
|
||||
|
||||
certstrap --depot-path ./data init --common-name pictrsCA
|
||||
certstrap --depot-path ./data request-cert --common-name pictrs --domain localhost
|
||||
certstrap --depot-path ./data sign pictrs --CA pictrsCA
|
|
@ -55,6 +55,8 @@ impl Args {
|
|||
address,
|
||||
api_key,
|
||||
temporary_directory,
|
||||
certificate,
|
||||
private_key,
|
||||
client_timeout,
|
||||
upgrade_concurrency,
|
||||
metrics_prometheus_address,
|
||||
|
@ -114,6 +116,8 @@ impl Args {
|
|||
danger_dummy_mode,
|
||||
max_file_count,
|
||||
temporary_directory,
|
||||
certificate,
|
||||
private_key,
|
||||
};
|
||||
|
||||
let client = Client {
|
||||
|
@ -521,6 +525,10 @@ struct Server {
|
|||
max_file_count: Option<u32>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
temporary_directory: Option<PathBuf>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
certificate: Option<PathBuf>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
private_key: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, serde::Serialize)]
|
||||
|
@ -913,6 +921,16 @@ struct Run {
|
|||
#[arg(long)]
|
||||
temporary_directory: Option<PathBuf>,
|
||||
|
||||
/// The path to the TLS certificate. Both the certificate and the private_key must be specified
|
||||
/// to enable TLS
|
||||
#[arg(long)]
|
||||
certificate: Option<PathBuf>,
|
||||
|
||||
/// The path to the private key used to negotiate TLS. Both the private_key and the certificate
|
||||
/// must be specified to enable TLS
|
||||
#[arg(long)]
|
||||
private_key: Option<PathBuf>,
|
||||
|
||||
/// How long (in seconds) the internel HTTP client should wait for responses
|
||||
///
|
||||
/// This number defaults to 30
|
||||
|
|
|
@ -118,6 +118,12 @@ pub(crate) struct Server {
|
|||
pub(crate) max_file_count: u32,
|
||||
|
||||
pub(crate) temporary_directory: PathBuf,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) certificate: Option<PathBuf>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub(crate) private_key: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
|
||||
|
|
92
src/lib.rs
92
src/lib.rs
|
@ -29,6 +29,7 @@ mod serde_str;
|
|||
mod store;
|
||||
mod stream;
|
||||
mod sync;
|
||||
mod tls;
|
||||
mod tmp_file;
|
||||
mod validate;
|
||||
|
||||
|
@ -77,6 +78,7 @@ use self::{
|
|||
serde_str::Serde,
|
||||
store::{file_store::FileStore, object_store::ObjectStore, Store},
|
||||
stream::{empty, once},
|
||||
tls::Tls,
|
||||
};
|
||||
|
||||
pub use self::config::{ConfigSource, PictRsConfiguration};
|
||||
|
@ -1840,14 +1842,16 @@ async fn launch_file_store<F: Fn(&mut web::ServiceConfig) + Send + Clone + 'stat
|
|||
client: ClientWithMiddleware,
|
||||
config: Configuration,
|
||||
extra_config: F,
|
||||
) -> std::io::Result<()> {
|
||||
) -> color_eyre::Result<()> {
|
||||
let process_map = ProcessMap::new();
|
||||
|
||||
let address = config.server.address;
|
||||
|
||||
spawn_cleanup(repo.clone(), &config);
|
||||
|
||||
HttpServer::new(move || {
|
||||
let tls = Tls::from_config(&config);
|
||||
|
||||
let server = HttpServer::new(move || {
|
||||
let tmp_dir = tmp_dir.clone();
|
||||
let client = client.clone();
|
||||
let store = store.clone();
|
||||
|
@ -1872,10 +1876,41 @@ async fn launch_file_store<F: Fn(&mut web::ServiceConfig) + Send + Clone + 'stat
|
|||
.app_data(web::Data::new(process_map.clone()))
|
||||
.app_data(web::Data::new(tmp_dir))
|
||||
.configure(move |sc| configure_endpoints(sc, repo, store, config, client, extra_config))
|
||||
})
|
||||
.bind(address)?
|
||||
.run()
|
||||
.await
|
||||
});
|
||||
|
||||
if let Some(tls) = tls {
|
||||
let certified_key = tls.open_keys().await?;
|
||||
|
||||
let (tx, rx) = rustls_channel_resolver::channel::<32>(certified_key);
|
||||
|
||||
let handle = crate::sync::abort_on_drop(crate::sync::spawn("cert-reader", async move {
|
||||
let mut interval = tokio::time::interval(Duration::from_secs(30));
|
||||
interval.tick().await;
|
||||
|
||||
loop {
|
||||
interval.tick().await;
|
||||
|
||||
match tls.open_keys().await {
|
||||
Ok(certified_key) => tx.update(certified_key),
|
||||
Err(e) => tracing::error!("Failed to open keys {}", format!("{e}")),
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
let config = rustls_021::ServerConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_no_client_auth()
|
||||
.with_cert_resolver(rx);
|
||||
|
||||
server.bind_rustls_021(address, config)?.run().await?;
|
||||
|
||||
handle.abort();
|
||||
let _ = handle.await;
|
||||
} else {
|
||||
server.bind(address)?.run().await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn launch_object_store<F: Fn(&mut web::ServiceConfig) + Send + Clone + 'static>(
|
||||
|
@ -1885,14 +1920,16 @@ async fn launch_object_store<F: Fn(&mut web::ServiceConfig) + Send + Clone + 'st
|
|||
client: ClientWithMiddleware,
|
||||
config: Configuration,
|
||||
extra_config: F,
|
||||
) -> std::io::Result<()> {
|
||||
) -> color_eyre::Result<()> {
|
||||
let process_map = ProcessMap::new();
|
||||
|
||||
let address = config.server.address;
|
||||
|
||||
spawn_cleanup(repo.clone(), &config);
|
||||
|
||||
HttpServer::new(move || {
|
||||
let tls = Tls::from_config(&config);
|
||||
|
||||
let server = HttpServer::new(move || {
|
||||
let tmp_dir = tmp_dir.clone();
|
||||
let client = client.clone();
|
||||
let store = store.clone();
|
||||
|
@ -1917,10 +1954,41 @@ async fn launch_object_store<F: Fn(&mut web::ServiceConfig) + Send + Clone + 'st
|
|||
.app_data(web::Data::new(process_map.clone()))
|
||||
.app_data(web::Data::new(tmp_dir))
|
||||
.configure(move |sc| configure_endpoints(sc, repo, store, config, client, extra_config))
|
||||
})
|
||||
.bind(address)?
|
||||
.run()
|
||||
.await
|
||||
});
|
||||
|
||||
if let Some(tls) = tls {
|
||||
let certified_key = tls.open_keys().await?;
|
||||
|
||||
let (tx, rx) = rustls_channel_resolver::channel::<32>(certified_key);
|
||||
|
||||
let handle = crate::sync::abort_on_drop(crate::sync::spawn("cert-reader", async move {
|
||||
let mut interval = tokio::time::interval(Duration::from_secs(30));
|
||||
interval.tick().await;
|
||||
|
||||
loop {
|
||||
interval.tick().await;
|
||||
|
||||
match tls.open_keys().await {
|
||||
Ok(certified_key) => tx.update(certified_key),
|
||||
Err(e) => tracing::error!("Failed to open keys {}", format!("{e}")),
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
let config = rustls_021::ServerConfig::builder()
|
||||
.with_safe_defaults()
|
||||
.with_no_client_auth()
|
||||
.with_cert_resolver(rx);
|
||||
|
||||
server.bind_rustls_021(address, config)?.run().await?;
|
||||
|
||||
handle.abort();
|
||||
let _ = handle.await;
|
||||
} else {
|
||||
server.bind(address)?.run().await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
|
|
|
@ -80,7 +80,7 @@ async fn drain(rx: flume::Receiver<actix_web::dev::Payload>) {
|
|||
}
|
||||
|
||||
if count > 0 {
|
||||
tracing::info!("Drained {count} dropped payloads");
|
||||
tracing::debug!("Drained {count} dropped payloads");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ impl Drop for DrainHandle {
|
|||
impl Drop for PayloadStream {
|
||||
fn drop(&mut self) {
|
||||
if let Some(payload) = self.inner.take() {
|
||||
tracing::warn!("Dropped unclosed payload, draining");
|
||||
tracing::debug!("Dropped unclosed payload, draining");
|
||||
if self.sender.try_send(payload).is_err() {
|
||||
metrics::counter!("pict-rs.payload.drain.fail-send").increment(1);
|
||||
tracing::error!("Failed to send unclosed payload for draining");
|
||||
|
|
65
src/tls.rs
Normal file
65
src/tls.rs
Normal file
|
@ -0,0 +1,65 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
pub(super) struct Tls {
|
||||
certificate: PathBuf,
|
||||
private_key: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
enum TlsError {
|
||||
#[error("Failed to read file")]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
#[error("Failed to sign certificate")]
|
||||
Sign(#[from] rustls_021::sign::SignError),
|
||||
|
||||
#[error("No certificates found in certificate file")]
|
||||
MissingCerts,
|
||||
|
||||
#[error("No key found in private key file")]
|
||||
MissingKey,
|
||||
}
|
||||
|
||||
impl Tls {
|
||||
pub(super) fn from_config(config: &crate::config::Configuration) -> Option<Self> {
|
||||
config
|
||||
.server
|
||||
.certificate
|
||||
.as_ref()
|
||||
.zip(config.server.private_key.as_ref())
|
||||
.map(|(cert, key)| Tls {
|
||||
certificate: cert.clone(),
|
||||
private_key: key.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) async fn open_keys(&self) -> color_eyre::Result<rustls_021::sign::CertifiedKey> {
|
||||
let cert_bytes = tokio::fs::read(&self.certificate)
|
||||
.await
|
||||
.map_err(TlsError::from)?;
|
||||
|
||||
let certs = rustls_pemfile::certs(&mut cert_bytes.as_slice())
|
||||
.map(|res| res.map(|c| rustls_021::Certificate(c.to_vec())))
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(TlsError::from)?;
|
||||
|
||||
if certs.is_empty() {
|
||||
return Err(TlsError::MissingCerts.into());
|
||||
}
|
||||
|
||||
let key_bytes = tokio::fs::read(&self.private_key)
|
||||
.await
|
||||
.map_err(TlsError::from)?;
|
||||
|
||||
let private_key = rustls_pemfile::private_key(&mut key_bytes.as_slice())
|
||||
.map_err(TlsError::from)?
|
||||
.ok_or(TlsError::MissingKey)?;
|
||||
|
||||
let private_key = rustls_021::sign::any_supported_type(&rustls_021::PrivateKey(Vec::from(
|
||||
private_key.secret_der(),
|
||||
)))
|
||||
.map_err(TlsError::from)?;
|
||||
|
||||
Ok(rustls_021::sign::CertifiedKey::new(certs, private_key))
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue