mirror of
https://gitlab.com/hacklab01/pivilion.git
synced 2026-08-06 16:08:22 +00:00
Fix captive portal detection and restore MOTD
This commit is contained in:
parent
3b7a16564b
commit
34b4c4b036
9 changed files with 153 additions and 59 deletions
|
|
@ -3,21 +3,11 @@ set -euo pipefail
|
|||
source /usr/local/lib/pivilion/common.sh
|
||||
pivilion_load_config
|
||||
|
||||
mode=$(pivilion_current_mode)
|
||||
torname="not generated yet"
|
||||
[ ! -s "$PIVILION_DIR/torname" ] || torname=$(tr -d '\r\n' < "$PIVILION_DIR/torname")
|
||||
uptime_text=$(uptime -p 2>/dev/null || true)
|
||||
pivilion_print_motd
|
||||
|
||||
cat <<EOF
|
||||
|
||||
Welcome to Pivilion!
|
||||
|
||||
Host...............: $(uname -n)
|
||||
System.............: $(uname -srmo)
|
||||
Uptime.............: ${uptime_text:-unknown}
|
||||
Mode after reboot..: $mode
|
||||
Onion address......: $torname
|
||||
Web root...........: $PIVILION_WEBROOT
|
||||
Web root: $PIVILION_WEBROOT
|
||||
|
||||
Commands:
|
||||
pivilion show this status
|
||||
|
|
@ -28,4 +18,5 @@ Commands:
|
|||
static convert the current gallery to static files
|
||||
hotglue install or restore Hotglue
|
||||
htaccess reset or remove captive redirect rules
|
||||
pivilion-diagnose check captive DNS, HTTP redirects, and services
|
||||
EOF
|
||||
|
|
|
|||
4
usr/local/bin/pivilion-diagnose
Executable file
4
usr/local/bin/pivilion-diagnose
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
[ "$(id -u)" -eq 0 ] || exec sudo "$0" "$@"
|
||||
exec /usr/local/lib/pivilion/mode.sh diagnose
|
||||
|
|
@ -111,3 +111,30 @@ pivilion_current_mode() {
|
|||
pivilion_require_root() {
|
||||
[ "$(id -u)" -eq 0 ] || { echo "This operation must run as root (use sudo)." >&2; return 1; }
|
||||
}
|
||||
|
||||
pivilion_print_motd() {
|
||||
local heading=${1:-Welcome to Pivilion!}
|
||||
local uptime_text memory_free memory_total load_one load_five load_fifteen processes torname mode
|
||||
|
||||
uptime_text=$(uptime -p 2>/dev/null || printf 'unknown')
|
||||
memory_free=$(awk '/^MemAvailable:/ {print $2; exit}' /proc/meminfo 2>/dev/null)
|
||||
memory_total=$(awk '/^MemTotal:/ {print $2; exit}' /proc/meminfo 2>/dev/null)
|
||||
read -r load_one load_five load_fifteen _ < /proc/loadavg
|
||||
processes=$(ps ax --no-headers 2>/dev/null | wc -l)
|
||||
torname=not-generated-yet
|
||||
[ ! -s "$PIVILION_DIR/torname" ] || torname=$(tr -d '\r\n' < "$PIVILION_DIR/torname")
|
||||
mode=$(pivilion_current_mode)
|
||||
|
||||
printf '\n%s\n' "$heading"
|
||||
cat <<EOF
|
||||
@@@@@@@@@@@@@@@@@@@ $(date '+%A, %e %B %Y, %r')
|
||||
@@@@@@, &@& *@@@@@@ $(uname -srnmo)
|
||||
@@@@@@@. .@@@@@@@ Uptime.............: $uptime_text
|
||||
@@@@ .@@@. @@@@ Memory.............: ${memory_free:-unknown}kB (Available) / ${memory_total:-unknown}kB (Total)
|
||||
@ &@@@@.@@@@# @ Load Averages......: $load_one, $load_five, $load_fifteen (1, 5, 15 min)
|
||||
@ @ . #@@@# . @ @ Running Processes..: $processes
|
||||
@ @@@, # ,@@@ @ Manual / more info.: pivilion.net
|
||||
@@, @ ,@@ Onion Address......: $torname
|
||||
@@@@@#@@@@@@@#@@@@@ Running in $mode mode
|
||||
EOF
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,77 @@ IFACE=$(pivilion_wifi_interface)
|
|||
RUN_DIR=/run/pivilion
|
||||
DNSMASQ_CONF=/etc/dnsmasq.d/pivilion-runtime.conf
|
||||
NM_HOTSPOT=pivilion-hotspot
|
||||
CAPTIVE_TEMPLATE=$PIVILION_DIR/config/html/.htaccess
|
||||
CAPTIVE_LIVE=$PIVILION_WEBROOT/gen/.htaccess
|
||||
|
||||
install_captive_redirect() {
|
||||
local tmp
|
||||
[ -r "$CAPTIVE_TEMPLATE" ] || {
|
||||
echo "Captive redirect template is missing: $CAPTIVE_TEMPLATE" >&2
|
||||
return 1
|
||||
}
|
||||
[ -d "$PIVILION_WEBROOT/gen" ] || {
|
||||
echo "Gallery webroot is missing: $PIVILION_WEBROOT/gen" >&2
|
||||
return 1
|
||||
}
|
||||
tmp=$(mktemp "$PIVILION_WEBROOT/gen/.htaccess.XXXXXX")
|
||||
if ! install -m 0644 -o root -g www-data "$CAPTIVE_TEMPLATE" "$tmp"; then
|
||||
rm -f "$tmp"
|
||||
return 1
|
||||
fi
|
||||
mv -f "$tmp" "$CAPTIVE_LIVE"
|
||||
}
|
||||
|
||||
diagnostic_result() {
|
||||
local label=$1
|
||||
shift
|
||||
if "$@"; then
|
||||
printf ' [ok] %s\n' "$label"
|
||||
return 0
|
||||
fi
|
||||
printf ' [fail] %s\n' "$label" >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
probe_redirect() {
|
||||
local host=$1 path=$2 headers
|
||||
headers=$(curl --silent --show-error --max-time 5 --dump-header - --output /dev/null \
|
||||
--header "Host: $host" "http://10.1.1.1$path") || return 1
|
||||
grep -Eq '^HTTP/[0-9.]+ 302([[:space:]]|$)' <<<"$headers" &&
|
||||
grep -Eiq '^Location:[[:space:]]*http://10\.1\.1\.1/index\.php\r?$' <<<"$headers"
|
||||
}
|
||||
|
||||
dns_points_to_portal() {
|
||||
local host=$1 answer
|
||||
answer=$(dig +short A @10.1.1.1 "$host" 2>/dev/null | tail -n1)
|
||||
[ "$answer" = 10.1.1.1 ]
|
||||
}
|
||||
|
||||
apache_rewrite_enabled() {
|
||||
apache2ctl -M 2>/dev/null | grep -q 'rewrite_module'
|
||||
}
|
||||
|
||||
nft_portal_table_active() {
|
||||
nft list table inet pivilion >/dev/null 2>&1
|
||||
}
|
||||
|
||||
hotspot_diagnostics() {
|
||||
local failures=0
|
||||
echo "Pivilion hotspot diagnostics:"
|
||||
diagnostic_result "Apache is active" systemctl is-active --quiet apache2 || failures=$((failures + 1))
|
||||
diagnostic_result "Apache rewrite module is enabled" apache_rewrite_enabled || failures=$((failures + 1))
|
||||
diagnostic_result "live captive redirect matches its template" cmp -s "$CAPTIVE_TEMPLATE" "$CAPTIVE_LIVE" || failures=$((failures + 1))
|
||||
diagnostic_result "Pivilion dnsmasq is active" systemctl is-active --quiet pivilion-dnsmasq.service || failures=$((failures + 1))
|
||||
diagnostic_result "captive DNS resolves Android probe" dns_points_to_portal connectivitycheck.gstatic.com || failures=$((failures + 1))
|
||||
diagnostic_result "Pivilion nftables table is active" nft_portal_table_active || failures=$((failures + 1))
|
||||
diagnostic_result "Android probe receives portal redirect" probe_redirect connectivitycheck.gstatic.com /generate_204 || failures=$((failures + 1))
|
||||
diagnostic_result "Apple probe receives portal redirect" probe_redirect captive.apple.com /hotspot-detect.html || failures=$((failures + 1))
|
||||
diagnostic_result "Microsoft probe receives portal redirect" probe_redirect www.msftconnecttest.com /connecttest.txt || failures=$((failures + 1))
|
||||
[ "$failures" -eq 0 ] || {
|
||||
echo "$failures hotspot diagnostic check(s) failed." >&2
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
stop_hotspot() {
|
||||
systemctl stop pivilion-dnsmasq.service 2>/dev/null || true
|
||||
|
|
@ -56,6 +127,7 @@ EOF
|
|||
|
||||
start_hotspot() {
|
||||
stop_hotspot
|
||||
install_captive_redirect
|
||||
rfkill unblock wifi 2>/dev/null || true
|
||||
systemctl start apache2
|
||||
if pivilion_uses_networkmanager; then
|
||||
|
|
@ -87,6 +159,7 @@ EOF
|
|||
dnsmasq --test --conf-file="$DNSMASQ_CONF"
|
||||
systemctl restart pivilion-dnsmasq.service
|
||||
start_firewall
|
||||
hotspot_diagnostics
|
||||
echo "Pivilion hotspot '$PIVILION_HOTSPOT_SSID' is active on $IFACE (10.1.1.1)."
|
||||
}
|
||||
|
||||
|
|
@ -120,7 +193,7 @@ start_onion() {
|
|||
systemctl restart dhcpcd 2>/dev/null || true
|
||||
systemctl restart "wpa_supplicant@$IFACE.service" 2>/dev/null || systemctl restart wpa_supplicant 2>/dev/null || true
|
||||
fi
|
||||
rm -f "$PIVILION_WEBROOT/gen/.htaccess"
|
||||
rm -f "$CAPTIVE_LIVE"
|
||||
systemctl start apache2
|
||||
if systemctl cat tor@default.service >/dev/null 2>&1; then
|
||||
systemctl restart tor@default.service
|
||||
|
|
@ -134,5 +207,6 @@ start_onion() {
|
|||
case "$MODE" in
|
||||
hotspot) start_hotspot ;;
|
||||
onion) start_onion ;;
|
||||
diagnose) hotspot_diagnostics ;;
|
||||
*) echo "Unknown Pivilion mode: $MODE" >&2; exit 2 ;;
|
||||
esac
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue