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!