summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHannes Duerr <h.duerr@proxmox.com>2025-02-10 15:19:25 +0100
committerThomas Lamprecht <t.lamprecht@proxmox.com>2025-03-06 10:00:21 +0100
commit894d2d33e3b104bcdc8b83e3f205427db93800c3 (patch)
tree94a5af2ba5a2a9b84a04ea28800affa7cc1ec5d2
parent77671ba327fa0fc6461d70f9e9e64891b58c36ab (diff)
api request helper: enforce TLS cert-check and add cert-fingerprint option
Currently, we do not verify the TLS certificate for API requests external IPAM and DNS integration. This could allow man-in-the-middle attacks, albeit most IPAM infrastructure is on controlled and isolated LANs, so it's not something that should frequently happen; and technically our IPAM integration is still marked as tech-preview, which had its reasons. Enforce verification, and allow users to pass a cert SHA256 fingerprint to ensure a certificates validity if it's not trusted by the system trust store, as it's, e.g., the case for self-signed certs. The code was adapted from the one in pve-apiclient, which we cannot reuse directly as it is only implemented for requests against PVE nodes, not as a generic HTTP client request helper. Add the new dependency `libio-socket-ssl-perl` required to get the verify callback for the TLS certificate used for cert-fingerprint checking. Signed-off-by: Hannes Duerr <h.duerr@proxmox.com> Tested-by: Stefan Hanreich <s.hanreich@proxmox.com> [TL: return valid for non-leaf certs and rewrite commit message] Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
-rw-r--r--debian/control1
-rw-r--r--src/PVE/Network/SDN.pm23
2 files changed, 22 insertions, 2 deletions
diff --git a/debian/control b/debian/control
index bb8cef9..34b7366 100644
--- a/debian/control
+++ b/debian/control
@@ -19,6 +19,7 @@ Package: libpve-network-perl
Architecture: all
Depends: libpve-common-perl (>= 5.0-45),
pve-cluster (>= 8.0.10),
+ libio-socket-ssl-perl,
libnet-subnet-perl,
libnet-ip-perl,
libnetaddr-ip-perl,
diff --git a/src/PVE/Network/SDN.pm b/src/PVE/Network/SDN.pm
index 1186d9e..8cd9ad8 100644
--- a/src/PVE/Network/SDN.pm
+++ b/src/PVE/Network/SDN.pm
@@ -3,7 +3,9 @@ package PVE::Network::SDN;
use strict;
use warnings;
+use IO::Socket::SSL; # important for SSL_verify_callback
use JSON;
+use Net::SSLeay;
use PVE::INotify;
@@ -256,7 +258,7 @@ sub encode_value {
#helpers
sub api_request {
- my ($method, $url, $headers, $data) = @_;
+ my ($method, $url, $headers, $data, $expected_fingerprint) = @_;
my $encoded_data = to_json($data) if $data;
@@ -270,7 +272,24 @@ sub api_request {
$ua->env_proxy;
}
- $ua->ssl_opts(verify_hostname => 0, SSL_verify_mode => 0x00);
+ if (defined($expected_fingerprint)) {
+ my $ssl_verify_callback = sub {
+ my (undef, undef, undef, undef, $cert, $depth) = @_;
+
+ # we don't care about intermediate or root certificates, always return as valid as the
+ # callback will be executed for all levels and all must be valid.
+ return 1 if $depth != 0;
+
+ my $fingerprint = Net::SSLeay::X509_get_fingerprint($cert, 'sha256');
+
+ return $fingerprint eq $expected_fingerprint ? 1 : 0;
+ };
+ $ua->ssl_opts(
+ verify_hostname => 0,
+ SSL_verify_mode => SSL_VERIFY_PEER,
+ SSL_verify_callback => $ssl_verify_callback,
+ );
+ }
my $response = $ua->request($req);