mirror of
https://git.proxmox.com/git/pve-manager
synced 2025-06-14 05:25:52 +00:00
takeover CertCache from pve-cluster
same code, same semantics, different file/module Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
parent
f1f4bfefc7
commit
0f9ac2dfc5
92
PVE/CertCache.pm
Normal file
92
PVE/CertCache.pm
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
package PVE::CertCache;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use Net::SSLeay;
|
||||||
|
|
||||||
|
use PVE::Cluster;
|
||||||
|
use PVE::SafeSyslog;
|
||||||
|
|
||||||
|
# X509 Certificate cache helper
|
||||||
|
|
||||||
|
my $cert_cache_nodes = {};
|
||||||
|
my $cert_cache_timestamp = time();
|
||||||
|
my $cert_cache_fingerprints = {};
|
||||||
|
|
||||||
|
sub update_cert_cache {
|
||||||
|
my ($update_node, $clear) = @_;
|
||||||
|
|
||||||
|
syslog('info', "Clearing outdated entries from certificate cache")
|
||||||
|
if $clear;
|
||||||
|
|
||||||
|
$cert_cache_timestamp = time() if !defined($update_node);
|
||||||
|
|
||||||
|
my $node_list = defined($update_node) ?
|
||||||
|
[ $update_node ] : [ keys %$cert_cache_nodes ];
|
||||||
|
|
||||||
|
foreach my $node (@$node_list) {
|
||||||
|
my $clear_old = sub {
|
||||||
|
if (my $old_fp = $cert_cache_nodes->{$node}) {
|
||||||
|
# distrust old fingerprint
|
||||||
|
delete $cert_cache_fingerprints->{$old_fp};
|
||||||
|
# ensure reload on next proxied request
|
||||||
|
delete $cert_cache_nodes->{$node};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
my $fp = eval { PVE::Cluster::get_node_fingerprint($node) };
|
||||||
|
if (my $err = $@) {
|
||||||
|
warn "$err\n";
|
||||||
|
&$clear_old() if $clear;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $old_fp = $cert_cache_nodes->{$node};
|
||||||
|
$cert_cache_fingerprints->{$fp} = 1;
|
||||||
|
$cert_cache_nodes->{$node} = $fp;
|
||||||
|
|
||||||
|
if (defined($old_fp) && $fp ne $old_fp) {
|
||||||
|
delete $cert_cache_fingerprints->{$old_fp};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# load and cache cert fingerprint once
|
||||||
|
sub initialize_cert_cache {
|
||||||
|
my ($node) = @_;
|
||||||
|
|
||||||
|
update_cert_cache($node)
|
||||||
|
if defined($node) && !defined($cert_cache_nodes->{$node});
|
||||||
|
}
|
||||||
|
|
||||||
|
sub check_cert_fingerprint {
|
||||||
|
my ($cert) = @_;
|
||||||
|
|
||||||
|
# clear cache every 30 minutes at least
|
||||||
|
update_cert_cache(undef, 1) if time() - $cert_cache_timestamp >= 60*30;
|
||||||
|
|
||||||
|
# get fingerprint of server certificate
|
||||||
|
my $fp = Net::SSLeay::X509_get_fingerprint($cert, 'sha256');
|
||||||
|
return 0 if !defined($fp) || $fp eq ''; # error
|
||||||
|
|
||||||
|
my $check = sub {
|
||||||
|
for my $expected (keys %$cert_cache_fingerprints) {
|
||||||
|
return 1 if $fp eq $expected;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
return 1 if &$check();
|
||||||
|
|
||||||
|
# clear cache and retry at most once every minute
|
||||||
|
if (time() - $cert_cache_timestamp >= 60) {
|
||||||
|
syslog ('info', "Could not verify remote node certificate '$fp' with list of pinned certificates, refreshing cache");
|
||||||
|
update_cert_cache();
|
||||||
|
return &$check();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
@ -11,6 +11,7 @@ use PVE::Exception qw(raise_param_exc raise);
|
|||||||
|
|
||||||
use PVE::RPCEnvironment;
|
use PVE::RPCEnvironment;
|
||||||
use PVE::AccessControl;
|
use PVE::AccessControl;
|
||||||
|
use PVE::CertCache;
|
||||||
use PVE::Cluster;
|
use PVE::Cluster;
|
||||||
use PVE::API2Tools;
|
use PVE::API2Tools;
|
||||||
|
|
||||||
@ -199,13 +200,13 @@ sub rest_handler {
|
|||||||
sub check_cert_fingerprint {
|
sub check_cert_fingerprint {
|
||||||
my ($self, $cert) = @_;
|
my ($self, $cert) = @_;
|
||||||
|
|
||||||
return PVE::Cluster::check_cert_fingerprint($cert);
|
return PVE::CertCache::check_cert_fingerprint($cert);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub initialize_cert_cache {
|
sub initialize_cert_cache {
|
||||||
my ($self, $node) = @_;
|
my ($self, $node) = @_;
|
||||||
|
|
||||||
PVE::Cluster::initialize_cert_cache($node);
|
PVE::CertCache::initialize_cert_cache($node);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub remote_node_ip {
|
sub remote_node_ip {
|
||||||
|
@ -7,6 +7,7 @@ PERLSOURCE = \
|
|||||||
API2Tools.pm \
|
API2Tools.pm \
|
||||||
APLInfo.pm \
|
APLInfo.pm \
|
||||||
AutoBalloon.pm \
|
AutoBalloon.pm \
|
||||||
|
CertCache.pm \
|
||||||
CertHelpers.pm \
|
CertHelpers.pm \
|
||||||
ExtMetric.pm \
|
ExtMetric.pm \
|
||||||
HTTPServer.pm \
|
HTTPServer.pm \
|
||||||
|
Loading…
Reference in New Issue
Block a user