#!/bin/bash # Immediate fix for Incus network - fixes all containers NOW # Usage: ./fix-network-now.sh 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" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" echo -e "${BLUE}🔧 IMMEDIATE FIX: Incus Network${NC}" echo "" # 0. Check host NAT tooling (Incus needs nftables or iptables to implement ipv4.nat=true) echo -e "${BLUE}0. Checking host NAT tooling (nftables/iptables)...${NC}" if ! command -v nft >/dev/null 2>&1 && ! command -v iptables >/dev/null 2>&1; then echo -e "${RED}❌ ERROR: Neither 'nft' nor 'iptables' is available on the host.${NC}" echo " This is the most common reason containers can reach 10.10.10.1 but not the Internet." echo "" echo " Install (Fedora):" echo " sudo dnf install -y nftables iptables-nft" echo "" echo " Then re-run:" echo " $0" exit 1 fi echo -e "${GREEN} ✅ Host NAT tooling present${NC}" # 1. Enable IP forwarding (CRITICAL) echo -e "${BLUE}1. Enabling IP forwarding...${NC}" if [ "$(cat /proc/sys/net/ipv4/ip_forward 2>/dev/null || echo 0)" != "1" ]; then if echo "1" | sudo tee /proc/sys/net/ipv4/ip_forward >/dev/null 2>&1; then echo -e "${GREEN} ✅ IP forwarding enabled${NC}" # Make 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 fi else echo -e "${RED} ❌ Failed to enable IP forwarding${NC}" echo " Run manually: sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'" exit 1 fi else echo -e "${GREEN} ✅ IP forwarding already enabled${NC}" fi # 2. Ensure network NAT is enabled (Incus config) echo -e "${BLUE}2. Ensuring Incus network NAT is enabled...${NC}" incus network set ${NETWORK} ipv4.nat=true 2>/dev/null || true incus network set ${NETWORK} ipv4.dhcp=true 2>/dev/null || true echo -e "${GREEN} ✅ Network NAT configured${NC}" # 2b. Ensure host forwarding + masquerade rules exist (Fedora can block FORWARD by default) echo -e "${BLUE}2b. Ensuring host NAT/FORWARD rules exist...${NC}" # Detect external interface (default route) EXT_IF="$(ip route get 8.8.8.8 2>/dev/null | awk '{for(i=1;i<=NF;i++) if ($i=="dev") {print $(i+1); exit}}')" if [ -z "${EXT_IF}" ]; then EXT_IF="$(ip route show default 2>/dev/null | awk '{print $5; exit}')" fi # Detect bridge interface by IP 10.10.10.1/24 (avoid regex portability issues) BR_IF="$(ip -o -4 addr show 2>/dev/null | awk '$4 == "10.10.10.1/24" {print $2; exit}')" if [ -z "${BR_IF}" ]; then # Fallback: try common Incus bridge names for c in incusbr0 lxdbr0 ${NETWORK}; do if ip link show "${c}" >/dev/null 2>&1; then BR_IF="${c}" break fi done fi if [ -z "${EXT_IF}" ] || [ -z "${BR_IF}" ]; then echo -e "${YELLOW} ⚠️ Could not auto-detect interfaces.${NC}" echo " External IF: ${EXT_IF:-}" echo " Bridge IF: ${BR_IF:-}" echo " You can still continue, but NAT may stay broken." else echo -e "${BLUE} External interface: ${EXT_IF}${NC}" echo -e "${BLUE} Bridge interface: ${BR_IF}${NC}" # Prefer iptables if available (works with iptables-nft backend on Fedora) if command -v iptables >/dev/null 2>&1; then # MASQUERADE for container subnet out of external interface if sudo iptables -t nat -C POSTROUTING -s 10.10.10.0/24 -o "${EXT_IF}" -j MASQUERADE >/dev/null 2>&1; then echo -e "${GREEN} ✅ iptables MASQUERADE rule already present${NC}" else sudo iptables -t nat -A POSTROUTING -s 10.10.10.0/24 -o "${EXT_IF}" -j MASQUERADE echo -e "${GREEN} ✅ Added iptables MASQUERADE rule${NC}" fi # Allow forwarding from bridge to external if sudo iptables -C FORWARD -i "${BR_IF}" -o "${EXT_IF}" -j ACCEPT >/dev/null 2>&1; then echo -e "${GREEN} ✅ iptables FORWARD bridge->ext already present${NC}" else sudo iptables -A FORWARD -i "${BR_IF}" -o "${EXT_IF}" -j ACCEPT echo -e "${GREEN} ✅ Added iptables FORWARD bridge->ext${NC}" fi # Allow established return traffic from external to bridge if sudo iptables -C FORWARD -i "${EXT_IF}" -o "${BR_IF}" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT >/dev/null 2>&1; then echo -e "${GREEN} ✅ iptables FORWARD ext->bridge (established) already present${NC}" else sudo iptables -A FORWARD -i "${EXT_IF}" -o "${BR_IF}" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT echo -e "${GREEN} ✅ Added iptables FORWARD ext->bridge (established)${NC}" fi else echo -e "${YELLOW} ⚠️ iptables not found; not adding explicit rules.${NC}" echo " If NAT is still broken, install iptables-nft and re-run:" echo " sudo dnf install -y iptables-nft" fi fi # 3. Fix all containers echo -e "${BLUE}3. Fixing network in all containers...${NC}" echo "" CONTAINERS=$(incus list veza- --format csv 2>/dev/null | cut -d',' -f1 || echo "") if [ -z "${CONTAINERS}" ]; then echo -e "${YELLOW}⚠️ No Veza containers found${NC}" exit 0 fi for CONTAINER in ${CONTAINERS}; do echo -e "${BLUE}--- Fixing ${CONTAINER} ---${NC}" # Get IP from device config CONTAINER_IP=$(incus config device show ${CONTAINER} 2>/dev/null | grep "ipv4.address" | head -1 | awk '{print $2}' || echo "") # Fallback methods if [ -z "${CONTAINER_IP}" ] || [ "${CONTAINER_IP}" = "" ]; then CONTAINER_IP=$(incus list ${CONTAINER} --format csv 2>/dev/null | cut -d',' -f4 | awk '{print $1}' | head -1 || echo "") fi # Determine IP from service type if still not found if [ -z "${CONTAINER_IP}" ] || [ "${CONTAINER_IP}" = "" ]; then case ${CONTAINER} in *infra*) CONTAINER_IP="10.10.10.10" ;; *backend-api*) CONTAINER_IP="10.10.10.2" ;; *chat-server*) CONTAINER_IP="10.10.10.3" ;; *stream-server*) CONTAINER_IP="10.10.10.4" ;; *web*) CONTAINER_IP="10.10.10.5" ;; *haproxy*) CONTAINER_IP="10.10.10.6" ;; *) echo -e "${YELLOW} ⚠️ Could not determine IP, skipping...${NC}"; continue ;; esac fi echo -e "${BLUE} IP: ${CONTAINER_IP}${NC}" # Fix network if incus exec ${CONTAINER} -- bash -c " set -e # Flush 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 routes ip route del default 2>/dev/null || true ip route del 10.10.10.0/24 2>/dev/null || true # Add routes ip route add 10.10.10.0/24 dev eth0 proto kernel scope link src ${CONTAINER_IP} ip route add default via 10.10.10.1 dev eth0 # Verify if ! ip route | grep -q 'default via 10.10.10.1'; then exit 1 fi # DNS rm -f /etc/resolv.conf echo 'nameserver 8.8.8.8' > /etc/resolv.conf echo 'nameserver 1.1.1.1' >> /etc/resolv.conf systemctl restart systemd-resolved 2>/dev/null || true " 2>/dev/null; then echo -e "${GREEN} ✅ Network configured${NC}" # Test sleep 1 if incus exec ${CONTAINER} -- ping -c 1 -W 1 8.8.8.8 >/dev/null 2>&1; then echo -e "${GREEN} ✅ Internet connectivity OK${NC}" else echo -e "${YELLOW} ⚠️ Internet connectivity test failed${NC}" fi else echo -e "${RED} ❌ Failed to configure network${NC}" fi echo "" done echo -e "${GREEN}✅ Network fix complete!${NC}" echo "" echo "Test connectivity:" echo " incus exec veza-infra -- ping -c 2 8.8.8.8"