public inbox for pmg-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [PATCH pmg-api/pmg-gui/pmg-docs 0/6] fix #8231: mail proxy: make automatically trusted networks visible and the local network optional
@ 2026-10-26  9:58 Carsten Haerle
  2026-10-26  9:58 ` [PATCH pmg-api 1/6] fix #8231: config: add option to not trust the local network automatically Carsten Haerle
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Carsten Haerle @ 2026-10-26  9:58 UTC (permalink / raw)
  To: pmg-devel; +Cc: Carsten Haerle

Besides the networks configured under Mail Proxy > Networks, PMG adds the
network of the node's IP address, the default relay and all transport
hosts (if configured as IP address) to postfix' mynetworks. All hosts in
it may relay through the internal port to any destination. None of these
entries is shown in the GUI, so the Networks panel can be empty while a
whole /24 is trusted, and the local network can only be removed by
overriding the main.cf template.

This series
- adds the option 'trust_local_network' (default 1, current behaviour
  unchanged) to stop trusting the local network automatically,
- lets the mynetworks API optionally list the automatic entries with
  their origin ('automatic=1', without it the result is unchanged),
- shows them greyed out in the Networks panel, with a comment that tells
  where each one is configured,
- resolves default relay and transport hosts configured by host name, so
  that they are trusted like hosts configured by address (pmg-api 4/6),
- documents all of this.

The default relay and transport hosts stay trusted unconditionally, as
they are the mail servers that send outgoing mail through the internal
port in the recommended setup.

Patch 4/6 changes existing installations that use host names for the
default relay or transports (these hosts can now relay, as they could if
configured by address), so it is a separate patch and can be considered
on its own. The docs patch describes the behaviour with it applied.
The GUI patch (5/6) depends on pmg-api 3/6.

Tested on a single-node PMG 9.1 (pmg-api 9.1.4, pmg-gui 5.2.3):
- option on: generated mynetworks identical to before
- option off: a host of the local network gets "454 4.7.1 Relay access
  denied" on port 26 for external recipients; an explicitly configured
  host of the same network may still relay
- API without parameter returns the configured networks only; with
  automatic=1 also local network, default relay and transport hosts with
  their origin
- default relay and transport by host name are resolved and listed with
  the name; a name that cannot be resolved is skipped with one warning per
  config sync

While testing I noticed that adding, changing or removing a transport
only runs postmap on the transport map but does not regenerate main.cf,
so the transport host's mynetworks entry is only updated with the next
full config sync. That is independent of this series and sent
as a separate patch for the same bug.

pmg-api:
Carsten Haerle (4):
      fix #8231: config: add option to not trust the local network automatically
      config: factor out automatically trusted networks
      fix #8231: api: mynetworks: optionally list automatically trusted networks
      fix #8231: config: resolve relay and transport host names for mynetworks

 src/PMG/API2/MyNetworks.pm |  47 ++++++++++++++-
 src/PMG/Config.pm          | 144 ++++++++++++++++++++++++++++++++-------------
 2 files changed, 150 insertions(+), 41 deletions(-)

pmg-gui:
Carsten Haerle (1):
      fix #8231: mail proxy: add trust local network option, show automatic networks

 js/MailProxyOptions.js | 4 ++++
 js/MyNetworks.js       | 9 +++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

pmg-docs:
Carsten Haerle (1):
      mail proxy: networks: document automatically trusted networks

 pmgconfig.adoc | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

-- 
2.53.0







^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH pmg-api 1/6] fix #8231: config: add option to not trust the local network automatically
  2026-10-26  9:58 [PATCH pmg-api/pmg-gui/pmg-docs 0/6] fix #8231: mail proxy: make automatically trusted networks visible and the local network optional Carsten Haerle
@ 2026-10-26  9:58 ` Carsten Haerle
  2026-10-26  9:58 ` [PATCH pmg-api 2/6] config: factor out automatically trusted networks Carsten Haerle
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Carsten Haerle @ 2026-10-26  9:58 UTC (permalink / raw)
  To: pmg-devel; +Cc: Carsten Haerle

The network of the node's IP address is always added to postfix'
mynetworks, so every host in it may relay mail through the internal
port to any destination. This is not visible in the GUI and can only be
changed by overriding the main.cf template, which then has to be kept
in sync with every update.

Add the 'trust_local_network' option to the mail section. It defaults
to 1, keeping the current behaviour. If disabled, only loopback, the
default relay, transport hosts and the configured networks are trusted.

Signed-off-by: Carsten Haerle <carsten.haerle@straightec.de>
---
 src/PMG/Config.pm | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/PMG/Config.pm b/src/PMG/Config.pm
index 070a34f..655a433 100644
--- a/src/PMG/Config.pm
+++ b/src/PMG/Config.pm
@@ -695,6 +695,14 @@ sub properties {
             type => 'boolean',
             default => 0,
         },
+        trust_local_network => {
+            description => "Trust the network of the node's IP address, that is, allow all"
+                . " hosts in it to relay mail through the internal port. If disabled, only"
+                . " the default relay, transport hosts and the configured networks are"
+                . " trusted.",
+            type => 'boolean',
+            default => 1,
+        },
         maxsize => {
             description =>
                 "Maximum email size. Larger mails are rejected. (postfix option `message_size_limit`)",
@@ -876,6 +884,7 @@ sub options {
         max_filters => { optional => 1 },
         max_policy => { optional => 1 },
         hide_received => { optional => 1 },
+        trust_local_network => { optional => 1 },
         rejectunknown => { optional => 1 },
         rejectunknownsender => { optional => 1 },
         conn_count_limit => { optional => 1 },
@@ -1578,7 +1587,8 @@ sub get_template_vars {
 
     $vars->{postfix}->{transportnets} = join(' ', sort keys %$transportnets);
 
-    if (defined($int_ip)) { # we cannot really do anything and the loopback nets are already added
+    # without an IP we cannot really do anything and the loopback nets are already added
+    if (defined($int_ip) && $self->get('mail', 'trust_local_network')) {
         if (my $int_net_cidr = PMG::Utils::find_local_network_for_ip($int_ip, 1)) {
             if ($int_net_cidr =~ m/^($IPV6RE)\/(\d+)$/) {
                 $mynetworks->{"[$1]/$2"} = 1;
-- 
2.53.0








^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH pmg-api 2/6] config: factor out automatically trusted networks
  2026-10-26  9:58 [PATCH pmg-api/pmg-gui/pmg-docs 0/6] fix #8231: mail proxy: make automatically trusted networks visible and the local network optional Carsten Haerle
  2026-10-26  9:58 ` [PATCH pmg-api 1/6] fix #8231: config: add option to not trust the local network automatically Carsten Haerle
@ 2026-10-26  9:58 ` Carsten Haerle
  2026-10-26  9:58 ` [PATCH pmg-api 3/6] fix #8231: api: mynetworks: optionally list " Carsten Haerle
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Carsten Haerle @ 2026-10-26  9:58 UTC (permalink / raw)
  To: pmg-devel; +Cc: Carsten Haerle

Move the computation of the networks that are added to mynetworks
automatically (local network, default relay, transport hosts) from
get_template_vars() into get_automatic_mynetworks(), which also records
where each entry comes from. This allows the API to show these entries,
so that the GUI can display what postfix actually trusts.

No functional change intended.

Signed-off-by: Carsten Haerle <carsten.haerle@straightec.de>
---
 src/PMG/Config.pm | 95 +++++++++++++++++++++++++++--------------------
 1 file changed, 54 insertions(+), 41 deletions(-)

diff --git a/src/PMG/Config.pm b/src/PMG/Config.pm
index 655a433..e01d4d7 100644
--- a/src/PMG/Config.pm
+++ b/src/PMG/Config.pm
@@ -1555,6 +1555,55 @@ sub get_host_dns_info {
     return $dnsinfo;
 }
 
+# Networks trusted automatically, in addition to loopback and the configured
+# networks. Returns a hash: cidr => { local => 1, relay => 1, transport => [domains] }
+sub get_automatic_mynetworks {
+    my ($self, $int_ip) = @_;
+
+    my $res = {};
+
+    if (my $tmap = PVE::INotify::read_file('transport')) {
+        foreach my $domain (sort keys %$tmap) {
+            my $host = $tmap->{$domain}->{host};
+            my $cidr;
+            if ($host =~ m/^$IPV4RE$/) {
+                $cidr = "$host/32";
+            } elsif ($host =~ m/^(?:ipv6:)?($IPV6RE)$/i) {
+                $cidr = "[$1]/128";
+            }
+            push $res->{$cidr}->{transport}->@*, $domain if defined($cidr);
+        }
+    }
+
+    # without an IP we cannot really do anything and the loopback nets are always trusted
+    if (defined($int_ip) && $self->get('mail', 'trust_local_network')) {
+        my $cidr;
+        if (my $int_net_cidr = PMG::Utils::find_local_network_for_ip($int_ip, 1)) {
+            if ($int_net_cidr =~ m/^($IPV6RE)\/(\d+)$/) {
+                $cidr = "[$1]/$2";
+            } else {
+                $cidr = $int_net_cidr;
+            }
+        } elsif ($int_ip =~ m/^$IPV6RE$/) {
+            $cidr = "[$int_ip]/128";
+        } else {
+            $cidr = "$int_ip/32";
+        }
+        $res->{$cidr}->{local} = 1;
+    }
+
+    # host names are not resolved, they are not trusted automatically
+    if (my $relay = $self->get('mail', 'relay')) {
+        if ($relay =~ m/^$IPV4RE$/) {
+            $res->{"$relay/32"}->{relay} = 1;
+        } elsif ($relay =~ m/^$IPV6RE$/) {
+            $res->{"[$relay]/128"}->{relay} = 1;
+        }
+    }
+
+    return $res;
+}
+
 sub get_template_vars {
     my ($self) = @_;
 
@@ -1565,45 +1614,20 @@ sub get_template_vars {
     my $int_ip = PMG::Cluster::remote_node_ip($dnsinfo->{hostname});
     $vars->{ipconfig}->{int_ip} = $int_ip;
 
+    my $automatic = $self->get_automatic_mynetworks($int_ip);
+
     my $transportnets = {};
     my $mynetworks = {
         '127.0.0.0/8' => 1,
         '[::1]/128', => 1,
     };
-
-    if (my $tmap = PVE::INotify::read_file('transport')) {
-        foreach my $domain (keys %$tmap) {
-            my $data = $tmap->{$domain};
-            my $host = $data->{host};
-            if ($host =~ m/^$IPV4RE$/) {
-                $transportnets->{"$host/32"} = 1;
-                $mynetworks->{"$host/32"} = 1;
-            } elsif ($host =~ m/^(?:ipv6:)?($IPV6RE)$/i) {
-                $transportnets->{"[$1]/128"} = 1;
-                $mynetworks->{"[$1]/128"} = 1;
-            }
-        }
+    foreach my $cidr (keys %$automatic) {
+        $mynetworks->{$cidr} = 1;
+        $transportnets->{$cidr} = 1 if $automatic->{$cidr}->{transport};
     }
 
     $vars->{postfix}->{transportnets} = join(' ', sort keys %$transportnets);
 
-    # without an IP we cannot really do anything and the loopback nets are already added
-    if (defined($int_ip) && $self->get('mail', 'trust_local_network')) {
-        if (my $int_net_cidr = PMG::Utils::find_local_network_for_ip($int_ip, 1)) {
-            if ($int_net_cidr =~ m/^($IPV6RE)\/(\d+)$/) {
-                $mynetworks->{"[$1]/$2"} = 1;
-            } else {
-                $mynetworks->{$int_net_cidr} = 1;
-            }
-        } else {
-            if ($int_ip =~ m/^$IPV6RE$/) {
-                $mynetworks->{"[$int_ip]/128"} = 1;
-            } else {
-                $mynetworks->{"$int_ip/32"} = 1;
-            }
-        }
-    }
-
     my $netlist = PVE::INotify::read_file('mynetworks');
     foreach my $cidr (keys %$netlist) {
         my $ip = PVE::Network::IP_from_cidr($cidr);
@@ -1618,17 +1642,6 @@ sub get_template_vars {
         }
     }
 
-    # add default relay to mynetworks
-    if (my $relay = $self->get('mail', 'relay')) {
-        if ($relay =~ m/^$IPV4RE$/) {
-            $mynetworks->{"$relay/32"} = 1;
-        } elsif ($relay =~ m/^$IPV6RE$/) {
-            $mynetworks->{"[$relay]/128"} = 1;
-        } else {
-            # DNS name - do nothing ?
-        }
-    }
-
     $vars->{postfix}->{mynetworks} = join(' ', sort keys %$mynetworks);
 
     # normalize dnsbl_sites
-- 
2.53.0








^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH pmg-api 3/6] fix #8231: api: mynetworks: optionally list automatically trusted networks
  2026-10-26  9:58 [PATCH pmg-api/pmg-gui/pmg-docs 0/6] fix #8231: mail proxy: make automatically trusted networks visible and the local network optional Carsten Haerle
  2026-10-26  9:58 ` [PATCH pmg-api 1/6] fix #8231: config: add option to not trust the local network automatically Carsten Haerle
  2026-10-26  9:58 ` [PATCH pmg-api 2/6] config: factor out automatically trusted networks Carsten Haerle
@ 2026-10-26  9:58 ` Carsten Haerle
  2026-10-26  9:58 ` [PATCH pmg-api 4/6] fix #8231: config: resolve relay and transport host names for mynetworks Carsten Haerle
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Carsten Haerle @ 2026-10-26  9:58 UTC (permalink / raw)
  To: pmg-devel; +Cc: Carsten Haerle

With 'automatic=1' the index also returns the networks that are added
to mynetworks automatically, marked with 'automatic: 1' and a comment
that tells where each entry comes from and where it is configured. A
configured entry for the same network takes precedence.

Without the parameter the result is unchanged, so existing API users
that iterate over and modify the list are not affected.

Signed-off-by: Carsten Haerle <carsten.haerle@straightec.de>
---
 src/PMG/API2/MyNetworks.pm | 44 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/src/PMG/API2/MyNetworks.pm b/src/PMG/API2/MyNetworks.pm
index 565b6f8..30bf448 100644
--- a/src/PMG/API2/MyNetworks.pm
+++ b/src/PMG/API2/MyNetworks.pm
@@ -11,6 +11,7 @@ use PVE::JSONSchema qw(get_standard_option);
 use PVE::RESTHandler;
 use PVE::INotify;
 
+use PMG::Cluster;
 use PMG::Config;
 
 use base qw(PVE::RESTHandler);
@@ -25,7 +26,15 @@ __PACKAGE__->register_method({
     permissions => { check => ['admin', 'audit'] },
     parameters => {
         additionalProperties => 0,
-        properties => {},
+        properties => {
+            automatic => {
+                description => "Also list the networks that are trusted automatically"
+                    . " (local network, default relay, transport hosts).",
+                type => 'boolean',
+                optional => 1,
+                default => 0,
+            },
+        },
     },
     returns => {
         type => 'array',
@@ -33,6 +42,12 @@ __PACKAGE__->register_method({
             type => "object",
             properties => {
                 cidr => { type => 'string' },
+                comment => { type => 'string', optional => 1 },
+                automatic => {
+                    description => "Trusted automatically, cannot be modified here.",
+                    type => 'boolean',
+                    optional => 1,
+                },
             },
         },
         links => [{ rel => 'child', href => "{cidr}" }],
@@ -48,6 +63,33 @@ __PACKAGE__->register_method({
             push @$res, $mynetworks->{$cidr};
         }
 
+        return $res if !$param->{automatic};
+
+        my $cfg = PMG::Config->new();
+        my $nodename = PVE::INotify::nodename();
+        my $int_ip = PMG::Cluster::remote_node_ip($nodename);
+        my $automatic = $cfg->get_automatic_mynetworks($int_ip);
+
+        foreach my $cidr (sort keys %$automatic) {
+            next if $mynetworks->{$cidr}; # a configured entry takes precedence
+
+            my $origin = $automatic->{$cidr};
+            my @why;
+            push @why, "local network of node '$nodename' (Options: Trust Local Network)"
+                if $origin->{local};
+            push @why, "default relay (Relaying)" if $origin->{relay};
+            if (my $domains = $origin->{transport}) {
+                push @why, "transport for " . join(', ', $domains->@*) . " (Transports)";
+            }
+
+            my $entry = {
+                cidr => $cidr,
+                comment => 'automatic: ' . join('; ', @why),
+                automatic => 1,
+            };
+            push @$res, $entry;
+        }
+
         return $res;
     },
 });
-- 
2.53.0








^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH pmg-api 4/6] fix #8231: config: resolve relay and transport host names for mynetworks
  2026-10-26  9:58 [PATCH pmg-api/pmg-gui/pmg-docs 0/6] fix #8231: mail proxy: make automatically trusted networks visible and the local network optional Carsten Haerle
                   ` (2 preceding siblings ...)
  2026-10-26  9:58 ` [PATCH pmg-api 3/6] fix #8231: api: mynetworks: optionally list " Carsten Haerle
@ 2026-10-26  9:58 ` Carsten Haerle
  2026-10-26  9:58 ` [PATCH pmg-gui 5/6] fix #8231: mail proxy: add trust local network option, show automatic networks Carsten Haerle
  2026-10-26  9:58 ` [PATCH pmg-docs 6/6] mail proxy: networks: document automatically trusted networks Carsten Haerle
  5 siblings, 0 replies; 7+ messages in thread
From: Carsten Haerle @ 2026-10-26  9:58 UTC (permalink / raw)
  To: pmg-devel; +Cc: Carsten Haerle

The default relay and the transport hosts are added to mynetworks, as
they are the mail servers that send outgoing mail through the internal
port. This only happened if they were configured as IP address. For a
host name nothing was added, so the same mail server was trusted or not
depending on whether it was entered by address or by name.

Resolve host names when the configuration is generated and add all their
addresses. If the address of such a host changes, this takes effect with
the next regeneration (configuration change, sync, boot). If a name
cannot be resolved, it is skipped with a warning, which is the same as
before. As the template variables are computed for every rendered
template, resolved names are cached for 60 seconds, so that a config
sync looks up (and warns) once instead of once per template.

Note that this extends the trusted networks on installations that use
host names for the default relay or transports: these mail servers can
now relay through the internal port, as they could if configured by
address.

The Networks list shows the host name the entry was resolved from.

Signed-off-by: Carsten Haerle <carsten.haerle@straightec.de>
---
 src/PMG/API2/MyNetworks.pm |  3 ++
 src/PMG/Config.pm          | 65 +++++++++++++++++++++++++++++++-------
 2 files changed, 56 insertions(+), 12 deletions(-)

diff --git a/src/PMG/API2/MyNetworks.pm b/src/PMG/API2/MyNetworks.pm
index 30bf448..bfb6183 100644
--- a/src/PMG/API2/MyNetworks.pm
+++ b/src/PMG/API2/MyNetworks.pm
@@ -81,6 +81,9 @@ __PACKAGE__->register_method({
             if (my $domains = $origin->{transport}) {
                 push @why, "transport for " . join(', ', $domains->@*) . " (Transports)";
             }
+            if (my $names = $origin->{names}) {
+                push @why, "resolved from '" . join("', '", sort keys $names->%*) . "'";
+            }
 
             my $entry = {
                 cidr => $cidr,
diff --git a/src/PMG/Config.pm b/src/PMG/Config.pm
index e01d4d7..e579334 100644
--- a/src/PMG/Config.pm
+++ b/src/PMG/Config.pm
@@ -913,6 +913,7 @@ use Template;
 
 use PVE::SafeSyslog;
 use PVE::Tools qw($IPV4RE $IPV6RE);
+use Socket qw(AF_INET6 SOCK_STREAM);
 use PVE::INotify;
 use PVE::JSONSchema;
 
@@ -1555,8 +1556,51 @@ sub get_host_dns_info {
     return $dnsinfo;
 }
 
+# The template variables are computed for every rendered template, so cache
+# resolved host names for a short time to look up (and warn) once per run.
+my $resolved_hosts = {};
+
+# Returns the networks to trust for a relay or transport host: the address itself
+# or all addresses of a host name. Host names are resolved now, so a changed address
+# only takes effect with the next regeneration of the configuration.
+sub mynetworks_for_host {
+    my ($host) = @_;
+
+    return ("$host/32") if $host =~ m/^$IPV4RE$/;
+    return ("[$1]/128") if $host =~ m/^(?:ipv6:)?($IPV6RE)$/i;
+
+    my $cached = $resolved_hosts->{$host};
+    return $cached->{cidrs}->@* if $cached && time() - $cached->{time} < 60;
+
+    my $cidrs = {};
+    $resolved_hosts->{$host} = { time => time(), cidrs => [] };
+
+    my @addrinfo = eval { PVE::Tools::getaddrinfo_all($host, socktype => SOCK_STREAM) };
+    if (my $err = $@) {
+        warn "not adding '$host' to trusted networks - $err";
+        return ();
+    }
+
+    for my $ai (@addrinfo) {
+        my ($family, undef, $addr) = PVE::Tools::unpack_sockaddr_in46($ai->{addr});
+        my $ip = Socket::inet_ntop($family, $addr);
+        if ($family != AF_INET6) {
+            $cidrs->{"$ip/32"} = 1;
+        } elsif ($ip =~ m/^::ffff:($IPV4RE)$/i) {
+            $cidrs->{"$1/32"} = 1;
+        } else {
+            $cidrs->{"[$ip]/128"} = 1;
+        }
+    }
+
+    $resolved_hosts->{$host}->{cidrs} = [sort keys %$cidrs];
+
+    return $resolved_hosts->{$host}->{cidrs}->@*;
+}
+
 # Networks trusted automatically, in addition to loopback and the configured
-# networks. Returns a hash: cidr => { local => 1, relay => 1, transport => [domains] }
+# networks. Returns a hash: cidr => { local => 1, relay => 1, transport => [domains],
+# names => { host name => 1 } }, 'names' only for hosts configured by host name.
 sub get_automatic_mynetworks {
     my ($self, $int_ip) = @_;
 
@@ -1565,13 +1609,11 @@ sub get_automatic_mynetworks {
     if (my $tmap = PVE::INotify::read_file('transport')) {
         foreach my $domain (sort keys %$tmap) {
             my $host = $tmap->{$domain}->{host};
-            my $cidr;
-            if ($host =~ m/^$IPV4RE$/) {
-                $cidr = "$host/32";
-            } elsif ($host =~ m/^(?:ipv6:)?($IPV6RE)$/i) {
-                $cidr = "[$1]/128";
+            my $is_name = $host !~ m/^(?:$IPV4RE|(?:ipv6:)?$IPV6RE)$/i;
+            for my $cidr (mynetworks_for_host($host)) {
+                push $res->{$cidr}->{transport}->@*, $domain;
+                $res->{$cidr}->{names}->{$host} = 1 if $is_name;
             }
-            push $res->{$cidr}->{transport}->@*, $domain if defined($cidr);
         }
     }
 
@@ -1592,12 +1634,11 @@ sub get_automatic_mynetworks {
         $res->{$cidr}->{local} = 1;
     }
 
-    # host names are not resolved, they are not trusted automatically
     if (my $relay = $self->get('mail', 'relay')) {
-        if ($relay =~ m/^$IPV4RE$/) {
-            $res->{"$relay/32"}->{relay} = 1;
-        } elsif ($relay =~ m/^$IPV6RE$/) {
-            $res->{"[$relay]/128"}->{relay} = 1;
+        my $is_name = $relay !~ m/^(?:$IPV4RE|$IPV6RE)$/;
+        for my $cidr (mynetworks_for_host($relay)) {
+            $res->{$cidr}->{relay} = 1;
+            $res->{$cidr}->{names}->{$relay} = 1 if $is_name;
         }
     }
 
-- 
2.53.0








^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH pmg-gui 5/6] fix #8231: mail proxy: add trust local network option, show automatic networks
  2026-10-26  9:58 [PATCH pmg-api/pmg-gui/pmg-docs 0/6] fix #8231: mail proxy: make automatically trusted networks visible and the local network optional Carsten Haerle
                   ` (3 preceding siblings ...)
  2026-10-26  9:58 ` [PATCH pmg-api 4/6] fix #8231: config: resolve relay and transport host names for mynetworks Carsten Haerle
@ 2026-10-26  9:58 ` Carsten Haerle
  2026-10-26  9:58 ` [PATCH pmg-docs 6/6] mail proxy: networks: document automatically trusted networks Carsten Haerle
  5 siblings, 0 replies; 7+ messages in thread
From: Carsten Haerle @ 2026-10-26  9:58 UTC (permalink / raw)
  To: pmg-devel; +Cc: Carsten Haerle

Add the 'Trust Local Network' option to the mail proxy options and list
the networks that are trusted automatically (local network, default
relay, transport hosts) in the Networks panel. They are shown greyed out
with a comment that tells where they come from, and cannot be edited or
removed there.

This makes visible what postfix actually trusts, which so far could only
be seen in the generated main.cf.

Requires the 'automatic' parameter of the mynetworks API in pmg-api.

Signed-off-by: Carsten Haerle <carsten.haerle@straightec.de>
---
 js/MailProxyOptions.js | 4 ++++
 js/MyNetworks.js       | 9 +++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/js/MailProxyOptions.js b/js/MailProxyOptions.js
index 51d6778..b182846 100644
--- a/js/MailProxyOptions.js
+++ b/js/MailProxyOptions.js
@@ -61,6 +61,10 @@ Ext.define('PMG.MailProxyOptions', {
 
         me.add_boolean_row('hide_received', gettext('Hide Internal Hosts'));
 
+        me.add_boolean_row('trust_local_network', gettext('Trust Local Network'), {
+            defaultValue: 1,
+        });
+
         me.add_boolean_row('log-headers', gettext('Log Header Information'), {
             onlineHelp: 'pmgconfig_mailproxy_log_headers',
         });
diff --git a/js/MyNetworks.js b/js/MyNetworks.js
index 3ac5eb9..84df290 100644
--- a/js/MyNetworks.js
+++ b/js/MyNetworks.js
@@ -1,9 +1,10 @@
 Ext.define('pmg-mynetworks', {
     extend: 'Ext.data.Model',
-    fields: ['cidr', 'comment'],
+    fields: ['cidr', 'comment', { name: 'automatic', type: 'boolean' }],
     proxy: {
         type: 'proxmox',
         url: '/api2/json/config/mynetworks',
+        extraParams: { automatic: 1 },
     },
     idProperty: 'cidr',
 });
@@ -28,7 +29,7 @@ Ext.define('PMG.MyNetworks', {
 
         let run_editor = function () {
             let rec = me.selModel.getSelection()[0];
-            if (!rec) {
+            if (!rec || rec.data.automatic) {
                 return;
             }
             Ext.createWidget('proxmoxWindowEdit', {
@@ -90,11 +91,13 @@ Ext.define('PMG.MyNetworks', {
                 text: gettext('Edit'),
                 disabled: true,
                 selModel: me.selModel,
+                enableFn: (rec) => !rec.data.automatic,
                 handler: run_editor,
             },
             {
                 xtype: 'proxmoxStdRemoveButton',
                 selModel: me.selModel,
+                enableFn: (rec) => !rec.data.automatic,
                 baseurl: '/config/mynetworks',
                 callback: reload,
                 waitMsgTarget: me,
@@ -114,6 +117,8 @@ Ext.define('PMG.MyNetworks', {
             run_editor: run_editor,
             viewConfig: {
                 trackOver: false,
+                // automatically trusted networks cannot be modified here
+                getRowClass: (rec) => (rec.data.automatic ? 'proxmox-disabled-row' : ''),
             },
             columns: [
                 {
-- 
2.53.0








^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH pmg-docs 6/6] mail proxy: networks: document automatically trusted networks
  2026-10-26  9:58 [PATCH pmg-api/pmg-gui/pmg-docs 0/6] fix #8231: mail proxy: make automatically trusted networks visible and the local network optional Carsten Haerle
                   ` (4 preceding siblings ...)
  2026-10-26  9:58 ` [PATCH pmg-gui 5/6] fix #8231: mail proxy: add trust local network option, show automatic networks Carsten Haerle
@ 2026-10-26  9:58 ` Carsten Haerle
  5 siblings, 0 replies; 7+ messages in thread
From: Carsten Haerle @ 2026-10-26  9:58 UTC (permalink / raw)
  To: pmg-devel; +Cc: Carsten Haerle

Document which networks are trusted in addition to the configured ones,
the new 'Trust Local Network' option and that host names of the default
relay and transport hosts are resolved when the configuration is
generated.

Signed-off-by: Carsten Haerle <carsten.haerle@straightec.de>
---
 pmgconfig.adoc | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/pmgconfig.adoc b/pmgconfig.adoc
index 00a988e..1269021 100644
--- a/pmgconfig.adoc
+++ b/pmgconfig.adoc
@@ -578,8 +578,19 @@ endif::manvolnum[]
 You can add additional internal (trusted) IP networks or hosts.  All hosts in
 this list are allowed to relay.
 
-NOTE: Hosts in the same subnet as {pmg} can relay by default and don't need to
-be added to this list.
+In addition, the following networks are trusted automatically. They are shown
+greyed out in the list and cannot be edited there:
+
+* The network of the node's IP address, so hosts in the same subnet as {pmg} can
+  relay by default and don't need to be added to this list. You can disable
+  this with the option 'Trust Local Network' under 'Mail Proxy -> Options'.
+  Then only the networks in this list and the hosts below are trusted.
+
+* The default relay and the hosts of all transports, as they are the mail
+  servers that send outgoing mail through {pmg}. Host names are resolved when
+  the configuration is generated, that is, on configuration changes and at
+  boot. If the address of such a host changes, it is only updated with the next
+  configuration change.
 
 
 [[pmgconfig_mailproxy_tls]]
-- 
2.53.0








^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-10-27  9:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-26  9:58 [PATCH pmg-api/pmg-gui/pmg-docs 0/6] fix #8231: mail proxy: make automatically trusted networks visible and the local network optional Carsten Haerle
2026-10-26  9:58 ` [PATCH pmg-api 1/6] fix #8231: config: add option to not trust the local network automatically Carsten Haerle
2026-10-26  9:58 ` [PATCH pmg-api 2/6] config: factor out automatically trusted networks Carsten Haerle
2026-10-26  9:58 ` [PATCH pmg-api 3/6] fix #8231: api: mynetworks: optionally list " Carsten Haerle
2026-10-26  9:58 ` [PATCH pmg-api 4/6] fix #8231: config: resolve relay and transport host names for mynetworks Carsten Haerle
2026-10-26  9:58 ` [PATCH pmg-gui 5/6] fix #8231: mail proxy: add trust local network option, show automatic networks Carsten Haerle
2026-10-26  9:58 ` [PATCH pmg-docs 6/6] mail proxy: networks: document automatically trusted networks Carsten Haerle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal