From 973807092d10406c039ab4b376f2fd74f456be1d Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Fri, 26 Mar 2021 10:41:01 +0100 Subject: Use the slrip4netns dns in the rootless cni ns If a user only has a local dns server in the resolv.conf file the dns resolution will fail. Instead we create a new resolv.conf which will use the slirp4netns dns. Signed-off-by: Paul Holzinger --- libpod/networking_linux.go | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'libpod/networking_linux.go') diff --git a/libpod/networking_linux.go b/libpod/networking_linux.go index 5c43ebb8b..157c85431 100644 --- a/libpod/networking_linux.go +++ b/libpod/networking_linux.go @@ -24,6 +24,7 @@ import ( "github.com/containers/podman/v3/libpod/network" "github.com/containers/podman/v3/pkg/errorhandling" "github.com/containers/podman/v3/pkg/netns" + "github.com/containers/podman/v3/pkg/resolvconf" "github.com/containers/podman/v3/pkg/rootless" "github.com/containers/podman/v3/pkg/util" "github.com/containers/storage/pkg/lockfile" @@ -134,9 +135,14 @@ func (r *rootlessCNI) Do(toRun func() error) error { return errors.Wrap(err, "failed to mount netns directory for rootless cni") } + // mount resolv.conf to make use of the host dns + err = unix.Mount(filepath.Join(r.dir, "resolv.conf"), "/etc/resolv.conf", "none", unix.MS_BIND, "") + if err != nil { + return errors.Wrap(err, "failed to mount resolv.conf for rootless cni") + } + // also keep /run/systemd if it exists - // many files are symlinked into this dir, for example systemd-resolved links - // /etc/resolv.conf but the dnsname plugin needs access to this file + // many files are symlinked into this dir, for example /dev/log runSystemd := "/run/systemd" _, err = os.Stat(runSystemd) if err == nil { @@ -348,6 +354,29 @@ func (r *Runtime) getRootlessCNINetNs(new bool) (*rootlessCNI, error) { return nil, err } + // build a new resolv.conf file which uses the slirp4netns dns server address + resolveIP := slirp4netnsDNS + if netOptions.cidr != "" { + _, cidr, err := net.ParseCIDR(netOptions.cidr) + if err != nil { + return nil, errors.Wrap(err, "failed to parse slirp4netns cidr") + } + // the slirp dns ip is always the third ip in the subnet + cidr.IP[len(cidr.IP)-1] = cidr.IP[len(cidr.IP)-1] + 3 + resolveIP = cidr.IP.String() + } + conf, err := resolvconf.Get() + if err != nil { + return nil, err + } + searchDomains := resolvconf.GetSearchDomains(conf.Content) + dnsOptions := resolvconf.GetOptions(conf.Content) + + _, err = resolvconf.Build(filepath.Join(cniDir, "resolv.conf"), []string{resolveIP}, searchDomains, dnsOptions) + if err != nil { + return nil, errors.Wrap(err, "failed to create rootless cni resolv.conf") + } + // create cni directories to store files // they will be bind mounted to the correct location in a extra mount ns err = os.MkdirAll(filepath.Join(cniDir, "var"), 0700) -- cgit v1.2.3-54-g00ecf