add ipv6 nameservers only when the container has ipv6 enabled

The containers /etc/resolv.conf allways preserved the ipv6 nameserves
from the host even when the container did not supported ipv6. Check
if the cni result contains an ipv6 address or slirp4netns has ipv6
support enabled and only add the ipv6 nameservers when this is the case.

The test needs to have an ipv6 nameserver in the hosts /etc/hosts but we
should never mess with this file on the host. Therefore the test is
skipped when no ipv6 is detected.

Fixes #10158

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger
2021-06-02 21:00:26 +02:00
committed by Matthew Heon
parent 4b8ca63039
commit f62c6bf6ec
2 changed files with 84 additions and 8 deletions

View File

@ -1666,17 +1666,16 @@ func (c *Container) generateResolvConf() (string, error) {
return "", err return "", err
} }
// Ensure that the container's /etc/resolv.conf is compatible with its ipv6 := false
// network configuration.
// TODO: set ipv6 enable bool more sanely
resolv, err := resolvconf.FilterResolvDNS(contents, true, c.config.CreateNetNS)
if err != nil {
return "", errors.Wrapf(err, "error parsing host resolv.conf")
}
// Check if CNI gave back and DNS servers for us to add in // Check if CNI gave back and DNS servers for us to add in
cniResponse := c.state.NetworkStatus cniResponse := c.state.NetworkStatus
for _, i := range cniResponse { for _, i := range cniResponse {
for _, ip := range i.IPs {
// Note: only using To16() does not work since it also returns a vaild ip for ipv4
if ip.Address.IP.To4() == nil && ip.Address.IP.To16() != nil {
ipv6 = true
}
}
if i.DNS.Nameservers != nil { if i.DNS.Nameservers != nil {
cniNameServers = append(cniNameServers, i.DNS.Nameservers...) cniNameServers = append(cniNameServers, i.DNS.Nameservers...)
logrus.Debugf("adding nameserver(s) from cni response of '%q'", i.DNS.Nameservers) logrus.Debugf("adding nameserver(s) from cni response of '%q'", i.DNS.Nameservers)
@ -1687,6 +1686,25 @@ func (c *Container) generateResolvConf() (string, error) {
} }
} }
if c.config.NetMode.IsSlirp4netns() {
ctrNetworkSlipOpts := []string{}
if c.config.NetworkOptions != nil {
ctrNetworkSlipOpts = append(ctrNetworkSlipOpts, c.config.NetworkOptions["slirp4netns"]...)
}
slirpOpts, err := parseSlirp4netnsNetworkOptions(c.runtime, ctrNetworkSlipOpts)
if err != nil {
return "", err
}
ipv6 = slirpOpts.enableIPv6
}
// Ensure that the container's /etc/resolv.conf is compatible with its
// network configuration.
resolv, err := resolvconf.FilterResolvDNS(contents, ipv6, c.config.CreateNetNS)
if err != nil {
return "", errors.Wrapf(err, "error parsing host resolv.conf")
}
dns := make([]net.IP, 0, len(c.runtime.config.Containers.DNSServers)) dns := make([]net.IP, 0, len(c.runtime.config.Containers.DNSServers))
for _, i := range c.runtime.config.Containers.DNSServers { for _, i := range c.runtime.config.Containers.DNSServers {
result := net.ParseIP(i) result := net.ParseIP(i)

View File

@ -329,4 +329,62 @@ load helpers
run_podman network rm -f $mynetname run_podman network rm -f $mynetname
} }
@test "podman ipv6 in /etc/resolv.conf" {
ipv6_regex='([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{0,4})(%\w+)?'
# Make sure to read the correct /etc/resolv.conf file in case of systemd-resolved.
resolve_file=$(readlink -f /etc/resolv.conf)
if [[ "$resolve_file" == "/run/systemd/resolve/stub-resolv.conf" ]]; then
resolve_file="/run/systemd/resolve/resolv.conf"
fi
# If the host doesn't have an ipv6 in resolv.conf skip this test.
# We should never modify resolv.conf on the host.
if ! grep -E "$ipv6_regex" "$resolve_file"; then
skip "This test needs an ipv6 nameserver in $resolve_file"
fi
# ipv4 slirp
run_podman run --rm --network slirp4netns:enable_ipv6=false $IMAGE cat /etc/resolv.conf
if grep -E "$ipv6_regex" <<< $output; then
die "resolv.conf contains a ipv6 nameserver"
fi
# ipv6 slirp
run_podman run --rm --network slirp4netns:enable_ipv6=true $IMAGE cat /etc/resolv.conf
# "is" does not like the ipv6 regex
if ! grep -E "$ipv6_regex" <<< $output; then
die "resolv.conf does not contain a ipv6 nameserver"
fi
# ipv4 cni
local mysubnet=$(random_rfc1918_subnet)
local netname=testnet-$(random_string 10)
run_podman network create --subnet $mysubnet.0/24 $netname
is "$output" ".*/cni/net.d/$netname.conflist" "output of 'network create'"
run_podman run --rm --network $netname $IMAGE cat /etc/resolv.conf
if grep -E "$ipv6_regex" <<< $output; then
die "resolv.conf contains a ipv6 nameserver"
fi
run_podman network rm -f $netname
# ipv6 cni
mysubnet=fd00:4:4:4:4::/64
netname=testnet-$(random_string 10)
run_podman network create --subnet $mysubnet $netname
is "$output" ".*/cni/net.d/$netname.conflist" "output of 'network create'"
run_podman run --rm --network $netname $IMAGE cat /etc/resolv.conf
# "is" does not like the ipv6 regex
if ! grep -E "$ipv6_regex" <<< $output; then
die "resolv.conf does not contain a ipv6 nameserver"
fi
run_podman network rm -f $netname
}
# vim: filetype=sh # vim: filetype=sh