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
9 ## @var Quelldatei für Standardwerte des Hotspot-Pakets
10 ON_CAPTIVE_PORTAL_DEFAULTS_FILE=/usr/share/opennet/captive-portal.defaults
13 ## @fn configure_free_network()
14 ## @brief Erzeuge das free-Netzwerk-Interface, falls es noch nicht existiert.
16 local uci_prefix=
"network.$NETWORK_FREE"
17 # es wurde bereits einmalig konfiguriert
18 if [ -z
"$(uci_get "$uci_prefix
")" ]; then
19 uci set
"${uci_prefix}=interface"
20 uci set
"${uci_prefix}.ifname=none"
21 uci set
"${uci_prefix}.proto=static"
22 uci set
"${uci_prefix}.ipaddr=$(get_on_captive_portal_default free_ipaddress)"
23 uci set
"${uci_prefix}.netmask=$(get_on_captive_portal_default free_netmask)"
24 # wir aktivieren das Interface manuell via hotplug
25 uci set
"${uci_prefix}.auto=0"
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 captive_portal_get_or_create_config()
44 ## @brief Liefere die uci-captive-Portal-Konfigurationssektion zurück.
45 ## @details Typischerweise ist dies so etwas wie nodogsplash.cfgXXXX. Falls die uci-Sektion noch
46 ## nicht existieren sollte, dann wird sie erzeugt und zurückgeliefert.
48 trap
"error_trap captive_portal_get_or_create_config '$*'" $GUARD_TRAPS
50 uci_prefix=$(find_first_uci_section
"nodogsplash" "instance" "network=$NETWORK_FREE")
51 # gefunden? Zurueckliefern ...
52 if [ -z
"$uci_prefix" ]; then
53 # neu mit grundlegenden Einstellungen anlegen
54 # Detail-Konfiguration findet via uci-defaults nur einmalig statt (damit der Nutzer sie überschreiben kann)
55 uci_prefix=
"nodogsplash.$(uci add "nodogsplash
" "instance
")"
56 # wir aktivieren den Dienst generell - der Nutzer muss dem Device aktiv ein Gerät hinzufügen, um es zu aktivieren
57 uci set
"${uci_prefix}.enabled=1"
58 uci set
"${uci_prefix}.network=$NETWORK_FREE"
59 uci set
"${uci_prefix}.gatewayname=$(get_on_captive_portal_default "node_name
")"
60 uci set
"${uci_prefix}.redirecturl=$(get_on_captive_portal_default "portal_url
")"
61 uci set
"${uci_prefix}.maxclients=250"
62 # kein Zwischen-Klick, keine lokale Webseite
63 uci set
"${uci_prefix}.authenticateimmediately=1"
64 # Wir definieren keine "authenticated"-Regeln: nodogsplash verwendet "RETURN", falls
65 # diese Liste leer ist. Dies ist wünschenswert, auf dass wir mit unserer firewall-
66 # Einstellung der free-Zone den gewünschten Verkehrsfluss regeln können. Typischerweise
67 # ist hier lediglich eine free->on_openvpn-Zonenregel erforderlich.
68 # Demgegenüber ist es für den "users-to-router"-Verkehr praktischer, die einfachen
69 # nodogsplash-Einstellungen zu verwenden. Dadurch vermeiden wir die Verwaltung
70 # separater firewall-Regeln.
71 # ssh/web (nur fuer Debugging)
72 #uci add_list "${uci_prefix}.users_to_router=allow tcp port 22"
73 #uci add_list "${uci_prefix}.users_to_router=allow tcp port 443"
75 uci add_list
"${uci_prefix}.users_to_router=allow tcp port 53"
76 uci add_list
"${uci_prefix}.users_to_router=allow udp port 53"
78 uci add_list
"${uci_prefix}.users_to_router=allow udp port 67"
79 # jeglichen Verkehr ohne Interaktion zulassen
80 # (lediglich der erste Zugriff auf Port 80 wird auf die Portalseite umgelenkt)
81 uci set
"${uci_prefix}.policy_preauthenticated_users=passthrough"
82 # erstmal nur speichern - um die Anwendung kuemmert sich jemand anders
83 uci commit nodogsplash
89 ## @fn get_on_captive_portal_default()
90 ## @param key Name des Schlüssels
91 ## @brief Liefere einen der default-Werte der aktuellen Firmware zurück (Paket on-captive-portal).
92 ## @details Die default-Werte werden nicht von der Konfigurationsverwaltung uci verwaltet.
93 ## Somit sind nach jedem Upgrade imer die neuesten Standard-Werte verfügbar.
100 ## @fn captive_portal_set_property()
101 ## @brief Setze ein Attribut der Captive-Portal-Funktion
102 ## @param key Eins der Captive-Portal-Attribute: name / url
103 ## @param value Der gewünschte neue Inhalt des Attributs
104 ## @attention Anschließend ist 'apply_changes on-captive-portal' aufzurufen, um die Änderungen wirksam werden zu lassen.
110 # ein Fehler ist aufgetreten - die obige subshell verdeckt ihn jedoch
111 [ -z
"$uci_attribute" ] &&
return 1
114 uci set
"${uci_prefix}.${uci_attribute}=$value"
118 ## @fn captive_portal_get_property()
119 ## @brief Hole ein Attribut der Captive-Portal-Funktion
120 ## @param key Eins der Captive-Portal-Attribute: name / url
125 # ein Fehler ist aufgetreten - die obige subshell verdeckt ihn jedoch
126 [ -z
"$uci_attribute" ] &&
return 1
129 uci_get
"${uci_prefix}.${uci_attribute}"
133 ## @fn _captive_portal_get_mapped_attribute()
134 ## @brief Liefere den UCI-Attribut-Namen für eine Captive-Portal-Eigenschaft zurück.
135 ## @param attribute Eins der Captive-Portal-Attribute: name / url
136 ## @details Dies ist lediglich eine Abstraktionsschicht.
139 if [
"$attribute" =
"name" ]; then
140 echo -n
"gatewayname"
141 elif [
"$attribute" =
"url" ]; then
142 echo -n
"redirecturl"
144 msg_error "unknown captive portal attribute mapping requested: $attribute"
150 ## @fn captive_portal_restart()
151 ## @brief Führe einen Neustart der Captive-Portal-Software mit minimalen Seiteneffekten durch.
152 ## @details Aktuelle Verbindungen bleiben nach Möglichkeit erhalten.
154 trap
"error_trap captive_portal_restart '$*'" $GUARD_TRAPS
155 # alte Clients-Liste sichern; keine Fehlerausgabe bei gestopptem Prozess
157 clients=$(ndsctl clients 2>/dev/
null | grep
"^ip=" | cut -f 2 -
d =)
158 # Prozess neustarten (reload legt wohl keine iptables-Regeln an)
159 /etc/init.d/nodogsplash restart >/dev/
null
160 # kurz warten, damit der Dienst startet
162 # kein laufender Prozess? Keine Wiederherstellung von Clients ...
163 [ -z
"$(pidof nodogsplash)" ] &&
return 0
164 # Client-Liste wiederherstellen
166 echo
"$clients" |
while read ip;
do
167 [ -z
"$ip" ] &&
continue
173 ## @fn captive_portal_reload()
174 ## @brief Neukonfiguration der Captive-Portal-Software, falls Änderungen aufgetreten sind.
175 ## @details Bestehende Verbindungen bleiben erhalten.
177 /etc/init.d/nodogsplash reload >/dev/
null
181 ## @fn captive_portal_has_devices()
182 ## @brief Prüfe, ob dem Captive Portal mindestens ein physisches Netzwerk-Gerät zugeordnet ist.
183 ## @details Sobald ein Netzwerk-Gerät konfiguriert ist, gilt der Captive-Portal-Dienst als aktiv.
185 [ -n
"$(get_subdevices_of_interface "$NETWORK_FREE
")" ] &&
return 0
186 trap
"" $GUARD_TRAPS &&
return 1
190 ## @fn captive_portail_repair_empty_network_bridge()
191 ## @brief Reduziere Konstruktionen wie beispielsweise "bridge(None, wlan0)" zu "wlan0".
192 ## @details Brücken mit "none"-Elementen verwirren das nodogsplash-Start-Skript.
194 local uci_prefix=
"network.${NETWORK_FREE}"
196 if [
"$(uci_get "${uci_prefix}.type
")" =
"bridge" -a
"$(uci_get "${uci_prefix}.ifname
")" =
"none" ]; then
197 # verdaechtig: Bruecke mit "none"-Device
198 if [ -n
"$sub_devices" ]; then
199 # wifi-Device is konfiguriert - Bruecke und "none" kann entfernt werden
203 # nichts ist konfiguriert - erstmal nur die Bruecke entfernen
206 apply_changes network
211 update_captive_portal_status() {
215 disable_captive_portal
220 disable_captive_portal() {
221 # free-Interface ist aktive - es gibt jedoch keinen Tunnel
222 ifdown
"$NETWORK_FREE"
223 # reload fuehrt zum sanften Stoppen
229 ## @fn sync_captive_portal_state_with_mig_connections()
230 ## @brief Synchronisiere den Zustand (up/down) des free-Interface mit dem des VPN-Tunnel-Interface.
231 ## @details Diese Funktion wird nach Statusänderungen des VPN-Interface, sowie innerhalb eines
232 ## regelmäßigen cronjobs ausgeführt.
234 trap
"error_trap sync_captive_portal_state_with_mig_connections '$*'" $GUARD_TRAPS
235 # eventuelle defekte/verwirrende Netzwerk-Konfiguration korrigieren
237 # Abbruch, falls keine Netzwerk-Interfaces zugeordnet wurden
244 # Pruefe ob mindestens eine IPv4-Adresse konfiguriert ist.
245 # (aus unbekannten Gruenden kann es vorkommen, dass die IPv4-Adresse spontan wegfaellt)
247 is_ipv4 "$address" && device_active=1 &&
break
251 if [ -n
"$device_active" -a -z
"$mig_active" ]; then
252 disable_captive_portal
253 elif [ -z
"$device_active" -a -n
"$mig_active" ]; then
254 # kein aktives free-Interface, aber ein aktiver Tunnel
257 # warte auf das Netzwerk-Interface
259 # Portalsoftware neu laden, falls das Interface aktiv ist, jedoch kein Prozess laeuft
265 ## @fn is_captive_portal_running()
266 ## @brief Prüfe ob der Captive-Portal-Dienst läuft.
268 [ -n
"$(pgrep "^/usr/bin/nodogsplash$
")" ] &&
return 0
269 trap
"" $GUARD_TRAPS &&
return 1
273 ## @fn get_captive_portal_client_count()
274 ## @brief Ermittle die Anzahl der verbundenen Clients.
283 ## @brief Zeilenweise aller aktuellen Clients inklusive ihrer relevanten Kenngrößen.
284 ## @details In jeder Zeile wird ein Client beschrieben, wobei die folgenden Detailinformationen durch Tabulatoren getrennt sind:
287 ## * Zeitpunkt des Verbindungsaufbaus (seit epoch)
288 ## * Zeitpunkt der letzten Aktivität (seit epoch)
289 ## * Download-Verkehrsvolumen (kByte)
290 ## * Upload-Verkehrsvolumen (kByte)
292 trap
"error_trap get_captive_portal_clients '$*'" $GUARD_TRAPS
298 local connection_timestamp=
299 local activity_timestamp=
300 local traffic_download=
301 local traffic_upload=
302 # erzwinge eine leere Zeile am Ende fuer die finale Ausgabe des letzten Clients
303 (ndsctl clients; echo) |
while read line;
do
304 key=$(echo
"$line" | cut -f 1 -d =)
305 value=$(echo
"$line" | cut -f 2- -d =)
306 [
"$key" =
"ip" ] && ip_address=
"$value"
307 [
"$key" =
"mac" ] && mac_address=
"$value"
308 [
"$key" =
"added" ] && connection_timestamp=
"$value"
309 [
"$key" =
"active" ] && activity_timestamp=
"$value"
310 [
"$key" =
"downloaded" ] && traffic_download=
"$value"
311 [
"$key" =
"uploaded" ] && traffic_upload=
"$value"
312 if [ -z
"$key" -a -n
"$ip_address" ]; then
313 # leere Eingabezeile trennt Clients: Ausgabe des vorherigen Clients
314 printf
"%s\t%s\t%s\t%s\t%s\t%s\n" \
315 "$ip_address" "$mac_address" "$connection_timestamp" \
316 "$activity_timestamp" "$traffic_download" "$traffic_upload"
319 connection_timestamp=
327 # 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.
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.
_captive_portal_get_mapped_attribute(attribute)
Liefere den UCI-Attribut-Namen für eine Captive-Portal-Eigenschaft zurück.
_get_file_dict_value(key)
Auslesen eines Werts aus einem Schlüssel/Wert-Eingabestrom.
captive_portal_get_or_create_config()
Liefere die uci-captive-Portal-Konfigurationssektion zurück.
captive_portal_get_property(key)
Hole ein Attribut der Captive-Portal-Funktion.
captive_portal_reload()
Neukonfiguration der Captive-Portal-Software, falls Änderungen aufgetreten sind.
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_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.
set eu on function print_services services log for dir in etc on services d var on services volatile d
is_captive_portal_running()
Prüfe ob der Captive-Portal-Dienst läuft.
get_active_mig_connections()
Liefere die aktiven VPN-Verbindungen (mit Mesh-Internet-Gateways) zurück.
msg_error(message)
Die Fehlermeldungen werden in die Standard-Fehlerausgabe und ins syslog geschrieben.
captive_portal_set_property(key, value)
Setze ein Attribut der Captive-Portal-Funktion.
set eu grep root::etc shadow exit if which chpasswd dev null
captive_portal_restart()
Führe einen Neustart der Captive-Portal-Software mit minimalen Seiteneffekten durch.
get_captive_portal_client_count()
Ermittle die Anzahl der verbundenen Clients.
is_on_module_installed_and_enabled(module)
Pruefe ob ein Modul sowohl installiert, als auch aktiv ist.
captive_portail_repair_empty_network_bridge()
Reduziere Konstruktionen wie beispielsweise "bridge(None, wlan0)" zu "wlan0".