diff --git a/src/dns/aardvark.rs b/src/dns/aardvark.rs index a1d45c914..748d0d97f 100644 --- a/src/dns/aardvark.rs +++ b/src/dns/aardvark.rs @@ -22,6 +22,7 @@ const AARDVARK_COMMIT_LOCK: &str = "aardvark.lock"; pub struct AardvarkEntry<'a> { pub network_name: &'a str, pub network_gateways: Vec, + pub network_dns_servers: &'a Option>, pub container_id: &'a str, pub container_ips_v4: Vec, pub container_ips_v6: Vec, @@ -183,15 +184,33 @@ impl Aardvark { let file = match OpenOptions::new().write(true).create_new(true).open(&path) { Ok(mut f) => { + // collect gateway let gws = entry .network_gateways .iter() .map(|g| g.to_string()) .collect::>() .join(","); - f.write_all(gws.as_bytes())?; - f.write_all("\n".as_bytes())?; + // collect network dns servers if specified + let network_dns_servers = + if let Some(network_dns_servers) = &entry.network_dns_servers { + if !network_dns_servers.is_empty() { + let dns_server_collected = network_dns_servers + .iter() + .map(|g| g.to_string()) + .collect::>() + .join(","); + format!(" {}", dns_server_collected) + } else { + "".to_string() + } + } else { + "".to_string() + }; + + let data = format!("{}{}\n", gws, network_dns_servers); + f.write_all(data.as_bytes())?; // return error if write fails f } Err(ref e) if e.kind() == ErrorKind::AlreadyExists => { diff --git a/src/network/bridge.rs b/src/network/bridge.rs index 21042f88a..aa170aa3a 100644 --- a/src/network/bridge.rs +++ b/src/network/bridge.rs @@ -182,6 +182,7 @@ impl driver::NetworkDriver for Bridge<'_> { network_name: &self.info.network.name, container_id: self.info.container_id, network_gateways: gw, + network_dns_servers: &self.info.network.network_dns_servers, container_ips_v4: ipv4, container_ips_v6: ipv6, container_names: names, diff --git a/src/network/types.rs b/src/network/types.rs index 9b9c20f73..317f39e7c 100644 --- a/src/network/types.rs +++ b/src/network/types.rs @@ -49,6 +49,10 @@ pub struct Network { /// Subnets to use for this network. #[serde(rename = "subnets")] pub subnets: Option>, + + /// Network DNS servers for aardvark-dns. + #[serde(rename = "network_dns_servers")] + pub network_dns_servers: Option>, } /// NetworkOptions for a given container. diff --git a/test/100-bridge-iptables.bats b/test/100-bridge-iptables.bats index 68fc034c2..1e28e6d44 100644 --- a/test/100-bridge-iptables.bats +++ b/test/100-bridge-iptables.bats @@ -210,6 +210,37 @@ fw_driver=iptables assert "${lines[1]}" =~ ".*aardvark-dns --config $NETAVARK_TMPDIR/config/aardvark-dns -p $dns_port run" "aardvark not running or bad options" } +@test "$fw_driver - bridge driver must generate config for aardvark with multiple custom dns server with network dns servers" { + # get a random port directly to avoid low ports e.g. 53 would not create iptables + dns_port=$((RANDOM+10000)) + + # hack to make aardvark-dns run when really root or when running as user with + # podman unshare --rootless-netns; since netavark runs aardvark with systemd-run + # it needs to know if it should use systemd user instance or not. + # iptables are still setup identically. + rootless=false + if [[ ! -e "/run/dbus/system_bus_socket" ]]; then + rootless=true + fi + + mkdir -p "$NETAVARK_TMPDIR/config" + + NETAVARK_DNS_PORT="$dns_port" run_netavark --file ${TESTSDIR}/testfiles/dualstack-bridge-network-container-dns-server.json \ + --rootless "$rootless" --config "$NETAVARK_TMPDIR/config" \ + setup $(get_container_netns_path) + + # check aardvark config and running + run_helper cat "$NETAVARK_TMPDIR/config/aardvark-dns/podman1" + assert "${lines[0]}" =~ "10.89.3.1,fd10:88:a::1 127.0.0.1,3.3.3.3" "aardvark set to listen to all IPs" + assert "${lines[1]}" =~ "^[0-9a-f]{64} 10.89.3.2 fd10:88:a::2 somename 8.8.8.8,1.1.1.1$" "aardvark config's container" + assert "${#lines[@]}" = 2 "too many lines in aardvark config" + + aardvark_pid=$(cat "$NETAVARK_TMPDIR/config/aardvark-dns/aardvark.pid") + assert "$ardvark_pid" =~ "[0-9]*" "aardvark pid not found" + run_helper ps "$aardvark_pid" + assert "${lines[1]}" =~ ".*aardvark-dns --config $NETAVARK_TMPDIR/config/aardvark-dns -p $dns_port run" "aardvark not running or bad options" +} + @test "$fw_driver - dual stack dns with alt port" { # get a random port directly to avoid low ports e.g. 53 would not create iptables dns_port=$((RANDOM+10000)) diff --git a/test/testfiles/dualstack-bridge-network-container-dns-server.json b/test/testfiles/dualstack-bridge-network-container-dns-server.json new file mode 100644 index 000000000..446ee9f9c --- /dev/null +++ b/test/testfiles/dualstack-bridge-network-container-dns-server.json @@ -0,0 +1,39 @@ +{ + "container_id": "f031bf33eecba75d0d84952337b1ceef6a239eb8e94b48aee0993d0791345325", + "container_name": "somename", + "dns_servers": ["8.8.8.8", "1.1.1.1"], + "networks": { + "podman1": { + "static_ips": [ + "10.89.3.2", + "fd10:88:a::2" + ], + "interface_name": "eth0" + } + }, + "network_info": { + "podman1": { + "name": "podman1", + "id": "ec79dd0cad82083c8ac5cc23e9542e4ddea813dff60d68258d36e84f6393b63b", + "driver": "bridge", + "network_interface": "podman1", + "subnets": [ + { + "subnet": "10.89.3.0/24", + "gateway": "10.89.3.1" + }, + { + "subnet": "fd10:88:a::/64", + "gateway": "fd10:88:a::1" + } + ], + "ipv6_enabled": true, + "internal": false, + "dns_enabled": true, + "network_dns_servers": ["127.0.0.1", "3.3.3.3"], + "ipam_options": { + "driver": "host-local" + } + } + } +}