Fun met de firewall
Ik ben niet meer zo vaak bezig met de nitty-gritty krochten van de wondere wereld van het systeembeheer (nu meer iemand die presentaties maakt en nota’s schrijft), maar af en toe wil ik toch ook nog iets met de handen doen. Caveat emptor zoals een Romein zou zeggen, en dit verhaal bewijst dat ze in ’t Antieke Rome goed wisten wat ze deden!
Voor een keer dat het geen DNS-probleem is …
Podman
Dit is een plezante (maar niet heus). Op één van mijn machines wil ik graag containers draaien met podman-compose; want dat is plezant. En ik kies ervoor om podman-compose en niet docker-compose te gebruiken omdat ik open source belangrijk vind.
Maar. Dat liep niet van een leien dakje. Alles leek te werken, allen konden containers elkaar niet via DNS bereiken. Via IP ging het wel, en de container startte ook mooi; maar wat ik ook probeerde, met elkaar praten via DNS lukte absoluut niet. Verdorie.
Na een avondje frustratie heeft tcpdump mooi geholpen om te zien wat het probleem exact was: de containers konden de interne DNS-server niet bereiken (Aardvark-DNS).
tcpdump --interface podman1
Daarop was mooi te zien dat de container de DNS-server op 10.89.0.1 probeerde te bereiken, maar dat die niet thuis gaf. Helaas bleek er in de logbestanden van aardvark-dns niets te staan, dus wat het probleem was, had ik nog niet gevonden. Met een ander oud commando kon ik zien dat er wel een DNS-server aan het luisteren was, maar dat het niet aardvark-dns was.
netstat -tulpn
gaf
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:53 0.0.0.0:* LISTEN 772/dnsmasq
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 588978/sshd: /usr/s
tcp6 0 0 :::53 :::* LISTEN 772/dnsmasq
tcp6 0 0 :::22 :::* LISTEN 588978/sshd: /usr/s
tcp6 0 0 :::10050 :::* LISTEN 724/zabbix_agent2
udp 0 0 0.0.0.0:53 0.0.0.0:* 772/dnsmasq
udp6 0 0 :::53 :::* 772/dnsmasq
De Aha-erlebnis! De logs vertelden niets, maar de hypothese kreeg vorm: dnsmasq luistert op alle interfaces, dus kan aardvark er niet op luisteren. En dan werkt het niet ahja.
Met wat puppet-fu de config /etc/dnsmasq.conf
aangepast naar (en daarna een systemctl restart dnsmasq
):
# Or which to listen on by address (remember to include 127.0.0.1 if
# you use this.)
listen-address=127.0.0.1
# If you want dnsmasq to provide only DNS service on an interface,
# configure it as shown above, and then use the following line to
# disable DHCP and TFTP on it.
no-dhcp-interface=yes
En zie daar:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 59229/dnsmasq
tcp 0 0 10.60.0.167:53 0.0.0.0:* LISTEN 59229/dnsmasq
tcp6 0 0 ::1:53 :::* LISTEN 59229/dnsmasq
tcp6 0 0 fe80::d093:49ff:fe0a:53 :::* LISTEN 59229/dnsmasq
tcp6 0 0 fe80::5054:ff:fe99:2:53 :::* LISTEN 59229/dnsmasq
tcp6 0 0 fe80::1016:aaff:fe19:53 :::* LISTEN 59229/dnsmasq
udp 0 0 10.89.0.1:53 0.0.0.0:* 112583/aardvark-dns
udp 0 0 127.0.0.1:53 0.0.0.0:* 59229/dnsmasq
udp 0 0 10.60.0.167:53 0.0.0.0:* 59229/dnsmasq
udp6 0 0 ::1:53 :::* 59229/dnsmasq
udp6 0 0 fe80::5054:ff:fe99:2:53 :::* 59229/dnsmasq
udp6 0 0 fe80::1016:aaff:fe19:53 :::* 59229/dnsmasq
udp6 0 0 fe80::d093:49ff:fe0a:53 :::* 59229/dnsmasq
Hoera!
Maar nu lukte het nog altijd niet. En we hebben het nog niet over de firewall gehad, en dit stukje heet fun met de firewall.
Podman voegt firewall-regels toe.
Een chain:
Chain NETAVARK_FORWARD (1 references)
target prot opt source destination
ACCEPT all -- anywhere 10.89.0.0/24 ctstate RELATED,ESTABLISHED
ACCEPT all -- 10.89.0.0/24 anywhere
En een rule in de FORWARD-chain.
NETAVARK_FORWARD all -- anywhere anywhere
Nu beheer ik mijn firewall met Puppet, configuratiemanagement weet je wel, en dus werden al die regels proper gewist. Dus werkte het vanzelfsprekend niet.
Gelukkig is dat niet zo moeilijk om op te lossen.
Een paar regels toevoegen:
-A INPUT -s 10.89.0.0/16 -p tcp -m multiport --dports 53 -m comment --comment "200 ALLOW DNS FROM CONTAINERS (TCP)" -j ACCEPT
-A INPUT -s 10.89.0.0/16 -p udp -m multiport --dports 53 -m comment --comment "200 ALLOW DNS FROM CONTAINERS (UDP)" -j ACCEPT
-A FORWARD -m comment --comment "200 JUMP TO NETAVARK" -j NETAVARK_FORWARD
En voila! De containers draaien! Je ziet, veel eenvoudger dan de webservers van vroeger!
do-release-upgrade
Mijn firewall-perikelen waren nog niet achter de rug. Op een andere machine heb ik een upgrade gedaan van Ubuntu 20.04 LTS (die EOL is) naar 22.04 LTS. Dit is niet zo speciaal, en het is ook niet de eerste keer dat ik dat doe. Maar nu was er toch echt wel iets vreemds aan de hand.
Er was geen enkel netwerkverkeer. Geen SSH, geen ping, niets. Maar er was wel een IP, een verbinding en een juiste route. Zeer vreemd. Ik heb zeer lang gezocht, meer plots kwam daar een random blog post gevonden tijdens het Googelen voor gevorderden.
Zou het een firewallprobleem kunnen zijn?
root@echnaton:~# iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Mijn God, ja! Hoe komt dat daar?
Ik beheer, zoals je hierboven kan lezen, al mijn firewallregels met puppet. En de standaardpolicy is DROP, alleen wordt SSH enzo toegestaan door regels die daar boven komen. Maar na een release upgrade zijn die weg. Nuttig om te weten, en gelukkig niet moeilijk om op te lossen:
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
En dan weer puppet aan de praat krijgen en we zijn weer vertrokken!