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