Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aardvark, netavark: support network scoped dns via network_dns_servers #497

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 21 additions & 2 deletions src/dns/aardvark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const AARDVARK_COMMIT_LOCK: &str = "aardvark.lock";
pub struct AardvarkEntry<'a> {
pub network_name: &'a str,
pub network_gateways: Vec<IpAddr>,
pub network_dns_servers: &'a Option<Vec<IpAddr>>,
pub container_id: &'a str,
pub container_ips_v4: Vec<Ipv4Addr>,
pub container_ips_v6: Vec<Ipv6Addr>,
Expand Down Expand Up @@ -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::<Vec<String>>()
.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::<Vec<String>>()
.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 => {
Expand Down
1 change: 1 addition & 0 deletions src/network/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 4 additions & 0 deletions src/network/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ pub struct Network {
/// Subnets to use for this network.
#[serde(rename = "subnets")]
pub subnets: Option<Vec<Subnet>>,

/// Network DNS servers for aardvark-dns.
#[serde(rename = "network_dns_servers")]
pub network_dns_servers: Option<Vec<IpAddr>>,
}

/// NetworkOptions for a given container.
Expand Down
31 changes: 31 additions & 0 deletions test/100-bridge-iptables.bats
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
45 changes: 45 additions & 0 deletions test/testfiles/dualstack-bridge-network-container-dns-server.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"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"
}
}
}
}