1 ## @defgroup captive_portal Captive Portal 2 ## @brief Funktionen für den Umgang mit der Captive-Portal-Software für offene WLAN-Knoten 3 # Beginn der Doku-Gruppe 7 # shellcheck disable=SC2034 10 ## @var Quelldatei für Standardwerte des Hotspot-Pakets 11 ON_CAPTIVE_PORTAL_DEFAULTS_FILE=/usr/share/opennet/captive-portal.defaults
14 ## @fn configure_free_network() 15 ## @brief Erzeuge das free-Netzwerk-Interface, falls es noch nicht existiert. 17 local uci_prefix=
"network.$NETWORK_FREE" 18 # es wurde bereits einmalig konfiguriert 19 if [ -z
"$(uci_get "$uci_prefix
")" ]; then
20 uci
set "${uci_prefix}=interface" 21 uci
set "${uci_prefix}.ifname=none" 22 uci
set "${uci_prefix}.proto=static" 23 uci
set "${uci_prefix}.ipaddr=$(get_on_captive_portal_default free_ipaddress)" 24 uci
set "${uci_prefix}.netmask=$(get_on_captive_portal_default free_netmask)" 25 uci
set "${uci_prefix}.auto=1" 29 uci_prefix=$(find_first_uci_section
"dhcp" "dhcp" "interface=$NETWORK_FREE")
30 # beenden, falls vorhanden
31 if [ -z
"$uci_prefix" ]; then
32 # DHCP-Einstellungen fuer dieses Interface festlegen 33 uci_prefix=
"dhcp.$(uci add "dhcp
" "dhcp
")" 34 uci
set "${uci_prefix}.interface=$NETWORK_FREE" 35 uci
set "${uci_prefix}.start=10" 36 uci
set "${uci_prefix}.limit=240" 37 uci
set "${uci_prefix}.leasetime=30m" 43 ## @fn get_on_captive_portal_default() 44 ## @param key Name des Schlüssels 45 ## @brief Liefere einen der default-Werte der aktuellen Firmware zurück (Paket on-captive-portal). 46 ## @details Die default-Werte werden nicht von der Konfigurationsverwaltung uci verwaltet. 47 ## Somit sind nach jedem Upgrade imer die neuesten Standard-Werte verfügbar. 54 ## @fn captive_portal_has_devices() 55 ## @brief Prüfe, ob dem Captive Portal mindestens ein physisches Netzwerk-Gerät zugeordnet ist. 56 ## @details Sobald ein Netzwerk-Gerät konfiguriert ist, gilt der Captive-Portal-Dienst als aktiv. 57 ## Es werden sowohl nicht-wifi-, als auch wifi-Interfaces geprueft. 59 [ -n
"$(get_subdevices_of_interface "$NETWORK_FREE
")" ] &&
return 0
60 [ -n
"$(find_all_uci_sections wireless wifi-iface "network=$NETWORK_FREE
")" ] &&
return 0
61 trap
"" EXIT &&
return 1
65 ## @fn captive_portal_repair_empty_network_bridge() 66 ## @brief Reduziere Konstruktionen wie beispielsweise "bridge(None, wlan0)" zu "wlan0". 67 ## @details Brücken mit "none"-Elementen verwirren das nodogsplash-Start-Skript. 69 local uci_prefix=
"network.${NETWORK_FREE}" 70 local sub_device_count
71 if [
"$(uci_get "${uci_prefix}.type
")" =
"bridge" ] && [
"$(uci_get "${uci_prefix}.ifname
")" =
"none" ]; then
72 # verdaechtig: Bruecke mit "none"-Device 74 if [
"$sub_device_count" -eq
"1" ]; then
75 # wifi-Device is konfiguriert - Bruecke und "none" kann entfernt werden 79 # nichts ist konfiguriert - erstmal nur die Bruecke entfernen 87 ## @fn captive_portal_uses_wifi_only_bridge() 88 ## @brief Prüfe ob eine fehleranfällige Brige-Konstruktion vorliegt. 89 ## @details Reine wifi-Bridges scheinen mit openwrt nicht nutzbar zu sein. 91 local uci_prefix=
"network.${NETWORK_FREE}" 93 if [
"$(uci_get "${uci_prefix}.type
")" =
"bridge" ]; then
94 ifname=$(uci_get
"${uci_prefix}.ifname")
95 if [ -z
"$ifname" ] || [
"$ifname" =
"none" ]; then
96 if [ -n
"$(get_subdevices_of_interface "$NETWORK_FREE
")" ]; then
97 # anscheinend handelt es sich um eine reine wifi-Bridge 102 trap
"" EXIT &&
return 1
110 disable_captive_portal
115 change_captive_portal_wireless_disabled_state() {
118 find_all_uci_sections wireless wifi-iface
"network=$NETWORK_FREE" |
while read -r uci_prefix;
do 119 uci
set "${uci_prefix}.disabled=$state" 121 apply_changes wireless
125 disable_captive_portal() {
126 trap
"error_trap disable_captive_portal" EXIT
127 msg_info "on-captive-portal: wifi-Interfaces abschalten" 128 # free-Interface ist aktiv - es gibt jedoch keinen Tunnel 129 change_captive_portal_wireless_disabled_state
"1" 133 ## @fn sync_captive_portal_state_with_mig_connections() 134 ## @brief Synchronisiere den Zustand (up/down) des free-Interface mit dem des VPN-Tunnel-Interface. 135 ## @details Diese Funktion wird nach Statusänderungen des VPN-Interface, sowie innerhalb eines 136 ## regelmäßigen cronjobs ausgeführt. 138 trap
"error_trap sync_captive_portal_state_with_mig_connections" EXIT
139 # eventuelle defekte/verwirrende Netzwerk-Konfiguration korrigieren 141 # Abbruch, falls keine Netzwerk-Interfaces zugeordnet wurden 148 # Pruefe ob mindestens eine IPv4-Adresse konfiguriert ist. 149 # (aus unbekannten Gruenden kann es vorkommen, dass die IPv4-Adresse spontan wegfaellt) 151 is_ipv4 "$address" && device_active=1 &&
break 155 if [ -n
"$device_active" ] && [ -z
"$mig_active" ]; then
156 disable_captive_portal
157 elif [ -n
"$mig_active" ]; then
158 [ -z
"$device_active" ] && ifup
"$NETWORK_FREE" 159 change_captive_portal_wireless_disabled_state
"0" 164 ## @fn is_captive_portal_running() 165 ## @brief Prüfe ob das Netzwerk-Interface des Captive-Portal aktiv ist. 168 trap
"" EXIT &&
return 1
172 ## @fn get_captive_portal_client_count() 173 ## @brief Ermittle die Anzahl der verbundenen Clients. Leere Ausgabe, falls keine aktiven 174 ## Interfaces vorhanden sind. 183 if assoclist=$(iwinfo
"$device" assoclist 2>/dev/
null); then
184 this_count=$(echo
"$assoclist" | awk
'{ if (($1 == "TX:") && ($(NF-1) >= 100)) count++; } END { print count; }')
186 # determine the number of valid arp cache items
for this interface
187 this_count=$(ip neighbor list dev
"$device" | grep -c
'REACHABLE$' ||
true)
189 count=$((count + this_count))
192 # Liefere keine Ausgabe (leer), falls wir gar nichts zum Zaehlen gefunden haben. 193 # Dadurch kann das munin-Plugin (und andere Aufrufer) erkennen, dass das Portal nicht 195 [ -z
"$count" ] &&
return 0
200 ## @fn get_captive_portal_clients() 201 ## @brief Zeilenweise aller aktuellen Clients inklusive ihrer relevanten Kenngrößen. 202 ## @details In jeder Zeile wird ein Client beschrieben, wobei die folgenden Detailinformationen durch Tabulatoren getrennt sind: 205 ## * Zeitpunkt des Verbindungsaufbaus (seit epoch) 206 ## * Zeitpunkt der letzten Aktivität (seit epoch) 207 ## * Download-Verkehrsvolumen (kByte) 208 ## * Upload-Verkehrsvolumen (kByte) 209 ## Der Einfachheit halber nehmen wir an, dass alle DHCP-Clients auch Captive-Portal-Clients sind. 211 trap
'error_trap get_captive_portal_clients "'"$*"'"' EXIT
216 # Die "iwinfo assoclist" ist wahrscheinlich der einzige brauchbare Weg, um 217 # Verkehrsstatistiken zu beliebigen Peers zu erhalten. Wir müssen es also gar nicht erst 218 # mit anderen (nicht-wifi) Interfaces versuchen. 221 iwinfo wlan0 assoclist 2>/dev/
null ||
true;
done)
222 # erzwinge eine leere Zeile am Ende fuer die finale Ausgabe des letzten Clients
223 # shellcheck disable=SC2034
224 while read -r timestamp mac_address ip_address hostname misc;
do 225 # eine assoclist-Zeile sieht etwa folgendermassen aus: 226 # TX: 6.5 MBit/s, MCS 0, 20MHz 217 Pkts. 227 packets_rxtx=$(echo
"$assoclist" | awk
' 228 BEGIN { my_mac = tolower("'"$mac_address"'"); } 230 if ($1 ~ /^(..:){5}..$/) current_mac = tolower($1); 231 if (($1 == "RX:") && (my_mac == current_mac)) my_rx=$(NF-1); 232 if (($1 == "TX:") && (my_mac == current_mac)) my_tx=$(NF-1); 234 END { OFS="\t"; print(my_rx, my_tx); }')
235 printf
'%s\t%s\t%s\t%s\n' "$ip_address" "$mac_address" "$timestamp" "$packets_rxtx" 236 done </var/dhcp.leases
239 # Ende der Doku-Gruppe uci_delete(uci_path)
Lösche ein UCI-Element.
get_captive_portal_clients()
Zeilenweise aller aktuellen Clients inklusive ihrer relevanten Kenngrößen.
set eu case in on captive portal on function update_captive_portal_status
is_ipv4(target)
Prüfe ob der übergebene Text eine IPv4-Adresse ist.
sync_captive_portal_state_with_mig_connections()
Synchronisiere den Zustand (up/down) des free-Interface mit dem des VPN-Tunnel-Interface.
_get_file_dict_value(key)
Auslesen eines Werts aus einem Schlüssel/Wert-Eingabestrom.
set eu grep root::etc shadow exit if command v chpasswd dev null
msg_info(message)
Informationen und Fehlermeldungen ins syslog schreiben.
is_interface_up(interface)
Prüfe ob ein logisches Netzwerk-Interface aktiv ist.
get_on_captive_portal_default(key)
Liefere einen der default-Werte der aktuellen Firmware zurück (Paket on-captive-portal).
get_subdevices_of_interface()
Ermittle die physischen Netzwerk-Geräte (bis auf wifi), die zu einem logischen Netzwerk-Interface geh...
get_current_addresses_of_network()
Liefere die IP-Adressen eines logischen Interface inkl. Praefix-Laenge (z.B. 172.16.0.1/24, network).
captive_portal_repair_empty_network_bridge()
Reduziere Konstruktionen wie beispielsweise "bridge(None, wlan0)" zu "wlan0".
captive_portal_has_devices()
Prüfe, ob dem Captive Portal mindestens ein physisches Netzwerk-Gerät zugeordnet ist.
configure_free_network()
Erzeuge das free-Netzwerk-Interface, falls es noch nicht existiert.
is_captive_portal_running()
Prüfe ob das Netzwerk-Interface des Captive-Portal aktiv ist.
get_active_mig_connections()
Liefere die aktiven VPN-Verbindungen (mit Mesh-Internet-Gateways) zurück.
get_captive_portal_client_count()
Ermittle die Anzahl der verbundenen Clients. Leere Ausgabe, falls keine aktiven Interfaces vorhanden ...
captive_portal_uses_wifi_only_bridge()
Prüfe ob eine fehleranfällige Brige-Konstruktion vorliegt.
is_on_module_installed_and_enabled(module)
Pruefe ob ein Modul sowohl installiert, als auch aktiv ist.