Skip to content

Commit

Permalink
use new c/common pasta2 setup logic to fix dns
Browse files Browse the repository at this point in the history
By default we just ignored any localhost reolvers, this is problematic
for anyone with more complicated dns setups, i.e. split dns with
systemd-reolved. To address this we now make use of the build in dns
proxy in pasta. As such we need to set the default nameserver ip now.

A second change is the option to exclude certain ips when generating the
host.containers.internal ip. With that we no longer set it to the same
ip as is used in the netns. The fix is not perfect as it could mean on a
system with a single ip we no longer add the entry, however given the
previous entry was incorrect anyway this seems like the better behavior.

Fixes #22044

Signed-off-by: Paul Holzinger <[email protected]>
  • Loading branch information
Luap99 committed Mar 19, 2024
1 parent 079bfb0 commit dc1795b
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 31 deletions.
2 changes: 2 additions & 0 deletions libpod/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"strings"
"time"

"github.com/containers/common/libnetwork/pasta"
"github.com/containers/common/libnetwork/types"
"github.com/containers/common/pkg/config"
"github.com/containers/common/pkg/secrets"
Expand Down Expand Up @@ -127,6 +128,7 @@ type Container struct {
restoreFromCheckpoint bool

slirp4netnsSubnet *net.IPNet
pastaResult *pasta.SetupResult
}

// ContainerState contains the current state of the container
Expand Down
32 changes: 21 additions & 11 deletions libpod/container_internal_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"fmt"
"io"
"math"
"net"
"os"
"os/user"
"path"
Expand Down Expand Up @@ -2116,8 +2117,8 @@ func (c *Container) addResolvConf() error {
// first add the nameservers from the networks status
nameservers = networkNameServers

// slirp4netns has a built in DNS forwarder.
nameservers = c.addSlirp4netnsDNS(nameservers)
// pasta and slirp4netns have a built in DNS forwarder.
nameservers = c.addSpecialDNS(nameservers)
}

// Set DNS search domains
Expand Down Expand Up @@ -2167,6 +2168,10 @@ func (c *Container) checkForIPv6(netStatus map[string]types.StatusBlock) bool {
}
}

if c.pastaResult != nil {
return c.pastaResult.IPv6
}

return c.isSlirp4netnsIPv6()
}

Expand Down Expand Up @@ -2225,11 +2230,10 @@ func (c *Container) getHostsEntries() (etchosts.HostEntries, error) {
case c.config.NetMode.IsBridge():
entries = etchosts.GetNetworkHostEntries(c.state.NetworkStatus, names...)
case c.config.NetMode.IsPasta():
ip, err := getPastaIP(c.state)
if err != nil {
return nil, err
// this should never be the case but check just to be sure and not panic
if len(c.pastaResult.IPAddresses) > 0 {
entries = etchosts.HostEntries{{IP: c.pastaResult.IPAddresses[0].String(), Names: names}}
}
entries = etchosts.HostEntries{{IP: ip.String(), Names: names}}
case c.config.NetMode.IsSlirp4netns():
ip, err := getSlirp4netnsIP(c.slirp4netnsSubnet)
if err != nil {
Expand Down Expand Up @@ -2276,12 +2280,18 @@ func (c *Container) addHosts() error {
return err
}

var exclude []net.IP
if c.pastaResult != nil {
exclude = c.pastaResult.IPAddresses
}

return etchosts.New(&etchosts.Params{
BaseFile: baseHostFile,
ExtraHosts: c.config.HostAdd,
ContainerIPs: containerIPsEntries,
HostContainersInternalIP: etchosts.GetHostContainersInternalIP(c.runtime.config, c.state.NetworkStatus, c.runtime.network),
TargetFile: targetFile,
BaseFile: baseHostFile,
ExtraHosts: c.config.HostAdd,
ContainerIPs: containerIPsEntries,
HostContainersInternalIP: etchosts.GetHostContainersInternalIPExcluding(
c.runtime.config, c.state.NetworkStatus, c.runtime.network, exclude),
TargetFile: targetFile,
})
}

Expand Down
2 changes: 1 addition & 1 deletion libpod/container_internal_freebsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ func (c *Container) setCgroupsPath(g *generate.Generator) error {
return nil
}

func (c *Container) addSlirp4netnsDNS(nameservers []string) []string {
func (c *Container) addSpecialDNS(nameservers []string) []string {
return nameservers
}

Expand Down
7 changes: 6 additions & 1 deletion libpod/container_internal_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,12 @@ func (c *Container) setCgroupsPath(g *generate.Generator) error {
return nil
}

func (c *Container) addSlirp4netnsDNS(nameservers []string) []string {
// addSpecialDNS adds special dns servers for slirp4netns and pasta
func (c *Container) addSpecialDNS(nameservers []string) []string {
if c.pastaResult != nil {
nameservers = append(nameservers, c.pastaResult.DNSForwardIPs...)
}

// slirp4netns has a built in DNS forwarder.
if c.config.NetMode.IsSlirp4netns() {
slirp4netnsDNS, err := slirp4netns.GetDNS(c.slirp4netnsSubnet)
Expand Down
4 changes: 0 additions & 4 deletions libpod/networking_freebsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,3 @@ func (c *Container) reloadRootlessRLKPortMapping() error {
func (c *Container) setupRootlessNetwork() error {
return nil
}

func getPastaIP(state *ContainerState) (net.IP, error) {
return nil, fmt.Errorf("pasta networking is Linux only")
}
11 changes: 0 additions & 11 deletions libpod/networking_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (

"github.com/containernetworking/plugins/pkg/ns"
"github.com/containers/common/libnetwork/types"
netUtil "github.com/containers/common/libnetwork/util"
"github.com/containers/common/pkg/netns"
"github.com/containers/podman/v5/libpod/define"
"github.com/containers/podman/v5/pkg/rootless"
Expand Down Expand Up @@ -300,13 +299,3 @@ func (c *Container) inspectJoinedNetworkNS(networkns string) (q types.StatusBloc
})
return result, err
}

func getPastaIP(state *ContainerState) (net.IP, error) {
var ip string
err := ns.WithNetNSPath(state.NetNS, func(_ ns.NetNS) error {
// get the first ip in the netns
ip = netUtil.GetLocalIP()
return nil
})
return net.ParseIP(ip), err
}
7 changes: 6 additions & 1 deletion libpod/networking_pasta_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@ package libpod
import "github.com/containers/common/libnetwork/pasta"

func (r *Runtime) setupPasta(ctr *Container, netns string) error {
return pasta.Setup(&pasta.SetupOptions{
res, err := pasta.Setup2(&pasta.SetupOptions{
Config: r.config,
Netns: netns,
Ports: ctr.convertPortMappings(),
ExtraOptions: ctr.config.NetworkOptions[pasta.BinaryName],
})
if err != nil {
return err
}
ctr.pastaResult = res
return nil
}
7 changes: 5 additions & 2 deletions test/system/505-networking-pasta.bats
Original file line number Diff line number Diff line change
Expand Up @@ -431,9 +431,12 @@ function pasta_test_do() {
@test "Local forwarder, IPv4" {
skip_if_no_ipv4 "IPv4 not routable on the host"

run_podman run --dns 198.51.100.1 \
--net=pasta:--dns-forward,198.51.100.1 $IMAGE nslookup 127.0.0.1 || :
# pasta is the default now so no need to set it
run_podman run --rm $IMAGE grep nameserver /etc/resolv.conf
assert "${lines[0]}" == "nameserver 169.254.0.1" "default dns forward server"

run_podman run --rm --net=pasta:--dns-forward,198.51.100.1 \
$IMAGE nslookup 127.0.0.1 || :
assert "$output" =~ "1.0.0.127.in-addr.arpa" "No answer from resolver"
}

Expand Down

0 comments on commit dc1795b

Please sign in to comment.