From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id 944E31FF0E0 for ; Thu, 06 Aug 2026 15:09:36 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 667DB2153C; Thu, 06 Aug 2026 15:09:36 +0200 (CEST) Date: Thu, 06 Aug 2026 15:09:28 +0200 From: Fabian =?iso-8859-1?q?Gr=FCnbichler?= Subject: Re: [PATCH proxmox-backup v3 05/16] config: use proxmox_tls_certificates for generating self-signed certificates To: pbs-devel@lists.proxmox.com, Shannon Sterz References: <20260805155308.519896-2-s.sterz@proxmox.com> <20260805155308.519896-7-s.sterz@proxmox.com> In-Reply-To: <20260805155308.519896-7-s.sterz@proxmox.com> MIME-Version: 1.0 User-Agent: astroid/0.17.0 (https://github.com/astroidmail/astroid) Message-Id: <1786019814.dpgzjo6tpu.astroid@yuna.none> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1786021756448 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.116 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_LOW -0.7 Sender listed at https://www.dnswl.org/, low trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: GSAPR7GZH76NR4242GLZ3VYUQ4GI457K X-Message-ID-Hash: GSAPR7GZH76NR4242GLZ3VYUQ4GI457K X-MailFrom: f.gruenbichler@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox Backup Server development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: On August 5, 2026 5:52 pm, Shannon Sterz wrote: > to avoid duplicating almost identical code here, re-use the version > from `proxmox_tls_certificates::create_self_signed_cert`. for > `days_valid` specify `None` to opt into the default of 3650 days. since you write that it is "almost duplicate", a small summary of where they might differ would be great ;) AFAICT the switch from 1000 years -> 10 years is the only semantic change here? tbh I am not sure whether the behaviour of appending the search domain to the nodename (still) makes much sense, maybe the interface should rather be an additional list of SANs, and the caller can decide how to create them? for some products, we might want to specify them in a config file. for others, we might want to look them up via `hostname -f` and fallback to the search domain thing we've been doing historically? for some we might want to add IP addresses, for others we might not want that (and we definitely don't want to have "query IP" logic in proxmox-tls-certificates..) IMHO similar logic applies to the subject. that probably means we want some helpers to build a subject name (if we don't want to expose openssl types here). but then again, the helper we move to here is openssl specific anyway.. >=20 > Signed-off-by: Shannon Sterz > --- > Cargo.toml | 3 ++ > debian/control | 2 + > src/config/mod.rs | 94 ++++------------------------------------------- > 3 files changed, 13 insertions(+), 86 deletions(-) >=20 > diff --git a/Cargo.toml b/Cargo.toml > index a2dcf85c3..df5f8942c 100644 > --- a/Cargo.toml > +++ b/Cargo.toml > @@ -97,6 +97,7 @@ proxmox-sys =3D "1" > proxmox-systemd =3D "1.0.1" > proxmox-tfa =3D { version =3D "6.0.3", features =3D [ "api", "api-types"= ] } > proxmox-time =3D "2" > +proxmox-tls-certificates =3D { version =3D "1", features =3D [ "impl" ] = } > proxmox-upgrade-checks =3D "1" > proxmox-uuid =3D { version =3D "1", features =3D [ "serde" ] } > proxmox-worker-task =3D "1" > @@ -255,6 +256,7 @@ proxmox-sys =3D { workspace =3D true, features =3D [ = "timer" ] } > proxmox-systemd.workspace =3D true > proxmox-tfa.workspace =3D true > proxmox-time.workspace =3D true > +proxmox-tls-certificates.workspace =3D true > proxmox-upgrade-checks.workspace =3D true > proxmox-uuid.workspace =3D true > proxmox-worker-task.workspace =3D true > @@ -325,6 +327,7 @@ proxmox-rrd-api-types.workspace =3D true > #proxmox-systemd =3D { path =3D "../proxmox/proxmox-systemd" } > #proxmox-tfa =3D { path =3D "../proxmox/proxmox-tfa" } > #proxmox-time =3D { path =3D "../proxmox/proxmox-time" } > +#proxmox-tls-certificates =3D { path =3D "../proxmox/proxmox-tls-certifi= cates" } > #proxmox-upgrade-checks =3D { path =3D "../proxmox/proxmox-upgrade-check= s" } > #proxmox-uuid =3D { path =3D "../proxmox/proxmox-uuid" } > #proxmox-worker-task =3D { path =3D "../proxmox/proxmox-worker-task" } > diff --git a/debian/control b/debian/control > index d8dcabdb7..8b9607fff 100644 > --- a/debian/control > +++ b/debian/control > @@ -132,6 +132,8 @@ Build-Depends: debhelper (>=3D 12~), > librust-proxmox-tfa-6+api-types-dev (>=3D 6.0.3-~~), > librust-proxmox-tfa-6+default-dev (>=3D 6.0.3-~~), > librust-proxmox-time-2+default-dev, > + librust-proxmox-tls-certificates-1+default-dev, > + librust-proxmox-tls-certificates-1+impl-dev, > librust-proxmox-upgrade-checks-1+default-dev, > librust-proxmox-uuid-1+default-dev, > librust-proxmox-uuid-1+serde-dev, > diff --git a/src/config/mod.rs b/src/config/mod.rs > index 98683186e..bbca5a9af 100644 > --- a/src/config/mod.rs > +++ b/src/config/mod.rs > @@ -5,9 +5,6 @@ > =20 > use anyhow::{Error, bail, format_err}; > use nix::sys::stat::Mode; > -use openssl::pkey::PKey; > -use openssl::rsa::Rsa; > -use openssl::x509::X509Builder; > use std::path::Path; > =20 > use proxmox_lang::try_block; > @@ -90,92 +87,17 @@ pub fn update_self_signed_cert(force: bool) -> Result= <(), Error> { > if key_path.exists() && cert_path.exists() && !force { > return Ok(()); > } > - > - let rsa =3D Rsa::generate(4096).unwrap(); > - > - let priv_pem =3D rsa.private_key_to_pem()?; > - > - let mut x509 =3D X509Builder::new()?; > - > - x509.set_version(2)?; > - > - let today =3D openssl::asn1::Asn1Time::days_from_now(0)?; > - x509.set_not_before(&today)?; > - let expire =3D openssl::asn1::Asn1Time::days_from_now(365 * 1000)?; > - x509.set_not_after(&expire)?; > - > - let nodename =3D proxmox_sys::nodename(); > - let mut fqdn =3D nodename.to_owned(); > - > let resolv_conf =3D crate::api2::node::dns::read_etc_resolv_conf()?; > - if let Some(search) =3D resolv_conf["search"].as_str() { > - fqdn.push('.'); > - fqdn.push_str(search); > - } > =20 > - // we try to generate an unique 'subject' to avoid browser problems > - //(reused serial numbers, ..) > - let uuid =3D proxmox_uuid::Uuid::generate(); > + let (priv_key, cert) =3D proxmox_tls_certificates::create_self_signe= d_cert( > + "Proxmox Backup Server", > + proxmox_sys::nodename(), > + resolv_conf["search"].as_str(), > + None, > + )?; > =20 > - let mut subject_name =3D openssl::x509::X509NameBuilder::new()?; > - subject_name.append_entry_by_text("O", "Proxmox Backup Server")?; > - subject_name.append_entry_by_text("OU", &format!("{uuid:X}"))?; > - subject_name.append_entry_by_text("CN", &fqdn)?; > - let subject_name =3D subject_name.build(); > - > - x509.set_subject_name(&subject_name)?; > - x509.set_issuer_name(&subject_name)?; > - > - let bc =3D openssl::x509::extension::BasicConstraints::new(); // CA = =3D false > - let bc =3D bc.build()?; > - x509.append_extension(bc)?; > - > - let usage =3D openssl::x509::extension::ExtendedKeyUsage::new() > - .server_auth() > - .build()?; > - x509.append_extension(usage)?; > - > - let context =3D x509.x509v3_context(None, None); > - > - let mut alt_names =3D openssl::x509::extension::SubjectAlternativeNa= me::new(); > - > - alt_names.ip("127.0.0.1"); > - alt_names.ip("::1"); > - > - alt_names.dns("localhost"); > - > - if nodename !=3D "localhost" { > - alt_names.dns(nodename); > - } > - if nodename !=3D fqdn { > - alt_names.dns(&fqdn); > - } > - > - let alt_names =3D alt_names.build(&context)?; > - > - x509.append_extension(alt_names)?; > - > - let pub_pem =3D rsa.public_key_to_pem()?; > - let pubkey =3D PKey::public_key_from_pem(&pub_pem)?; > - > - x509.set_pubkey(&pubkey)?; > - > - let context =3D x509.x509v3_context(None, None); > - let ext =3D openssl::x509::extension::SubjectKeyIdentifier::new().bu= ild(&context)?; > - x509.append_extension(ext)?; > - > - let context =3D x509.x509v3_context(None, None); > - let ext =3D openssl::x509::extension::AuthorityKeyIdentifier::new() > - .keyid(true) > - .build(&context)?; > - x509.append_extension(ext)?; > - > - let privkey =3D PKey::from_rsa(rsa)?; > - > - x509.sign(&privkey, openssl::hash::MessageDigest::sha256())?; > - > - let x509 =3D x509.build(); > - let cert_pem =3D x509.to_pem()?; > + let cert_pem =3D cert.to_pem()?; > + let priv_pem =3D priv_key.private_key_to_pem_pkcs8()?; > =20 > set_proxy_certificate(&cert_pem, &priv_pem)?; > =20 > --=20 > 2.47.3 >=20 >=20 >=20 >=20 >=20 >=20