* [PATCH container] fix #7388: prefer container DNS config over host-managed DHCP
@ 2026-03-11 11:20 Filip Schauer
0 siblings, 0 replies; only message in thread
From: Filip Schauer @ 2026-03-11 11:20 UTC (permalink / raw)
To: pve-devel
For host-managed container network interfaces using DHCP, dhclient may
overwrite /etc/resolv.conf with DNS information supplied by the DHCP
server, causing any explicitly configured nameserver/searchdomain to be
silently ignored.
Fix this with a custom dhclient.conf that ensures the container config
takes precedence over any DNS settings offered by the DHCP server.
Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
---
src/PVE/LXC.pm | 46 +++++++++++++++++++++++++++++++++++++++-------
1 file changed, 39 insertions(+), 7 deletions(-)
diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm
index 9633451..c4d4a11 100644
--- a/src/PVE/LXC.pm
+++ b/src/PVE/LXC.pm
@@ -5,7 +5,7 @@ use warnings;
use Cwd qw();
use Errno qw(ELOOP ENOTDIR EROFS ECONNREFUSED EEXIST);
-use Fcntl qw(O_RDONLY O_WRONLY O_NOFOLLOW O_DIRECTORY O_CREAT :mode);
+use Fcntl qw(O_RDONLY O_WRONLY O_NOFOLLOW O_DIRECTORY O_CREAT SEEK_SET :mode);
use File::Basename;
use File::Path;
use File::Spec;
@@ -1324,12 +1324,42 @@ sub get_interfaces {
}
sub manage_dhclient {
- my ($action, $vmid, $ipversion, $eth, $rootdir) = @_;
+ my ($action, $vmid, $conf, $ipversion, $eth, $rootdir) = @_;
File::Path::make_path("/var/lib/lxc/$vmid/hook") if $action eq 'start';
my $pidfile = "/var/lib/lxc/$vmid/hook/dhclient$ipversion-$eth.pid";
my $leasefile = "/var/lib/lxc/$vmid/hook/dhclient$ipversion-$eth.leases";
my $scriptfile = '/usr/share/lxc/hooks/dhclient-script';
+
+ # Copied from /etc/dhcp/dhclient.conf in isc-dhcp-client Debian package
+ my $config =
+ "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"
+ . "send host-name = gethostname();\n"
+ . "request subnet-mask, broadcast-address, time-offset, routers, "
+ . "domain-name, domain-name-servers, domain-search, host-name, "
+ . "dhcp6.name-servers, dhcp6.domain-search, dhcp6.fqdn, dhcp6.sntp-servers, "
+ . "netbios-name-servers, netbios-scope, interface-mtu, "
+ . "rfc3442-classless-static-routes, ntp-servers;\n";
+
+ if ($ipversion == 6) {
+ if (my @nameservers = grep { /$IPV6RE/ } PVE::Tools::split_list($conf->{nameserver})) {
+ $config .= "supersede dhcp6.name-servers " . join(", ", @nameservers) . ";\n";
+ }
+ } elsif (my @nameservers = grep { /$IPV4RE/ } PVE::Tools::split_list($conf->{nameserver})) {
+ $config .= "supersede domain-name-servers " . join(", ", @nameservers) . ";\n";
+ }
+
+ if (my @searchdomains = PVE::Tools::split_list($conf->{searchdomain})) {
+ $config .= "supersede " . (($ipversion == 6) ? "dhcp6." : "") . "domain-search ";
+ $config .= join(", ", map { "\"$_\"" } @searchdomains) . ";\n";
+ }
+
+ open(my $configfh, '+>', undef) or die "failed to create dhclient config: $!";
+ print $configfh $config;
+ $configfh->flush();
+ sysseek($configfh, 0, SEEK_SET);
+ my $configfile = "/proc/$$/fd/" . fileno($configfh);
+
PVE::Tools::run_command([
'lxc-attach',
'-n',
@@ -1351,6 +1381,8 @@ sub manage_dhclient {
"ROOTFS=$rootdir",
'-sf',
$scriptfile,
+ '-cf',
+ $configfile,
$eth,
]);
}
@@ -1411,10 +1443,10 @@ sub update_ipconfig {
my $is_real_ip = ($newip && $newip !~ /^(?:auto|dhcp|manual)$/);
if ($change_ip) {
if ($newnet->{'host-managed'} && $newip && $newip eq 'dhcp') {
- manage_dhclient('start', $vmid, $ipversion, $eth, $rootdir);
+ manage_dhclient('start', $vmid, $conf, $ipversion, $eth, $rootdir);
}
if ($optdata->{'host-managed'} && $oldip && $oldip eq 'dhcp') {
- manage_dhclient('stop', $vmid, $ipversion, $eth, $rootdir);
+ manage_dhclient('stop', $vmid, $conf, $ipversion, $eth, $rootdir);
}
if ($is_real_ip) {
@@ -1425,7 +1457,7 @@ sub update_ipconfig {
}
}
} elsif ($optdata->{'host-managed'} && !$newnet->{'host-managed'}) {
- manage_dhclient('stop', $vmid, $ipversion, $eth, $rootdir);
+ manage_dhclient('stop', $vmid, $conf, $ipversion, $eth, $rootdir);
}
# step 2: replace gateway
@@ -3227,12 +3259,12 @@ sub vm_start {
my $rootdir = "/proc/$pid/root";
for my $eth (@managed_dhcpv4_interfaces) {
- eval { manage_dhclient('start', $vmid, 4, $eth, $rootdir) };
+ eval { manage_dhclient('start', $vmid, $conf, 4, $eth, $rootdir) };
PVE::RESTEnvironment::log_warn("DHCP failed - $@") if $@;
}
for my $eth (@managed_dhcpv6_interfaces) {
- eval { manage_dhclient('start', $vmid, 6, $eth, $rootdir) };
+ eval { manage_dhclient('start', $vmid, $conf, 6, $eth, $rootdir) };
PVE::RESTEnvironment::log_warn("DHCP failed - $@") if $@;
}
--
2.47.3
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-03-11 11:21 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-03-11 11:20 [PATCH container] fix #7388: prefer container DNS config over host-managed DHCP Filip Schauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox