95 lines
5.5 KiB
Bash
95 lines
5.5 KiB
Bash
#!/bin/sh
|
|
# Aurora router (B12R, runtime state only in /run): aurora-router up | down | status
|
|
# up: wlan0 192.168.77.1/24, default route via wwan0 (only if none), nftables table inet aurora_router (NAT LAN->wwan0, default-deny forward,
|
|
# no LTE->LAN, Wi-Fi blocked from the USB mgmt subnet and from every board address except 192.168.77.1 DHCP/DNS/ping), ip_forward=1,
|
|
# dnsmasq bound to wlan0 only (upstream = bearer DNS).
|
|
# down: undo exactly that. Needs kernel nf_tables (7.2.7-aurora-b12).
|
|
. /etc/aurora/router.conf
|
|
S=/run/aurora-router; LOG=$S/router.log; mkdir -p $S
|
|
now() { cut -d' ' -f1 /proc/uptime; }
|
|
log() { m="[$(now)] $*"; echo "$m"; echo "$m" >> $LOG; echo "<5>[aurora-router] $*" > /dev/kmsg 2>/dev/null; }
|
|
fail() { log "FAIL: $*"; exit 1; }
|
|
dpid() { [ -f $S/dnsmasq.pid ] && kill -0 "$(cat $S/dnsmasq.pid)" 2>/dev/null && cat $S/dnsmasq.pid; }
|
|
case "$1" in
|
|
up)
|
|
log "=== ROUTER UP"
|
|
nft list tables >/dev/null 2>&1 || fail "kernel has no nf_tables ($(uname -r))"
|
|
[ -e /sys/class/net/$LAN_IF ] || fail "$LAN_IF absent"; [ -e /sys/class/net/$WAN_IF ] || fail "$WAN_IF absent"
|
|
DNS=$(sed -n 's/^DNS=//p' /run/aurora-modem/ipcfg 2>/dev/null | tr ',' ' '); [ -n "$DNS" ] || DNS=$FALLBACK_DNS
|
|
[ -f $S/ip_forward.saved ] || cat /proc/sys/net/ipv4/ip_forward > $S/ip_forward.saved
|
|
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"
|
|
if ! ip route | grep -q "^default"; then ip route add default dev $WAN_IF && echo $WAN_IF > $S/default.added || fail "default route"; fi
|
|
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 "Wi-Fi may not touch mgmt/WAN addresses of the board"
|
|
udp dport 53 accept
|
|
tcp dport 22 accept comment "B17: SSH (dropbear) from Wi-Fi to the board LAN address only"
|
|
tcp dport 53 accept
|
|
icmp type echo-request limit rate 20/second accept
|
|
meta l4proto ipv6-icmp accept
|
|
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
|
|
# B15: aurora-vpn owns the firewall while up (fail-closed LAN -> tunnel); a late router up (AP enabled after VPN) must not
|
|
# re-add aurora_router, whose forward chain drops LAN -> wg0/singtun0 (both forward hooks must accept).
|
|
if nft list table inet aurora_vpn >/dev/null 2>&1; then log "aurora_vpn table present: keep VPN firewall, skip aurora_router ruleset"
|
|
else nft -f $S/ruleset.nft || fail "nft ruleset"; fi
|
|
echo 1 > /proc/sys/net/ipv4/ip_forward
|
|
if [ -z "$(dpid)" ]; 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
|
|
dnsmasq --conf-file=$S/dnsmasq.conf || fail "dnsmasq"; sleep 1
|
|
fi
|
|
[ -n "$(dpid)" ] || fail "dnsmasq not running"
|
|
log "=== ROUTER UP OK lan $LAN_IF $LAN_ADDR/$LAN_PFX dhcp $DHCP_RANGE dns [$DNS] wan $WAN_IF default=[$(ip route | grep "^default")] fwd=$(cat /proc/sys/net/ipv4/ip_forward) dnsmasq=$(dpid)";;
|
|
down)
|
|
log "=== ROUTER DOWN"
|
|
p=$(dpid); [ -n "$p" ] && { kill $p; sleep 1; }; rm -f $S/dnsmasq.pid
|
|
nft list table inet aurora_router >/dev/null 2>&1 && nft delete table inet aurora_router
|
|
[ -f $S/ip_forward.saved ] && { cat $S/ip_forward.saved > /proc/sys/net/ipv4/ip_forward; rm -f $S/ip_forward.saved; }
|
|
ip addr del $LAN_ADDR/$LAN_PFX dev $LAN_IF 2>/dev/null
|
|
[ -f $S/default.added ] && { ip route del default dev "$(cat $S/default.added)" 2>/dev/null; rm -f $S/default.added; }
|
|
log "=== ROUTER DOWN OK fwd=$(cat /proc/sys/net/ipv4/ip_forward) tables=[$(nft list tables 2>/dev/null | tr '\n' ' ')] default=[$(ip route | grep "^default")]";;
|
|
status)
|
|
echo "kernel $(uname -r) ip_forward=$(cat /proc/sys/net/ipv4/ip_forward) dnsmasq=$(dpid)"
|
|
ip -4 addr show dev $LAN_IF | grep inet; ip route | grep "^default"
|
|
echo "-- leases"; cat $S/dnsmasq.leases 2>/dev/null
|
|
echo "-- stations"; iw dev $LAN_IF station dump 2>/dev/null | grep -E "^Station|signal:|connected time"
|
|
echo "-- conntrack $(cat /proc/sys/net/netfilter/nf_conntrack_count 2>/dev/null)"
|
|
nft list table inet aurora_router 2>&1 | grep -E "counter|chain"
|
|
tail -3 $LOG 2>/dev/null;;
|
|
*) echo "usage: $0 up|down|status"; exit 2;;
|
|
esac
|