DNS resolution between containers

We are running a multi-container app which has a web server in one container and a browser kiosk in the other. Both containers are on the host network via network_mode: host. The server container includes an openvpn client and has NET_ADMIN capabilities to be able to establish the required VPN tunnels at the host level, as they need to be available to the kiosk container as well. We are using openresolv to set the DNS servers in the server container, which is working as intended, i.e. when the VPN connects, the DNS servers in the server container are updated to the VPN DNS servers and it is able to resolve names over the VPN.

The issue I am running into is that in the kiosk container, while it can access hosts in the VPN via IP addresses (the VPN shows up in the list of connections under nmcli as it is in host network mode as well), the kiosk container is not able to resolve any DNS names over the VPN, as it’s resolv.conf file does not get updated by openresolv (which is running only in the server container where the VPN tunnel is established). Is there any way to specify that DNS servers for one container should match another? I don’t want to hardcode the dns servers in the compose file as they will change across deployments; rather the DNS of the kiosk container needs to dynamically match the DNS being set by openresolv in the server container.

One approach that I tried (and failed at) was to run dnsmasq in the server container, mapped port 53, then pointed the kiosk container’s DNS to 127.0.0.1 in the compose file. But the issue I ran into was that the server container was not able to bind to port 53 on 127.0.0.1 as the port was being used by the host (which was no surprise based on this link)

Another approach that failed was to create a symbolic link to the server’s /etc/resolv.conf file in the /data volume such that it is available to the kiosk container, but I’m then not able to point /etc/resolv.conf in the host container to this link, since the file is read only.

Does anyone have experience with something like this? One way I was thinking of doing this is specifying a custom network under the networks: heading in the compose file, which I understand would allow the two containers to share DNS servers, but with this would openresolv (running in one of the containers) be able to update DNS for both containers? How are the resolv.conf files linked if so?

could you use dbus to set the DNS servers in NetworkManager when they get sent via the OpenVPN connection?

That sounds like a good solution, but I thought I had read in another post that it was not possible to update the host DNS settings via DBUS. Could you give me an example of what the command would look like to do this?

So the following command will show me the DNS config:

# dbus-send --system --print-reply --dest=org.freedesktop.NetworkManager /org/freedesktop/NetworkManager/DnsManager org.freedesktop.DBus.Properties.Get string:"org.freedesktop.NetworkManager.DnsManager" string:"Configuration"

method return time=1592404561.578519 sender=:1.4 -> destination=:1.5796 serial=14751 reply_serial=2
   variant       array [
         array [
            dict entry(
               string "nameservers"
               variant                   array [
                     string "8.8.8.8"
                     string "1.1.1.1"
                  ]
            )
            dict entry(
               string "domains"
               variant                   array [
                     string "lan"
                  ]
            )
            dict entry(
               string "interface"
               variant                   string "enp0s3"
            )
            dict entry(
               string "priority"
               variant                   int32 100
            )
            dict entry(
               string "vpn"
               variant                   boolean false
            )
         ]
      ]

The configuration isn’t directly writable (https://developer.gnome.org/NetworkManager/stable/gdbus-org.freedesktop.NetworkManager.DnsManager.html) but it’s pulling from the connections so I guess you should create a connection with the settings, I am not sure.

I ran the dbus-send command from your example in my server container and as suspected the result does not include the VPN DNS server, just the local network DNS server that is obtained via DHCP. But the odd thing is that the VPN connection is already on the host machine (remember the server container is running with network_mode: host). Given this would I still need to create a new connection on the host to pass the DNS settings from the server container to the kiosk container?

Just FYI when I run nmcli con show on the host, it shows the tun0 VPN connection, and in fact the kiosk container also has the tun0 VPN connection because it is in host mode as well.

I was able to get this working. In case anyone else runs into this issue, all I had to do was install openresolv on the containers I need to update the DNS records, which makes resolv.conf writeable. Then in my openvpn container, I add a line to the end of update-resolv-conf script to copy it’s resolv.conf to a shared location after it gets updated. And finally I overwrite the local resolv.conf from the shared location on the containers that need the update. Everything works as intended now.

Hey! glad that you manage to get this working properly!