Skip to content

Commit

Permalink
Merge pull request #16297 from flouthoc/netavark-custom-dns
Browse files Browse the repository at this point in the history
libpod,netavark: correctly set `/etc/resolv.conf` for custom dns server and make `--dns` functional
  • Loading branch information
openshift-merge-robot authored Jan 23, 2023
2 parents ebc754f + b7ab889 commit 1a90189
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 10 deletions.
23 changes: 17 additions & 6 deletions libpod/container_internal_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -1993,24 +1993,35 @@ func (c *Container) generateResolvConf() error {
return err
}

networkBackend := c.runtime.config.Network.NetworkBackend
nameservers := make([]string, 0, len(c.runtime.config.Containers.DNSServers)+len(c.config.DNSServer))
nameservers = append(nameservers, c.runtime.config.Containers.DNSServers...)
for _, ip := range c.config.DNSServer {
nameservers = append(nameservers, ip.String())

// If NetworkBackend is `netavark` do not populate `/etc/resolv.conf`
// with custom dns server since after https://github.com/containers/netavark/pull/452
// netavark will always set required `nameservers` in statsBlock and libpod
// will correctly populate `networkNameServers`. Also see https://github.com/containers/podman/issues/16172

// Exception: Populate `/etc/resolv.conf` if container is not connected to any network
// ( i.e len(netStatus)==0 ) since in such case netavark is not invoked at all.
if networkBackend != string(types.Netavark) || len(netStatus) == 0 {
nameservers = append(nameservers, c.runtime.config.Containers.DNSServers...)
for _, ip := range c.config.DNSServer {
nameservers = append(nameservers, ip.String())
}
}
// If the user provided dns, it trumps all; then dns masq; then resolv.conf
var search []string
keepHostServers := false
if len(nameservers) == 0 {
keepHostServers = true
// first add the nameservers from the networks status
nameservers = networkNameServers
// when we add network dns server we also have to add the search domains
search = networkSearchDomains
// slirp4netns has a built in DNS forwarder.
nameservers = c.addSlirp4netnsDNS(nameservers)
}

// Set DNS search domains
search := networkSearchDomains

if len(c.config.DNSSearch) > 0 || len(c.runtime.config.Containers.DNSSearches) > 0 {
customSearch := make([]string, 0, len(c.config.DNSSearch)+len(c.runtime.config.Containers.DNSSearches))
customSearch = append(customSearch, c.runtime.config.Containers.DNSSearches...)
Expand Down
6 changes: 6 additions & 0 deletions libpod/networking_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,15 @@ func (c *Container) convertPortMappings() []types.PortMapping {
}

func (c *Container) getNetworkOptions(networkOpts map[string]types.PerNetworkOptions) types.NetworkOptions {
nameservers := make([]string, 0, len(c.runtime.config.Containers.DNSServers)+len(c.config.DNSServer))
nameservers = append(nameservers, c.runtime.config.Containers.DNSServers...)
for _, ip := range c.config.DNSServer {
nameservers = append(nameservers, ip.String())
}
opts := types.NetworkOptions{
ContainerID: c.config.ID,
ContainerName: getNetworkPodName(c),
DNSServers: nameservers,
}
opts.PortMappings = c.convertPortMappings()

Expand Down
31 changes: 31 additions & 0 deletions test/e2e/run_networking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,37 @@ var _ = Describe("Podman run networking", func() {
Expect(session).Should(Exit(0))
})

It("podman verify resolv.conf with --dns + --network", func() {
// Following test is only functional with netavark and aardvark
// since new behaviour depends upon output from of statusBlock
SkipIfCNI(podmanTest)
net := createNetworkName("IntTest")
session := podmanTest.Podman([]string{"network", "create", net})
session.WaitWithDefaultTimeout()
defer podmanTest.removeNetwork(net)
Expect(session).Should(Exit(0))

session = podmanTest.Podman([]string{"run", "--name", "con1", "--dns", "1.1.1.1", "--network", net, ALPINE, "cat", "/etc/resolv.conf"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
// Must not contain custom dns server in containers
// `/etc/resolv.conf` since custom dns-server is
// already expected to be present and processed by
// Podman's DNS resolver i.e ( aarvark-dns or dnsname ).
Expect(session.OutputToString()).ToNot(ContainSubstring("nameserver 1.1.1.1"))
// But /etc/resolve.conf must contain othe nameserver
// i.e dns server configured for network.
Expect(session.OutputToString()).To(ContainSubstring("nameserver"))

session = podmanTest.Podman([]string{"run", "--name", "con2", "--dns", "1.1.1.1", ALPINE, "cat", "/etc/resolv.conf"})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
// All the networks being used by following container
// don't have dns_enabled in such scenario `/etc/resolv.conf`
// must contain nameserver which were specified via `--dns`.
Expect(session.OutputToString()).To(ContainSubstring("nameserver 1.1.1.1"))
})

It("podman run network expose port 222", func() {
SkipIfRootless("iptables is not supported for rootless users")
session := podmanTest.Podman([]string{"run", "-dt", "--expose", "222-223", "-P", ALPINE, "/bin/sh"})
Expand Down
12 changes: 8 additions & 4 deletions test/system/500-networking.bats
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,7 @@ EOF
"

CONTAINERS_CONF=$containersconf run_podman run --rm $IMAGE cat /etc/resolv.conf
is "$output" "search example.com$nl.*" "correct search domain"
is "$output" "search example.com.*" "correct search domain"
is "$output" ".*nameserver 1.1.1.1${nl}nameserver $searchIP${nl}nameserver 1.0.0.1${nl}nameserver 8.8.8.8" "nameserver order is correct"

# create network with dns
Expand All @@ -660,9 +660,13 @@ EOF
run_podman network create --subnet "$subnet.0/24" $netname
# custom server overwrites the network dns server
CONTAINERS_CONF=$containersconf run_podman run --network $netname --rm $IMAGE cat /etc/resolv.conf
is "$output" "search example.com$nl.*" "correct search domain"
is "$output" ".*nameserver 1.1.1.1${nl}nameserver $searchIP${nl}nameserver 1.0.0.1${nl}nameserver 8.8.8.8" "nameserver order is correct"

is "$output" "search example.com.*" "correct search domain"
local store=$output
if is_netavark; then
is "$store" ".*nameserver $subnet.1.*" "integrated dns nameserver is set"
else
is "$store" ".*nameserver 1.1.1.1${nl}nameserver $searchIP${nl}nameserver 1.0.0.1${nl}nameserver 8.8.8.8" "nameserver order is correct"
fi
# we should use the integrated dns server
run_podman run --network $netname --rm $IMAGE cat /etc/resolv.conf
is "$output" "search dns.podman.*" "correct search domain"
Expand Down

0 comments on commit 1a90189

Please sign in to comment.