]> git.proxmox.com Git - pve-http-server.git/commitdiff
access control: correctly match v4-mapped-v6 addresses
authorStoiko Ivanov <s.ivanov@proxmox.com>
Wed, 5 May 2021 14:36:26 +0000 (16:36 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Fri, 7 May 2021 15:47:46 +0000 (17:47 +0200)
With recent changes to the listening socket code in pve-manager
the proxy daemons now usually bind to '::' and ipv4 clients are
read as v4-mapped-v6 addresses [0] from ::ffff:0:0/96.

This caused the allow_from/deny_from matching to break.

This patch addresses the issue by normalizing addresses from
::ffff:0:0/96 using Net::IP::ip_get_embedded_ipv4
(which roughly splits on ':' and checks if the last part looks like an
ipv4 address).

Issue was originally reported in our community forum [1]

[0] https://en.wikipedia.org/wiki/IPv6_address
[1] https://forum.proxmox.com/threads/my-pveproxy-file-doesnt-work.83228/

Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
PVE/APIServer/AnyEvent.pm
PVE/APIServer/Utils.pm

index 0654bd4901fd45e0cbdf64e5a9a70d62521d0e84..f0e2e68739f6b83740a77e54dd1031d7032939aa 100644 (file)
@@ -34,6 +34,7 @@ use PVE::SafeSyslog;
 use PVE::INotify;
 use PVE::Tools;
 use PVE::APIServer::Formatter;
+use PVE::APIServer::Utils;
 
 use Net::IP;
 use URI;
@@ -1662,6 +1663,7 @@ sub wait_end_loop {
 sub check_host_access {
     my ($self, $clientip) = @_;
 
+    $clientip = PVE::APIServer::Utils::normalize_v4_in_v6($clientip);
     my $cip = Net::IP->new($clientip);
 
     if (!$cip) {
index 36e3ae63b1c1f126b2293d63d11e4ea8c505aa79..8470f803425b89ac06cbb5e8f6cd45f218cf5dbc 100644 (file)
@@ -34,7 +34,7 @@ sub read_proxy_config {
            my $ips = [];
            foreach my $ip (split(/,/, $value)) {
                $ip = "0/0" if $ip eq 'all';
-               push @$ips, Net::IP->new($ip) || die Net::IP::Error() . "\n";
+               push @$ips, Net::IP->new(normalize_v4_in_v6($ip)) || die Net::IP::Error() . "\n";
            }
            $res->{$key} = $ips;
        } elsif ($key eq 'LISTEN_IP') {
@@ -57,4 +57,15 @@ sub read_proxy_config {
     return $res;
 }
 
+sub normalize_v4_in_v6 {
+    my ($ip_text) = @_;
+
+    my $ip = Net::IP->new($ip_text) || die Net::IP::Error() . "\n";
+    my $v4_mapped_v6_prefix = Net::IP->new('::ffff:0:0/96');
+    if ($v4_mapped_v6_prefix->overlaps($ip)) {
+       return Net::IP::ip_get_embedded_ipv4($ip_text);
+    }
+    return $ip_text;
+}
+
 1;