Add support for sslmode=require for diesel-async DB connections (#3189)
This commit is contained in:
parent
d7da911a48
commit
6d67f88603
4 changed files with 152 additions and 19 deletions
92
Cargo.lock
generated
92
Cargo.lock
generated
|
@ -215,7 +215,7 @@ dependencies = [
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"mio",
|
"mio",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"socket2",
|
"socket2 0.4.9",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
@ -245,7 +245,7 @@ dependencies = [
|
||||||
"http",
|
"http",
|
||||||
"log",
|
"log",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"tokio-rustls",
|
"tokio-rustls 0.23.4",
|
||||||
"tokio-util 0.7.4",
|
"tokio-util 0.7.4",
|
||||||
"webpki-roots",
|
"webpki-roots",
|
||||||
]
|
]
|
||||||
|
@ -297,7 +297,7 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"socket2",
|
"socket2 0.4.9",
|
||||||
"time 0.3.15",
|
"time 0.3.15",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
@ -496,7 +496,7 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"rustls",
|
"rustls 0.20.7",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
|
@ -2262,7 +2262,7 @@ dependencies = [
|
||||||
"httpdate",
|
"httpdate",
|
||||||
"itoa",
|
"itoa",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"socket2",
|
"socket2 0.4.9",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
@ -2640,9 +2640,11 @@ dependencies = [
|
||||||
"diesel-derive-newtype",
|
"diesel-derive-newtype",
|
||||||
"diesel_ltree",
|
"diesel_ltree",
|
||||||
"diesel_migrations",
|
"diesel_migrations",
|
||||||
|
"futures-util",
|
||||||
"lemmy_utils",
|
"lemmy_utils",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"regex",
|
"regex",
|
||||||
|
"rustls 0.21.2",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
|
@ -2651,6 +2653,8 @@ dependencies = [
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-postgres",
|
||||||
|
"tokio-postgres-rustls",
|
||||||
"tracing",
|
"tracing",
|
||||||
"ts-rs",
|
"ts-rs",
|
||||||
"typed-builder",
|
"typed-builder",
|
||||||
|
@ -2736,6 +2740,7 @@ dependencies = [
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel-async",
|
"diesel-async",
|
||||||
"doku",
|
"doku",
|
||||||
|
"futures-util",
|
||||||
"lemmy_api",
|
"lemmy_api",
|
||||||
"lemmy_api_common",
|
"lemmy_api_common",
|
||||||
"lemmy_api_crud",
|
"lemmy_api_crud",
|
||||||
|
@ -2749,9 +2754,12 @@ dependencies = [
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"reqwest-middleware",
|
"reqwest-middleware",
|
||||||
"reqwest-tracing",
|
"reqwest-tracing",
|
||||||
|
"rustls 0.21.2",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-postgres",
|
||||||
|
"tokio-postgres-rustls",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-actix-web 0.6.2",
|
"tracing-actix-web 0.6.2",
|
||||||
"tracing-error",
|
"tracing-error",
|
||||||
|
@ -2820,7 +2828,7 @@ dependencies = [
|
||||||
"nom 7.1.1",
|
"nom 7.1.1",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"quoted_printable",
|
"quoted_printable",
|
||||||
"socket2",
|
"socket2 0.4.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3932,11 +3940,11 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "postgres-protocol"
|
name = "postgres-protocol"
|
||||||
version = "0.6.4"
|
version = "0.6.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "878c6cbf956e03af9aa8204b407b9cbf47c072164800aa918c516cd4b056c50c"
|
checksum = "78b7fa9f396f51dffd61546fd8573ee20592287996568e6175ceb0f8699ad75d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.13.1",
|
"base64 0.21.2",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
"fallible-iterator",
|
"fallible-iterator",
|
||||||
|
@ -4495,6 +4503,28 @@ dependencies = [
|
||||||
"webpki",
|
"webpki",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls"
|
||||||
|
version = "0.21.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e32ca28af694bc1bbf399c33a516dbdf1c90090b8ab23c2bc24f834aa2247f5f"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"ring",
|
||||||
|
"rustls-webpki",
|
||||||
|
"sct",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-webpki"
|
||||||
|
version = "0.100.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.9"
|
version = "1.0.9"
|
||||||
|
@ -4859,6 +4889,16 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "socket2"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spin"
|
name = "spin"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
|
@ -5304,7 +5344,7 @@ dependencies = [
|
||||||
"parking_lot 0.12.1",
|
"parking_lot 0.12.1",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"socket2",
|
"socket2 0.4.9",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
|
@ -5343,9 +5383,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-postgres"
|
name = "tokio-postgres"
|
||||||
version = "0.7.7"
|
version = "0.7.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "29a12c1b3e0704ae7dfc25562629798b29c72e6b1d0a681b6f29ab4ae5e7f7bf"
|
checksum = "6e89f6234aa8fd43779746012fcf53603cdb91fdd8399aa0de868c2d56b6dde1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
@ -5360,22 +5400,46 @@ dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"postgres-protocol",
|
"postgres-protocol",
|
||||||
"postgres-types",
|
"postgres-types",
|
||||||
"socket2",
|
"socket2 0.5.3",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util 0.7.4",
|
"tokio-util 0.7.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-postgres-rustls"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dd5831152cb0d3f79ef5523b357319ba154795d64c7078b2daa95a803b54057f"
|
||||||
|
dependencies = [
|
||||||
|
"futures",
|
||||||
|
"ring",
|
||||||
|
"rustls 0.21.2",
|
||||||
|
"tokio",
|
||||||
|
"tokio-postgres",
|
||||||
|
"tokio-rustls 0.24.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-rustls"
|
name = "tokio-rustls"
|
||||||
version = "0.23.4"
|
version = "0.23.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
|
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustls",
|
"rustls 0.20.7",
|
||||||
"tokio",
|
"tokio",
|
||||||
"webpki",
|
"webpki",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-rustls"
|
||||||
|
version = "0.24.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
|
||||||
|
dependencies = [
|
||||||
|
"rustls 0.21.2",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-stream"
|
name = "tokio-stream"
|
||||||
version = "0.1.11"
|
version = "0.1.11"
|
||||||
|
|
|
@ -107,6 +107,10 @@ rand = "0.8.5"
|
||||||
opentelemetry = { version = "0.17.0", features = ["rt-tokio"] }
|
opentelemetry = { version = "0.17.0", features = ["rt-tokio"] }
|
||||||
tracing-opentelemetry = { version = "0.17.4" }
|
tracing-opentelemetry = { version = "0.17.4" }
|
||||||
ts-rs = { version = "6.2", features = ["serde-compat", "format", "chrono-impl"] }
|
ts-rs = { version = "6.2", features = ["serde-compat", "format", "chrono-impl"] }
|
||||||
|
rustls = { version ="0.21.2", features = ["dangerous_configuration"]}
|
||||||
|
futures-util = "0.3.28"
|
||||||
|
tokio-postgres = "0.7.8"
|
||||||
|
tokio-postgres-rustls = "0.10.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
lemmy_api = { workspace = true }
|
lemmy_api = { workspace = true }
|
||||||
|
@ -140,3 +144,8 @@ opentelemetry-otlp = { version = "0.10.0", optional = true }
|
||||||
pict-rs = { version = "0.4.0-rc.3", optional = true }
|
pict-rs = { version = "0.4.0-rc.3", optional = true }
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
actix-cors = "0.6.4"
|
actix-cors = "0.6.4"
|
||||||
|
rustls = { workspace = true }
|
||||||
|
futures-util = { workspace = true }
|
||||||
|
tokio-postgres = { workspace = true }
|
||||||
|
tokio-postgres-rustls = { workspace = true }
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,11 @@ async-trait = { workspace = true }
|
||||||
tokio = { workspace = true }
|
tokio = { workspace = true }
|
||||||
tracing = { workspace = true }
|
tracing = { workspace = true }
|
||||||
deadpool = { version = "0.9.5", features = ["rt_tokio_1"], optional = true }
|
deadpool = { version = "0.9.5", features = ["rt_tokio_1"], optional = true }
|
||||||
ts-rs = { workspace = true, optional = true }
|
ts-rs = { workspace = true, optional = true }
|
||||||
|
rustls = { workspace = true }
|
||||||
|
futures-util = { workspace = true }
|
||||||
|
tokio-postgres = { workspace = true }
|
||||||
|
tokio-postgres-rustls = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serial_test = { workspace = true }
|
serial_test = { workspace = true }
|
||||||
|
|
|
@ -12,7 +12,7 @@ use diesel::{
|
||||||
backend::Backend,
|
backend::Backend,
|
||||||
deserialize::FromSql,
|
deserialize::FromSql,
|
||||||
pg::Pg,
|
pg::Pg,
|
||||||
result::{Error as DieselError, Error::QueryBuilderError},
|
result::{ConnectionError, ConnectionResult, Error as DieselError, Error::QueryBuilderError},
|
||||||
serialize::{Output, ToSql},
|
serialize::{Output, ToSql},
|
||||||
sql_types::Text,
|
sql_types::Text,
|
||||||
PgConnection,
|
PgConnection,
|
||||||
|
@ -25,11 +25,21 @@ use diesel_async::{
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use diesel_migrations::EmbeddedMigrations;
|
use diesel_migrations::EmbeddedMigrations;
|
||||||
|
use futures_util::{future::BoxFuture, FutureExt};
|
||||||
use lemmy_utils::{error::LemmyError, settings::structs::Settings};
|
use lemmy_utils::{error::LemmyError, settings::structs::Settings};
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::{env, env::VarError, time::Duration};
|
use rustls::{
|
||||||
use tracing::info;
|
client::{ServerCertVerified, ServerCertVerifier},
|
||||||
|
ServerName,
|
||||||
|
};
|
||||||
|
use std::{
|
||||||
|
env,
|
||||||
|
env::VarError,
|
||||||
|
sync::Arc,
|
||||||
|
time::{Duration, SystemTime},
|
||||||
|
};
|
||||||
|
use tracing::{error, info};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
const FETCH_LIMIT_DEFAULT: i64 = 10;
|
const FETCH_LIMIT_DEFAULT: i64 = 10;
|
||||||
|
@ -136,7 +146,15 @@ pub fn diesel_option_overwrite_to_url_create(
|
||||||
async fn build_db_pool_settings_opt(settings: Option<&Settings>) -> Result<DbPool, LemmyError> {
|
async fn build_db_pool_settings_opt(settings: Option<&Settings>) -> Result<DbPool, LemmyError> {
|
||||||
let db_url = get_database_url(settings);
|
let db_url = get_database_url(settings);
|
||||||
let pool_size = settings.map(|s| s.database.pool_size).unwrap_or(5);
|
let pool_size = settings.map(|s| s.database.pool_size).unwrap_or(5);
|
||||||
let manager = AsyncDieselConnectionManager::<AsyncPgConnection>::new(&db_url);
|
// We only support TLS with sslmode=require currently
|
||||||
|
let tls_enabled = db_url.contains("sslmode=require");
|
||||||
|
let manager = if tls_enabled {
|
||||||
|
// diesel-async does not support any TLS connections out of the box, so we need to manually
|
||||||
|
// provide a setup function which handles creating the connection
|
||||||
|
AsyncDieselConnectionManager::<AsyncPgConnection>::new_with_setup(&db_url, establish_connection)
|
||||||
|
} else {
|
||||||
|
AsyncDieselConnectionManager::<AsyncPgConnection>::new(&db_url)
|
||||||
|
};
|
||||||
let pool = Pool::builder(manager)
|
let pool = Pool::builder(manager)
|
||||||
.max_size(pool_size)
|
.max_size(pool_size)
|
||||||
.wait_timeout(POOL_TIMEOUT)
|
.wait_timeout(POOL_TIMEOUT)
|
||||||
|
@ -153,6 +171,44 @@ async fn build_db_pool_settings_opt(settings: Option<&Settings>) -> Result<DbPoo
|
||||||
Ok(pool)
|
Ok(pool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn establish_connection(config: &str) -> BoxFuture<ConnectionResult<AsyncPgConnection>> {
|
||||||
|
let fut = async {
|
||||||
|
let rustls_config = rustls::ClientConfig::builder()
|
||||||
|
.with_safe_defaults()
|
||||||
|
.with_custom_certificate_verifier(Arc::new(NoCertVerifier {}))
|
||||||
|
.with_no_client_auth();
|
||||||
|
|
||||||
|
let tls = tokio_postgres_rustls::MakeRustlsConnect::new(rustls_config);
|
||||||
|
let (client, conn) = tokio_postgres::connect(config, tls)
|
||||||
|
.await
|
||||||
|
.map_err(|e| ConnectionError::BadConnection(e.to_string()))?;
|
||||||
|
tokio::spawn(async move {
|
||||||
|
if let Err(e) = conn.await {
|
||||||
|
error!("Database connection failed: {e}");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AsyncPgConnection::try_from(client).await
|
||||||
|
};
|
||||||
|
fut.boxed()
|
||||||
|
}
|
||||||
|
|
||||||
|
struct NoCertVerifier {}
|
||||||
|
|
||||||
|
impl ServerCertVerifier for NoCertVerifier {
|
||||||
|
fn verify_server_cert(
|
||||||
|
&self,
|
||||||
|
_end_entity: &rustls::Certificate,
|
||||||
|
_intermediates: &[rustls::Certificate],
|
||||||
|
_server_name: &ServerName,
|
||||||
|
_scts: &mut dyn Iterator<Item = &[u8]>,
|
||||||
|
_ocsp_response: &[u8],
|
||||||
|
_now: SystemTime,
|
||||||
|
) -> Result<ServerCertVerified, rustls::Error> {
|
||||||
|
// Will verify all (even invalid) certs without any checks (sslmode=require)
|
||||||
|
Ok(ServerCertVerified::assertion())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
|
pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
|
||||||
|
|
||||||
pub fn run_migrations(db_url: &str) {
|
pub fn run_migrations(db_url: &str) {
|
||||||
|
|
Loading…
Reference in a new issue