Debugging Methodology¶
Systematic Approach¶
When troubleshooting network/firewall issues, follow this systematic process:
1. Define the Problem
↓
2. Gather Information
↓
3. Isolate the Layer
↓
4. Test Hypothesis
↓
5. Implement Fix
↓
6. Verify Solution
Step 1: Define the Problem¶
Ask Specific Questions¶
- What exactly isn't working?
- What error messages appear?
- When did it stop working?
- What changed recently?
Document Expected vs Actual¶
Step 2: Gather Information¶
Network Configuration¶
# IP addresses
ip addr show
# Routes
ip route show
# DNS
resolvectl status
# Listening ports
ss -tlnp
Firewall State¶
# UFW status
ufw status verbose
# iptables rules
iptables -L -n -v
iptables -t nat -L -n -v
# Connection tracking
conntrack -L
Service State¶
# Docker
docker ps
docker network ls
# libvirt
virsh list --all
virsh net-list --all
# LXD
lxc list
lxc network list
Step 3: Isolate the Layer¶
OSI Model Approach¶
Layer 7 - Application (service config)
Layer 4 - Transport (ports, firewall)
Layer 3 - Network (IP, routing)
Layer 2 - Data Link (bridges, VLANs)
Layer 1 - Physical (cables, NICs)
Quick Tests by Layer¶
Layer 1-2 (Physical/Link):
# Interface up?
ip link show eth0
# Cable connected?
ethtool eth0 | grep "Link detected"
# Bridge members?
bridge link show
Layer 3 (Network):
# Can ping gateway?
ping -c 3 192.168.1.1
# Can ping destination?
ping -c 3 8.8.8.8
# Route exists?
ip route get 8.8.8.8
Layer 4 (Transport/Firewall):
# Port open locally?
ss -tlnp | grep :80
# Port reachable?
nc -zv localhost 80
# Firewall blocking?
iptables -L -n -v | grep -E "DROP|REJECT"
Layer 7 (Application):
# Service running?
systemctl status nginx
# Service responding?
curl -v http://localhost/
# Logs show errors?
journalctl -u nginx -f
Step 4: Test Hypothesis¶
Form a Hypothesis¶
Based on gathered information:
"Traffic is being blocked by UFW because there's no allow rule for port 8080"
Test It¶
# Temporarily disable UFW
sudo ufw disable
# Test again
curl http://server:8080
# If works, hypothesis confirmed
# Re-enable UFW
sudo ufw enable
Alternative: Add Logging¶
# Add logging rule
iptables -I INPUT -p tcp --dport 8080 -j LOG --log-prefix "[TEST-8080] "
# Generate traffic
curl http://server:8080
# Check logs
journalctl -k | grep TEST-8080
Step 5: Implement Fix¶
Make Minimal Changes¶
Don't change multiple things at once.
Document Changes¶
Step 6: Verify Solution¶
Test the Original Problem¶
Test for Regressions¶
Verify Persistence¶
Common Debugging Scenarios¶
Scenario: Container Can't Reach Internet¶
# 1. Check container has IP
docker exec container ip addr
# 2. Check can ping gateway (docker0)
docker exec container ping -c 1 172.17.0.1
# 3. Check can ping host's external IP
docker exec container ping -c 1 192.168.1.100
# 4. Check can ping external
docker exec container ping -c 1 8.8.8.8
# 5. If step 4 fails, check NAT
sudo iptables -t nat -L POSTROUTING -n -v | grep 172.17
# 6. Check IP forwarding
cat /proc/sys/net/ipv4/ip_forward
Scenario: Service Unreachable from Outside¶
# 1. Service listening?
ss -tlnp | grep :8080
# 2. Reachable locally?
curl localhost:8080
# 3. Reachable from host IP?
curl 192.168.1.100:8080
# 4. Check firewall
sudo iptables -L INPUT -n -v | grep 8080
sudo ufw status | grep 8080
# 5. If Docker, check Docker rules
sudo iptables -t nat -L DOCKER -n
sudo iptables -L DOCKER-USER -n
Scenario: VM Has No Network¶
# 1. VM interface up?
virsh domiflist vmname
# 2. Bridge exists?
ip link show virbr0
# 3. libvirt network running?
virsh net-list
# 4. From VM console, check IP
# (virsh console vmname)
ip addr
ip route
# 5. Check DHCP
journalctl | grep dnsmasq
# 6. Check forwarding rules
sudo iptables -L FORWARD -n -v | grep virbr0
Debugging Tools¶
Essential Tools¶
# Install if needed
sudo apt install -y \
net-tools \
tcpdump \
nmap \
traceroute \
dnsutils \
conntrack
tcpdump Examples¶
# All traffic on interface
tcpdump -i eth0
# Specific port
tcpdump -i eth0 port 80
# Specific host
tcpdump -i eth0 host 192.168.1.100
# Docker bridge
tcpdump -i docker0
# Write to file
tcpdump -i eth0 -w capture.pcap
iptables Debugging¶
# Packet counts
iptables -L -n -v
# Trace packets
iptables -t raw -A PREROUTING -p tcp --dport 80 -j TRACE
dmesg | grep TRACE
# Log specific traffic
iptables -I INPUT -p tcp --dport 80 -j LOG --log-prefix "[HTTP] "
Checklist Template¶
Use this checklist for systematic debugging:
## Issue: [Description]
### Symptoms
- [ ] Error message:
- [ ] When:
- [ ] Frequency:
### Environment
- [ ] Host:
- [ ] Docker version:
- [ ] libvirt version:
- [ ] UFW status:
### Layer 1-2 (Physical/Link)
- [ ] Interface up:
- [ ] Link detected:
- [ ] Bridge OK:
### Layer 3 (Network)
- [ ] IP assigned:
- [ ] Gateway reachable:
- [ ] External reachable:
### Layer 4 (Transport)
- [ ] Port listening:
- [ ] Firewall rules:
- [ ] NAT rules:
### Layer 7 (Application)
- [ ] Service running:
- [ ] Service responding:
- [ ] Logs:
### Root Cause
[Analysis]
### Solution
[Fix applied]
### Verification
- [ ] Problem resolved:
- [ ] No regressions:
- [ ] Survives reboot: