BASH
#!/bin/bash
# Hostsystem: CachyOS / Shell: zsh
# Editor-Tipp: micro
set -e

# --- KONFIGURATION ---
PHY="phy0"
REAL_IFACE="wlan0"
AP_INTERFACE="ap0"
TS_IFACE="tailscale0"
AP_MAC="d4:25:8b:38:3a:ee"
SSID="USER"
PASSPHRASE="interNET"
AP_IP="192.168.50.1/24"
DNSMASQ_PID_FILE="/tmp/dnsmasq_hotspot.pid"
DNSMASQ_LEASE_FILE="/tmp/dnsmasq_hotspot.leases"

if [ "$EUID" -ne 0 ]; then
    echo "Bitte mit sudo starten!"
    exit 1
fi

cleanup_iptables() {
    echo "Cleaning up hotspot-specific firewall rules..."
    # Normales Internet Cleanup
    iptables -t nat -D POSTROUTING -s 192.168.50.0/24 -o "$REAL_IFACE" -j MASQUERADE 2>/dev/null || true
    iptables -D FORWARD -i "$AP_INTERFACE" -o "$REAL_IFACE" -j ACCEPT 2>/dev/null || true
    iptables -D FORWARD -i "$REAL_IFACE" -o "$AP_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || true

    # === TAILSCALE CLEANUP ===
    iptables -t nat -D POSTROUTING -s 192.168.50.0/24 -o "$TS_IFACE" -j MASQUERADE 2>/dev/null || true
    iptables -D FORWARD -i "$AP_INTERFACE" -o "$TS_IFACE" -j ACCEPT 2>/dev/null || true
    iptables -D FORWARD -i "$TS_IFACE" -o "$AP_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || true
    # =========================

    iptables -D INPUT -i "$AP_INTERFACE" -p udp --dport 67:68 --sport 67:68 -j ACCEPT 2>/dev/null || true
    iptables -D INPUT -i "$AP_INTERFACE" -p udp --dport 53 -j ACCEPT 2>/dev/null || true
    iptables -D INPUT -i "$AP_INTERFACE" -p tcp --dport 53 -j ACCEPT 2>/dev/null || true
    iptables -D FORWARD -i "$AP_INTERFACE" -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu 2>/dev/null || true
    iptables -D INPUT -i "$AP_INTERFACE" -p tcp --dport 1714:1764 -j ACCEPT 2>/dev/null || true
    iptables -D INPUT -i "$AP_INTERFACE" -p udp --dport 1714:1764 -j ACCEPT 2>/dev/null || true
}
echo "Warte auf $PHY..."
for i in $(seq 1 30); do
    iw "$PHY" info &>/dev/null && break
    sleep 2
done

if ! iw "$PHY" info &>/dev/null; then
    echo "$PHY nicht verfügbar, Abbruch."
    exit 1
fi
echo "$PHY bereit"

# --- 1. GEZIELTES CLEANUP ---
echo "1. Cleanup..."
if [ -f "$DNSMASQ_PID_FILE" ]; then
    kill $(cat "$DNSMASQ_PID_FILE") 2>/dev/null || true
    rm -f "$DNSMASQ_PID_FILE"
fi

ip link set "$AP_INTERFACE" down 2>/dev/null || true
iw dev "$AP_INTERFACE" del 2>/dev/null || true
cleanup_iptables
sleep 1

# --- 2. KANAL-ERKENNUNG ---
CHANNEL=$(iw dev "$REAL_IFACE" info 2>/dev/null | awk '/channel/{print $2}')
if [ -z "$CHANNEL" ]; then
    CHANNEL=6
    echo "⚠️ Kanal nicht erkannt, nutze Standard $CHANNEL"
else
    echo "✅ Nutze Kanal $CHANNEL"
fi

# --- 3. VIRTUELLES AP-INTERFACE ---
echo "3. Erstelle Interface $AP_INTERFACE..."
iw phy "$PHY" interface add "$AP_INTERFACE" type __ap
ip link set "$AP_INTERFACE" address "$AP_MAC"
nmcli device set "$AP_INTERFACE" managed no 2>/dev/null || true
sleep 1
iw dev "$REAL_IFACE" set power_save off
sleep 1

# --- 4. IP-SETUP ---
echo "4. IP-Setup..."
ip addr flush dev "$AP_INTERFACE" 2>/dev/null || true
ip addr add "$AP_IP" dev "$AP_INTERFACE"
ip link set "$AP_INTERFACE" up
sleep 1

# --- 5. HOSTAPD CONFIG ---
cat > /tmp/hostapd.conf <<EOC
interface=$AP_INTERFACE
driver=nl80211
ssid=$SSID
hw_mode=g
channel=$CHANNEL
wpa=2
wpa_passphrase=$PASSPHRASE
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
wmm_enabled=1
EOC

# --- 6. DNSMASQ (Strikt isoliert ohne systemd-resolved Schleife) ---
echo "6. Starte dnsmasq..."
dnsmasq \
    --pid-file="$DNSMASQ_PID_FILE" \
    --dhcp-leasefile="$DNSMASQ_LEASE_FILE" \
    --interface="$AP_INTERFACE" \
    --listen-address="192.168.50.1" \
    --except-interface=lo \
    --bind-interfaces \
    --dhcp-range=192.168.50.10,192.168.50.100,12h \
    --no-resolv \
    --server=100.100.100.100 \
    --dhcp-option=option:dns-server,192.168.50.1 \
    --conf-file=/dev/null

# --- 7. Check für libvirt default network ---
if ! virsh -c qemu:///system net-list 2>/dev/null | awk '{print $1}' | grep -qx "default"; then
    echo "⚠️ Libvirt network was down, restarting..."
    virsh -c qemu:///system net-start default 2>/dev/null || true
fi

# --- 8. NAT & ROUTING (Ganz oben in iptables einspeisen) ---
echo 1 > /proc/sys/net/ipv4/ip_forward
echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/default/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/ap0/rp_filter 2>/dev/null || true
echo 0 > /proc/sys/net/ipv4/conf/tailscale0/rp_filter 2>/dev/null || true
echo 0 > /proc/sys/net/ipv4/conf/wlan0/rp_filter 2>/dev/null || true

cleanup_iptables

# Standard Internet-Routing
iptables -I FORWARD 1 -i "$AP_INTERFACE" -o "$REAL_IFACE" -j ACCEPT
iptables -I FORWARD 1 -i "$REAL_IFACE" -o "$AP_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -I POSTROUTING 1 -s 192.168.50.0/24 -o "$REAL_IFACE" -j MASQUERADE

# === TAILSCALE ROUTING ===
# Erlaubt Traffic von ap0 (ESP32) nach tailscale0 (VPS)
iptables -I FORWARD 1 -i "$AP_INTERFACE" -o "$TS_IFACE" -j ACCEPT
# Erlaubt Antwort-Pakete von tailscale0 zurück zu ap0
iptables -I FORWARD 1 -i "$TS_IFACE" -o "$AP_INTERFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT
# Maskiert die ESP32-IP (192.168.50.x) mit der Tailscale-IP deines Hosts, wenn es ins VPN geht
iptables -t nat -I POSTROUTING 1 -s 192.168.50.0/24 -o "$TS_IFACE" -j MASQUERADE
# =========================

# Explicitly allow DHCP and DNS traffic on the AP interface
iptables -I INPUT 1 -i "$AP_INTERFACE" -p udp --dport 67:68 --sport 67:68 -j ACCEPT
iptables -I INPUT 1 -i "$AP_INTERFACE" -p udp --dport 53 -j ACCEPT
iptables -I INPUT 1 -i "$AP_INTERFACE" -p tcp --dport 53 -j ACCEPT
# Explicitly allow KDE Connect traffic on the AP interface
iptables -I INPUT 1 -i "$AP_INTERFACE" -p tcp --dport 1714:1764 -j ACCEPT
iptables -I INPUT 1 -i "$AP_INTERFACE" -p udp --dport 1714:1764 -j ACCEPT

iptables -I FORWARD 1 -i "$AP_INTERFACE" -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
# --- 9. HOSTAPD ---
echo "Hotspot läuft. VMs bleiben ungestört."
trap 'echo "Beende..."; [ -f "$DNSMASQ_PID_FILE" ] && kill $(cat "$DNSMASQ_PID_FILE") && rm -f "$DNSMASQ_PID_FILE"; cleanup_iptables; ip link set "$AP_INTERFACE" down 2>/dev/null; iw dev "$AP_INTERFACE" del 2>/dev/null; exit' SIGINT SIGTERM

# hostapd im Vordergrund ausführen, damit systemd den Prozess tracken kann
exec hostapd /tmp/hostapd.conf

Hotspot stoppen

BASH
sudo pkill hostapd && sudo pkill dnsmasq && sudo iptables -t nat -F && sudo iw dev wlan0 del

Autostarz einrichten