]>
git.proxmox.com Git - pmg-api.git/blob - PMG/Cluster.pm
11 use PMG
::ClusterConfig
;
14 my ($nodename, $noerr) = @_;
16 my $cinfo = PVE
::INotify
::read_file
("cluster.conf");
18 foreach my $entry (values %{$cinfo->{ids
}}) {
19 if ($entry->{name
} eq $nodename) {
20 my $ip = $entry->{ip
};
21 return $ip if !wantarray;
22 my $family = PVE
::Tools
::get_host_address_family
($ip);
23 return ($ip, $family);
27 # fallback: try to get IP by other means
28 return PMG
::Utils
::lookup_node_ip
($nodename, $noerr);
34 $cinfo = PVE
::INotify
::read_file
("cluster.conf");
36 return $cinfo->{master
}->{name
} if defined($cinfo->{master
});
41 # X509 Certificate cache helper
43 my $cert_cache_nodes = {};
44 my $cert_cache_timestamp = time();
45 my $cert_cache_fingerprints = {};
47 sub update_cert_cache
{
48 my ($update_node, $clear) = @_;
50 syslog
('info', "Clearing outdated entries from certificate cache")
53 $cert_cache_timestamp = time() if !defined($update_node);
55 my $node_list = defined($update_node) ?
56 [ $update_node ] : [ keys %$cert_cache_nodes ];
58 my $clear_node = sub {
60 if (my $old_fp = $cert_cache_nodes->{$node}) {
61 # distrust old fingerprint
62 delete $cert_cache_fingerprints->{$old_fp};
63 # ensure reload on next proxied request
64 delete $cert_cache_nodes->{$node};
68 my $nodename = PVE
::INotify
::nodename
();
70 foreach my $node (@$node_list) {
72 if ($node ne $nodename) {
73 &$clear_node($node) if $clear;
77 my $cert_path = "/etc/pmg/pmg-api.pem";
81 my $bio = Net
::SSLeay
::BIO_new_file
($cert_path, 'r');
82 $cert = Net
::SSLeay
::PEM_read_bio_X509
($bio);
83 Net
::SSLeay
::BIO_free
($bio);
86 if ($err || !defined($cert)) {
87 &$clear_node($node) if $clear;
93 $fp = Net
::SSLeay
::X509_get_fingerprint
($cert, 'sha256');
96 if ($err || !defined($fp) || $fp eq '') {
97 &$clear_node($node) if $clear;
101 my $old_fp = $cert_cache_nodes->{$node};
102 $cert_cache_fingerprints->{$fp} = 1;
103 $cert_cache_nodes->{$node} = $fp;
105 if (defined($old_fp) && $fp ne $old_fp) {
106 delete $cert_cache_fingerprints->{$old_fp};
111 # load and cache cert fingerprint once
112 sub initialize_cert_cache
{
115 update_cert_cache
($node)
116 if defined($node) && !defined($cert_cache_nodes->{$node});
119 sub check_cert_fingerprint
{
122 # clear cache every 30 minutes at least
123 update_cert_cache
(undef, 1) if time() - $cert_cache_timestamp >= 60*30;
125 # get fingerprint of server certificate
128 $fp = Net
::SSLeay
::X509_get_fingerprint
($cert, 'sha256');
130 return 0 if $@ || !defined($fp) || $fp eq ''; # error
133 for my $expected (keys %$cert_cache_fingerprints) {
134 return 1 if $fp eq $expected;
139 return 1 if &$check();
141 # clear cache and retry at most once every minute
142 if (time() - $cert_cache_timestamp >= 60) {
143 syslog
('info', "Could not verify remote node certificate '$fp' with list of pinned certificates, refreshing cache");