The first impact

This commit is contained in:
Ludwig Behm 2025-03-14 11:40:20 +01:00
commit 627453eaa6
Signed by: l.behm
GPG key ID: D344835D63B89384
2 changed files with 74 additions and 0 deletions

38
README.md Normal file
View file

@ -0,0 +1,38 @@
# `docker-zonefiled`
## What's this?
This generates DNS zone files containing DNS hostnames and aliases of running docker containers in all docker networks for a given docker host.
It generates zone files like this:
```
container_name.network_name.in-docker.internal. A 172.25.1.2
alias.network_name.in-docker.internal. AAAA 2a02:F00:BA4::1:2
container_name.backend_network.in-docker.internal. A 192.168.42.2
```
This is currently implemented as an trivial simple bash script utilizing `docker events` for listening on changes, `docker container inspect` to query the network details and some `jq` magic.
## Why 'tho?
- I wanted sane dns resolution from the docker host to docker containers.
- nss-docker isn't enough or working.
- DNS operations are well understood. Automagic name resolution via nss leads to unexpected behavior, if container name vanished and queries drop down to dns.
- Using DNS subdomains host and aliases are structured per network name.
- Your networking, routing and firewalling decides if you're able to reach the container interfaces.
- Passing a different docker socket and alternative domain zone name can support multi-docker-setups.
## Remarks
### Input sanitization of user controlled values
Specially grafted host and alias names of docker containers can inject stuff in the generated zone file, I guess.
I'm currently open to discuss, how to catch invalid characters in host names.
### Currently used `.internal` TLD
This is currently used since it should never be resolved in the internet.
Since it could be used in a private / enterprise context, it could be conflicting existing setups.
I'm very open to discuss if a `.in-docker` TLD would be a sane idea.

36
docker-zonefiled Normal file
View file

@ -0,0 +1,36 @@
#!/bin/bash
ZONE_FILE="$1"
SOA="$(hostname -f). $(whoami).$(hostname -f)."
ZONE="in-docker.internal"
function generate_records() {
docker container ls -q \
| xargs docker container inspect 2>/dev/null \
| jq -r '.[] | select(.State.Running) | .NetworkSettings.Networks | to_entries | map(.key as $net | .value as $conf | (.value.DNSNames[] | (.+"."+$net) as $host | [ ($host + " IN A "+$conf.IPAddress), ($host + " IN AAAA " + $conf.GlobalIPv6Address)])) | flatten | .[]'
}
function update() {
SN="$(date +%y%m%d%H%M%S)"
cat <<EOF > $ZONE_FILE
\$ORIGIN $ZONE.
\$TTL 10 ; default time to live
@ IN SOA $SOA (
$SN ; serial number <yymmddHHMM>
60 ; Refresh
60 ; Retry
60 ; Expire
10 ; Min TTL
)
$(generate_records)
EOF
}
update
docker events --filter 'type=network' --filter 'event=connect' --filter 'event=disconnect' --format '{{json .}}' \
| while read _event
do
update
done