[pbs-devel] [PATCH proxmox-backup] node.cfg/proxy: add tls min/max protocol version

Fabian Grünbichler f.gruenbichler at proxmox.com
Fri Jan 14 11:50:25 CET 2022


in a new 'tls' config key for future extensibility.

Signed-off-by: Fabian Grünbichler <f.gruenbichler at proxmox.com>
---
 pbs-api-types/src/lib.rs        | 39 +++++++++++++++++++++++++++++++++
 src/api2/node/config.rs         |  4 ++++
 src/bin/proxmox-backup-proxy.rs | 22 +++++++++++++++++--
 src/config/node.rs              | 10 ++++++++-
 4 files changed, 72 insertions(+), 3 deletions(-)

diff --git a/pbs-api-types/src/lib.rs b/pbs-api-types/src/lib.rs
index 754e7b22..caf68ebf 100644
--- a/pbs-api-types/src/lib.rs
+++ b/pbs-api-types/src/lib.rs
@@ -359,6 +359,45 @@ pub enum NodePowerCommand {
     Shutdown,
 }
 
+#[api()]
+#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
+/// TLS protocol version ('tls-1.2' or 'tls-1.3').
+pub enum TlsVersion {
+    /// TLS version 1.2
+    #[serde(rename = "tls-1.2")]
+    Tls1_2,
+    /// TLS version 1.3
+    #[serde(rename = "tls-1.3")]
+    Tls1_3,
+}
+
+#[api(
+    properties: {
+        "min-ver": {
+            type: TlsVersion,
+            optional: true,
+        },
+        "max-ver": {
+            type: TlsVersion,
+            optional: true,
+        },
+    },
+)]
+#[derive(Clone, Serialize, Deserialize)]
+#[serde(rename_all = "kebab-case")]
+/// TLS settings
+pub struct TlsSettings {
+    /// Minimum TLS protocol version (requires proxy restart to take effect)
+    pub min_ver: Option<TlsVersion>,
+    /// Maximum TLS protocol version (requires proxy restart to take effect)
+    pub max_ver: Option<TlsVersion>,
+}
+
+pub const TLS_SETTINGS_STRING_SCHEMA: Schema = StringSchema::new(
+    "TLS settings")
+    .format(&ApiStringFormat::PropertyString(&TlsSettings::API_SCHEMA))
+    .schema();
+
 
 #[api()]
 #[derive(Eq, PartialEq, Debug, Serialize, Deserialize)]
diff --git a/src/api2/node/config.rs b/src/api2/node/config.rs
index c4af7b92..710e9ebc 100644
--- a/src/api2/node/config.rs
+++ b/src/api2/node/config.rs
@@ -62,6 +62,8 @@ pub enum DeletableProperty {
     /// Delete the ciphers-tls-1.2 property.
     #[serde(rename="ciphers-tls-1.2")]
     ciphers_tls_1_2,
+    /// Delete the tls property
+    tls,
 }
 
 #[api(
@@ -121,6 +123,7 @@ pub fn update_node_config(
                 DeletableProperty::email_from => { config.email_from = None; },
                 DeletableProperty::ciphers_tls_1_3 => { config.ciphers_tls_1_3 = None; },
                 DeletableProperty::ciphers_tls_1_2 => { config.ciphers_tls_1_2 = None; },
+                DeletableProperty::tls => { config.tls = None; },
             }
         }
     }
@@ -135,6 +138,7 @@ pub fn update_node_config(
     if update.email_from.is_some() { config.email_from = update.email_from; }
     if update.ciphers_tls_1_3.is_some() { config.ciphers_tls_1_3 = update.ciphers_tls_1_3; }
     if update.ciphers_tls_1_2.is_some() { config.ciphers_tls_1_2 = update.ciphers_tls_1_2; }
+    if update.tls.is_some() { config.tls = update.tls; }
 
     crate::config::node::save_config(&config)?;
 
diff --git a/src/bin/proxmox-backup-proxy.rs b/src/bin/proxmox-backup-proxy.rs
index 523966cf..eadfb2de 100644
--- a/src/bin/proxmox-backup-proxy.rs
+++ b/src/bin/proxmox-backup-proxy.rs
@@ -12,7 +12,7 @@ use hyper::{Body, StatusCode};
 use hyper::header;
 use url::form_urlencoded;
 
-use openssl::ssl::{SslMethod, SslAcceptor, SslFiletype};
+use openssl::ssl::{SslMethod, SslAcceptor, SslFiletype, SslVersion};
 use tokio_stream::wrappers::ReceiverStream;
 use serde_json::{json, Value};
 use http::{Method, HeaderMap};
@@ -22,6 +22,7 @@ use proxmox_sys::fs::CreateOptions;
 use proxmox_lang::try_block;
 use proxmox_router::{RpcEnvironment, RpcEnvironmentType, UserInformation};
 use proxmox_http::client::{RateLimitedStream, ShareableRateLimit};
+use proxmox_schema::ApiType;
 use proxmox_sys::{task_log, task_warn};
 use proxmox_sys::logrotate::LogRotate;
 
@@ -51,7 +52,7 @@ use proxmox_time::CalendarEvent;
 
 use pbs_api_types::{
     Authid, TapeBackupJobConfig, VerificationJobConfig, SyncJobConfig, DataStoreConfig,
-    PruneOptions,
+    PruneOptions, TlsVersion, TlsSettings,
 };
 
 use proxmox_rest_server::daemon;
@@ -358,6 +359,23 @@ fn make_tls_acceptor() -> Result<SslAcceptor, Error> {
     acceptor.set_certificate_chain_file(cert_path)
         .map_err(|err| format_err!("unable to read proxy cert {} - {}", cert_path, err))?;
     acceptor.set_options(openssl::ssl::SslOptions::NO_RENEGOTIATION);
+
+    if let Some(tls_settings) = config.tls {
+        if let Ok(value) = TlsSettings::API_SCHEMA.parse_property_string(&tls_settings) {
+            if let Ok(settings) = serde_json::from_value::<TlsSettings>(value) {
+                let convert = |version: Option<TlsVersion>| {
+                    version.map(|version| match version {
+                        TlsVersion::Tls1_2 => SslVersion::TLS1_2,
+                        TlsVersion::Tls1_3 => SslVersion::TLS1_3,
+                    })
+                };
+
+                acceptor.set_min_proto_version(convert(settings.min_ver))?;
+                acceptor.set_max_proto_version(convert(settings.max_ver))?;
+            }
+        }
+    }
+
     acceptor.check_private_key().unwrap();
 
     Ok(acceptor.build())
diff --git a/src/config/node.rs b/src/config/node.rs
index 40d7b220..d96a0911 100644
--- a/src/config/node.rs
+++ b/src/config/node.rs
@@ -8,7 +8,7 @@ use proxmox_schema::{api, ApiStringFormat, ApiType, Updater};
 
 use proxmox_http::ProxyConfig;
 
-use pbs_api_types::{EMAIL_SCHEMA, OPENSSL_CIPHERS_TLS_1_2_SCHEMA, OPENSSL_CIPHERS_TLS_1_3_SCHEMA};
+use pbs_api_types::{EMAIL_SCHEMA, OPENSSL_CIPHERS_TLS_1_2_SCHEMA, OPENSSL_CIPHERS_TLS_1_3_SCHEMA, TLS_SETTINGS_STRING_SCHEMA};
 use pbs_buildcfg::configdir;
 use pbs_config::{open_backup_lockfile, BackupLockGuard};
 
@@ -100,6 +100,10 @@ pub struct AcmeConfig {
             schema: OPENSSL_CIPHERS_TLS_1_2_SCHEMA,
             optional: true,
         },
+        "tls": {
+            schema: TLS_SETTINGS_STRING_SCHEMA,
+            optional: true,
+        },
     },
 )]
 #[derive(Deserialize, Serialize, Updater)]
@@ -138,6 +142,10 @@ pub struct NodeConfig {
     /// List of TLS ciphers for TLS <= 1.2 that will be used by the proxy. (Proxy has to be restarted for changes to take effect)
     #[serde(skip_serializing_if = "Option::is_none", rename="ciphers-tls-1.2")]
     pub ciphers_tls_1_2: Option<String>,
+
+    /// TLS protocol settings that will be used by the proxy. (Proxy has to be restarted for changes to take effect)
+    #[serde(skip_serializing_if = "Option::is_none")]
+    pub tls: Option<String>,
 }
 
 impl NodeConfig {
-- 
2.30.2






More information about the pbs-devel mailing list