From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <pve-devel-bounces@lists.proxmox.com>
Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9])
	by lore.proxmox.com (Postfix) with ESMTPS id D6D221FF16B
	for <inbox@lore.proxmox.com>; Thu, 12 Dec 2024 04:28:16 +0100 (CET)
Received: from firstgate.proxmox.com (localhost [127.0.0.1])
	by firstgate.proxmox.com (Proxmox) with ESMTP id D240E121B2;
	Thu, 12 Dec 2024 04:28:21 +0100 (CET)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1733974062; x=1734578862;
 h=content-transfer-encoding:mime-version:references:in-reply-to
 :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
 :subject:date:message-id:reply-to;
 bh=jZ9WM6WERksiFZd3wGekab0dpWsDfWJyWnw+if/Y2U4=;
 b=JFheS3XH7mmnlGpQs3af7XYnLZKb1Fzbn2Dm7NMkosMKPtGPhAriTieGOJG9APglw3
 l30Lrae/KLAN4CgpsoSvcRQZa/VdtuOyPRVDLHbXb6U4ev32xse9Kd31sw7ry6l+iyrg
 sBUBI6n+JOWcnPbq/TbQQJ63qSnPncvdqiCRL8mzDdqAlsMhcO2+/KwcK5fWcNjJfTr+
 5vAol81g7Qsm6EalrBmWYIwNTyqdHe9dLGqNEPkGAPthp/JqDEKUWOxFBOpn9LHl0/dA
 CvWHIU8MLcnDScQVazgk3FVk6j0vfxJDq/d0oMmcN+gqwt6F31n6rd+kML2rA8MDzKea
 +Ccw==
X-Gm-Message-State: AOJu0YyWbQr6a2k8UkpQgopSNo8SeTDJ74VQ/YnEUGVNKao+iWdrO46R
 lsGNd3yKn/WaweFGkocmhqP646CHO+bOZj4KorcN4HhnbBHx3Zi87UolALva
X-Gm-Gg: ASbGncsJcyhrqkR6DWYjDVncCz2BjOCFZq6SeQTBMnQTwCnQmgvTVUX0VVPVzV45Ol6
 Q0yLRe8fI5+tsCBc9op29atKu7eNBRFx6gjtJg3piZynw+8HpchaY5+cqswfcxyc/QgcEZ/DuUq
 e6Kis+Y86TiVrt+d1oswckGG3wd0DjLeST0gGHbrzEvlN9eaIyN+qf0LowkdpQL/iOK2EJDHGLG
 30ni5ojZxz1GAt4BklRnlN88rpUDJNOmhUOwE9ar7rVxhbPid68EzdgfeNSg9gB06RIYexvnzhP
 tIEMl/5IHsWFVYVhLnCFYo/Jdkmg9C5fgLpVHTB4K9e/neBp8/Xn/0dsfltc72LPn52TWw==
X-Google-Smtp-Source: AGHT+IHG6YOQC+hWsMFzJGWAg8iCrR+nkj9Wc1ZuEQ+j/5kcazRcRbSCJ4S2v+ddQwE5Amloo5n8oA==
X-Received: by 2002:a05:6902:1104:b0:e3c:9f89:fd65 with SMTP id
 3f1490d57ef6-e3dabcbca0amr1722542276.46.1733974062588; 
 Wed, 11 Dec 2024 19:27:42 -0800 (PST)
From: Thomas Skinner <thomas@atskinner.net>
To: pve-devel@lists.proxmox.com
Date: Wed, 11 Dec 2024 21:27:05 -0600
Message-Id: <20241212032706.151121-3-thomas@atskinner.net>
X-Mailer: git-send-email 2.39.5
In-Reply-To: <20241212032706.151121-1-thomas@atskinner.net>
References: <20241212032706.151121-1-thomas@atskinner.net>
MIME-Version: 1.0
X-SPAM-LEVEL: Spam detection results:  0
 AWL 0.027 Adjusted score from AWL reputation of From: address
 BAYES_00                 -1.9 Bayes spam probability is 0 to 1%
 DMARC_MISSING             0.1 Missing DMARC policy
 FREEMAIL_FORGED_FROMDOMAIN 0.001 2nd level domains in From and EnvelopeFrom
 freemail headers are different
 FREEMAIL_FROM 0.001 Sender email is commonly abused enduser mail provider
 HEADER_FROM_DIFFERENT_DOMAINS 0.249 From and EnvelopeFrom 2nd level mail
 domains are different
 KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment
 RCVD_IN_DNSWL_NONE     -0.0001 Sender listed at https://www.dnswl.org/,
 no trust RCVD_IN_MSPIKE_H2      -0.001 Average reputation (+2)
 SPF_HELO_NONE           0.001 SPF: HELO does not publish an SPF Record
 SPF_PASS               -0.001 SPF: sender matches SPF record
Subject: [pve-devel] [PATCH http-server v2 2/3] fix #5699: pveproxy: add
 library methods for real IP support
X-BeenThere: pve-devel@lists.proxmox.com
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com>
List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe>
List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/>
List-Post: <mailto:pve-devel@lists.proxmox.com>
List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help>
List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, 
 <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe>
Reply-To: Proxmox VE development discussion <pve-devel@lists.proxmox.com>
Cc: Thomas Skinner <thomas@atskinner.net>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit
Errors-To: pve-devel-bounces@lists.proxmox.com
Sender: "pve-devel" <pve-devel-bounces@lists.proxmox.com>

Signed-off-by: Thomas Skinner <thomas@atskinner.net>
---
 src/PVE/APIServer/AnyEvent.pm | 38 ++++++++++++++++++++++++++++++++++-
 src/PVE/APIServer/Utils.pm    | 15 ++++++++++++++
 2 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/src/PVE/APIServer/AnyEvent.pm b/src/PVE/APIServer/AnyEvent.pm
index 24209a1..5f15a13 100644
--- a/src/PVE/APIServer/AnyEvent.pm
+++ b/src/PVE/APIServer/AnyEvent.pm
@@ -92,13 +92,14 @@ sub log_request {
     $loginfo->{written} = 1;
 
     my $peerip = $reqstate->{peer_host} || '-';
+    my $realip = $loginfo->{real_ip} || $peerip;
     my $userid = $loginfo->{userid} || '-';
     my $content_length = defined($loginfo->{content_length}) ? $loginfo->{content_length} : '-';
     my $code =  $loginfo->{code} || 500;
     my $requestline = $loginfo->{requestline} || '-';
     my $timestr = strftime("%d/%m/%Y:%H:%M:%S %z", localtime());
 
-    my $msg = "$peerip - $userid [$timestr] \"$requestline\" $code $content_length\n";
+    my $msg = "$realip - $userid [$timestr] \"$requestline\" $code $content_length\n";
 
     $self->write_log($msg);
 }
@@ -1474,6 +1475,18 @@ sub authenticate_and_handle_request {
 
     my $auth = {};
 
+    if (my $proxy_real_ip_header = $self->{proxy_real_ip_header}) {
+	if (my $proxy_real_ip_value = $request->header($proxy_real_ip_header)) {
+	    my $real_ip = Net::IP->new($proxy_real_ip_value);
+	    if (defined($real_ip) && $self->check_allowed_proxy($reqstate->{peer_host})) {
+		$reqstate->{log}->{real_ip} = Net::IP::ip_compress_address(
+		    $real_ip->ip(), 
+		    $real_ip->version(),
+		);
+	    }
+	}
+    }
+
     if ($self->{spiceproxy}) {
 	my $connect_str = $request->header('Host');
 	my ($vmid, $node, $port) = $self->verify_spice_connect_url($connect_str);
@@ -1813,6 +1826,29 @@ sub check_host_access {
     return $match_allow;
 }
 
+sub check_allowed_proxy {
+    my ($self, $client_ip) = @_;
+
+    $client_ip = PVE::APIServer::Utils::normalize_v4_in_v6($client_ip);
+    my $client_ip_object = Net::IP->new($client_ip);
+
+    if (!$client_ip_object) {
+	$self->dprint("client IP not parsable: $@");
+	return 0;
+    }
+
+    if (my $proxy_real_ip_allow_from = $self->{proxy_real_ip_allow_from}) {
+	for my $allowed_net ($proxy_real_ip_allow_from->@*) {
+	    if ($allowed_net->overlaps($client_ip_object)) {
+		$self->dprint("client IP in allowed proxies: ". $allowed_net->print());
+		return 1;
+	    }
+	}
+	return 0;
+    }
+    return 1;
+}
+
 sub accept_connections {
     my ($self) = @_;
 
diff --git a/src/PVE/APIServer/Utils.pm b/src/PVE/APIServer/Utils.pm
index 5728d97..75f72a1 100644
--- a/src/PVE/APIServer/Utils.pm
+++ b/src/PVE/APIServer/Utils.pm
@@ -26,6 +26,8 @@ sub read_proxy_config {
     $shcmd .= 'echo \"COMPRESSION:\$COMPRESSION\";';
     $shcmd .= 'echo \"DISABLE_TLS_1_2:\$DISABLE_TLS_1_2\";';
     $shcmd .= 'echo \"DISABLE_TLS_1_3:\$DISABLE_TLS_1_3\";';
+    $shcmd .= 'echo \"PROXY_REAL_IP_HEADER:\$PROXY_REAL_IP_HEADER\";';
+    $shcmd .= 'echo \"PROXY_REAL_IP_ALLOW_FROM:\$PROXY_REAL_IP_ALLOW_FROM\";';
 
     my $data = -f $conffile ? `bash -c "$shcmd"` : '';
 
@@ -65,6 +67,19 @@ sub read_proxy_config {
 	    $res->{$key} = $value;
 	} elsif ($key eq 'TLS_KEY_FILE') {
 	    $res->{$key} = $value;
+	} elsif ($key eq 'PROXY_REAL_IP_HEADER') {
+	    $res->{$key} = $value;
+	} elsif ($key eq 'PROXY_REAL_IP_ALLOW_FROM') {
+	    my $ips = [];
+	    for my $ip (split(/,/, $value)) {
+		if ($ip eq 'all') {
+		    push @$ips, Net::IP->new('0/0') || die Net::IP::Error() . "\n";
+		    push @$ips, Net::IP->new('::/0') || die Net::IP::Error() . "\n";
+		    next;
+		}
+		push @$ips, Net::IP->new(normalize_v4_in_v6($ip)) || die Net::IP::Error() . "\n";
+	    }
+	    $res->{$key} = $ips;
 	} elsif (grep { $key eq $_ } @$boolean_options) {
 	    die "unknown value '$value' - use 0 or 1\n" if $value !~ m/^(0|1)$/;
 	    $res->{$key} = $value;
-- 
2.39.5


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel