uzbek-plus/b12/router/router-up.sh

77 lines
3.7 KiB
Bash

#!/bin/sh
# B12 router-up (runtime-only, nothing persistent): Wi-Fi LAN -> DHCP/DNS (dnsmasq, LAN only) -> nftables NAT -> wwan0.
# USB NCM management (usb0) untouched; Wi-Fi clients cannot reach the board except DHCP/DNS/ping, nor the mgmt subnet.
. "$(dirname "$0")/router-common.sh"
set -u
fail() { log "FAIL: $*"; echo "ROUTER-UP FAIL"; exit 1; }
log "=== ROUTER UP"
[ -x $B/sbin/nft ] && [ -x $B/sbin/dnsmasq ] || fail "bundle $B missing"
nft list tables >/dev/null 2>&1 || fail "kernel has no nf_tables (needs 7.2.7-aurora-b12)"
[ -e /sys/class/net/$LAN_IF ] || fail "$LAN_IF absent"
[ -e /sys/class/net/$WAN_IF ] || fail "$WAN_IF absent"
DNS=; [ -f /run/aurora-modem/ipcfg ] && DNS=$(sed -n 's/^DNS=//p' /run/aurora-modem/ipcfg | tr ',' ' ')
[ -n "$DNS" ] || DNS=$FALLBACK_DNS
mkdir -p $S
# 1. sysctl (save originals once)
[ -f $S/sysctl.saved ] || { echo "ip_forward=$(cat /proc/sys/net/ipv4/ip_forward)" > $S/sysctl.saved; }
# 2. LAN address
ip -4 addr show dev $LAN_IF | grep -q "inet $LAN_ADDR/" || ip addr add $LAN_ADDR/$LAN_PFX dev $LAN_IF || fail "addr $LAN_IF"
# 3. default route via LTE (only if none); remember that we added it
if ! ip route show default | grep -q .; then ip route add default dev $WAN_IF && echo $WAN_IF > $S/default.added || fail "default route"; fi
# 4. nftables (own table only; flushed/recreated atomically)
cat > $S/ruleset.nft <<N
table inet aurora_router
delete table inet aurora_router
table inet aurora_router {
chain input {
type filter hook input priority filter; policy accept;
ct state established,related accept
iifname "lo" accept
iifname "$MGMT_IF" accept
iifname "$LAN_IF" jump lan_in
iifname "$WAN_IF" jump wan_in
}
chain lan_in {
udp sport 68 udp dport 67 accept comment "DHCP (incl. broadcast)"
ip daddr != $LAN_ADDR counter drop comment "LAN may not touch mgmt/WAN addresses of the board"
udp dport 53 accept
tcp dport 53 accept
icmp type echo-request limit rate 20/second accept
meta l4proto ipv6-icmp accept
udp dport 547 drop
counter drop
}
chain wan_in {
icmp type { echo-reply, destination-unreachable, time-exceeded } accept
counter drop comment "no unsolicited inbound from LTE"
}
chain forward {
type filter hook forward priority filter; policy drop;
ct state invalid counter drop
iifname "$LAN_IF" oifname "$WAN_IF" ip saddr $LAN_NET counter accept
iifname "$WAN_IF" oifname "$LAN_IF" ct state established,related counter accept
iifname "$LAN_IF" oifname "$MGMT_IF" counter drop comment "Wi-Fi -> USB mgmt blocked"
iifname "$MGMT_IF" oifname "$LAN_IF" counter drop
counter drop comment "default deny (incl. LTE -> LAN)"
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
oifname "$WAN_IF" ip saddr $LAN_NET counter masquerade
}
}
N
nft -f $S/ruleset.nft || fail "nft ruleset"
echo 1 > /proc/sys/net/ipv4/ip_forward
# 5. dnsmasq on LAN only
if [ -z "$(dnsmasq_pid)" ]; then
{ echo "interface=$LAN_IF"; echo "except-interface=lo"; echo "bind-interfaces"; echo "no-resolv"; echo "no-hosts"
for d in $DNS; do echo "server=$d"; done
echo "dhcp-range=$DHCP_RANGE"; echo "dhcp-option=option:router,$LAN_ADDR"; echo "dhcp-option=option:dns-server,$LAN_ADDR"
echo "dhcp-leasefile=$S/dnsmasq.leases"; echo "dhcp-authoritative"; echo "cache-size=300"; echo "domain-needed"; echo "bogus-priv"
echo "pid-file=$S/dnsmasq.pid"; echo "log-facility=$S/dnsmasq.log"; echo "log-dhcp"; echo "user=root"; } > $S/dnsmasq.conf
bx dnsmasq --conf-file=$S/dnsmasq.conf || fail "dnsmasq start"
sleep 1
fi
[ -n "$(dnsmasq_pid)" ] || fail "dnsmasq not running"
log "LAN $LAN_IF $LAN_ADDR/$LAN_PFX dhcp $DHCP_RANGE dns-up [$DNS] wan $WAN_IF fwd=$(cat /proc/sys/net/ipv4/ip_forward) dnsmasq=$(dnsmasq_pid)"
echo "ROUTER-UP OK"