#!/bin/bash # Fix Incus network connectivity issues # Usage: ./fix-network.sh [container-name] set -euo pipefail # Colors GREEN='\033[0;32m' BLUE='\033[0;34m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' NETWORK="veza-network" CONTAINER="${1:-}" echo -e "${BLUE}🔧 Fixing Incus network connectivity${NC}" echo "" # 1. Check IP forwarding on host echo -e "${BLUE}1. Checking IP forwarding on host...${NC}" if [ "$(cat /proc/sys/net/ipv4/ip_forward)" != "1" ]; then echo -e "${YELLOW} IP forwarding is disabled, enabling...${NC}" echo "1" | sudo tee /proc/sys/net/ipv4/ip_forward >/dev/null echo -e "${GREEN} ✅ IP forwarding enabled${NC}" # Make it persistent if ! grep -q "net.ipv4.ip_forward=1" /etc/sysctl.conf 2>/dev/null; then echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf >/dev/null echo -e "${GREEN} ✅ IP forwarding made persistent${NC}" fi else echo -e "${GREEN} ✅ IP forwarding is enabled${NC}" fi # 2. Check network bridge echo -e "${BLUE}2. Checking network bridge...${NC}" BRIDGE_NAME=$(incus network show ${NETWORK} | grep -E "^name:" | awk '{print $2}' || echo "") if [ -z "${BRIDGE_NAME}" ]; then BRIDGE_NAME="incusbr0" # Default Incus bridge name fi # Find the actual bridge interface ACTUAL_BRIDGE=$(ip link show | grep -E "incus|veza" | grep -v "@" | head -1 | cut -d: -f2 | tr -d ' ' || echo "") if [ -z "${ACTUAL_BRIDGE}" ]; then # Try to find bridge by network ACTUAL_BRIDGE=$(ip -br link show | grep -E "incus|veza" | head -1 | awk '{print $1}' || echo "") fi if [ -n "${ACTUAL_BRIDGE}" ]; then echo -e "${GREEN} ✅ Found bridge: ${ACTUAL_BRIDGE}${NC}" # Check if bridge is up if ip link show ${ACTUAL_BRIDGE} | grep -q "state UP"; then echo -e "${GREEN} ✅ Bridge is UP${NC}" else echo -e "${YELLOW} ⚠️ Bridge is DOWN, bringing up...${NC}" sudo ip link set ${ACTUAL_BRIDGE} up || true fi else echo -e "${YELLOW} ⚠️ Could not find bridge interface${NC}" fi # 3. Restart network to apply NAT echo -e "${BLUE}3. Restarting network to apply NAT...${NC}" if incus network show ${NETWORK} >/dev/null 2>&1; then # Stop and start network to refresh NAT incus network set ${NETWORK} ipv4.nat=true incus network set ${NETWORK} ipv4.dhcp=true echo -e "${GREEN} ✅ Network configuration refreshed${NC}" else echo -e "${RED} ❌ Network ${NETWORK} does not exist${NC}" exit 1 fi # 4. Fix containers if specified if [ -n "${CONTAINER}" ]; then echo -e "${BLUE}4. Fixing network in container ${CONTAINER}...${NC}" if ! incus list -c n --format csv | grep -q "^${CONTAINER}$"; then echo -e "${RED} ❌ Container ${CONTAINER} does not exist${NC}" exit 1 fi # Get container IP from Incus device config (most reliable) CONTAINER_IP=$(incus config device show ${CONTAINER} 2>/dev/null | grep "ipv4.address" | head -1 | awk '{print $2}' || echo "") # Fallback to list output if [ -z "${CONTAINER_IP}" ] || [ "${CONTAINER_IP}" = "" ]; then CONTAINER_IP=$(incus list ${CONTAINER} --format csv | cut -d',' -f4 | awk '{print $1}' | head -1 || echo "") fi # Fallback to network leases if [ -z "${CONTAINER_IP}" ] || [ "${CONTAINER_IP}" = "" ]; then CONTAINER_IP=$(incus network list-leases ${NETWORK} 2>/dev/null | grep "${CONTAINER}" | awk '{print $4}' | head -1 || echo "") fi if [ -z "${CONTAINER_IP}" ] || [ "${CONTAINER_IP}" = "" ]; then echo -e "${RED} ❌ Could not determine container IP${NC}" echo " Current network state:" incus exec ${CONTAINER} -- ip addr show eth0 2>/dev/null || true exit 1 fi echo -e "${BLUE} Container IP: ${CONTAINER_IP}${NC}" # Fix network inside container if ! incus exec ${CONTAINER} -- bash -c " set -e # Remove any existing IP ip addr flush dev eth0 2>/dev/null || true # Add IP ip addr add ${CONTAINER_IP}/24 dev eth0 2>/dev/null || \ ip addr replace ${CONTAINER_IP}/24 dev eth0 # Remove old default route ip route del default 2>/dev/null || true # Add default route (CRITICAL for NAT) ip route add default via 10.10.10.1 dev eth0 # Verify route if ! ip route | grep -q 'default via 10.10.10.1'; then echo 'ERROR: Default route not set' exit 1 fi # Configure DNS rm -f /etc/resolv.conf echo 'nameserver 8.8.8.8' > /etc/resolv.conf echo 'nameserver 1.1.1.1' >> /etc/resolv.conf # Restart systemd-resolved if available systemctl restart systemd-resolved 2>/dev/null || true "; then echo -e "${RED} ❌ Failed to configure network in container${NC}" exit 1 fi # Wait a moment for network to stabilize sleep 2 # Test connectivity echo -e "${BLUE} Testing connectivity...${NC}" # Test gateway if incus exec ${CONTAINER} -- ping -c 3 -W 3 10.10.10.1 >/dev/null 2>&1; then echo -e "${GREEN} ✅ Gateway (10.10.10.1) reachable${NC}" else echo -e "${RED} ❌ Gateway not reachable${NC}" echo " Current routes:" incus exec ${CONTAINER} -- ip route show 2>/dev/null || true fi # Test Internet if incus exec ${CONTAINER} -- ping -c 3 -W 3 8.8.8.8 >/dev/null 2>&1; then echo -e "${GREEN} ✅ Internet (8.8.8.8) reachable${NC}" else echo -e "${RED} ❌ Internet not reachable${NC}" echo -e "${YELLOW} ⚠️ NAT may not be working.${NC}" echo " Diagnostic commands:" echo " - Check IP forwarding: cat /proc/sys/net/ipv4/ip_forward" echo " - Check NAT rules: sudo iptables -t nat -L -n -v" echo " - Check bridge: ip addr show | grep -A 5 incus" fi # Test DNS if incus exec ${CONTAINER} -- getent hosts google.com >/dev/null 2>&1; then echo -e "${GREEN} ✅ DNS resolution working${NC}" else echo -e "${YELLOW} ⚠️ DNS resolution failed${NC}" fi else echo -e "${BLUE}4. To fix a specific container, run:${NC}" echo " $0 " echo "" echo "Available containers:" incus list veza- --format csv 2>/dev/null | cut -d',' -f1 | sed 's/^/ - /' || echo " No containers found" fi echo "" echo -e "${GREEN}✅ Network fix complete!${NC}"