Beurteilung Programmcode, Wlan AP mit selbst geschriebenem Captive Portal in bash
Ich bin relativ neu im Umgang mit Linux und möchte meine Programmierkenntnisse vertiefen.
Deshalb interessiert mich eure Meinung zu meinem Code.
Falls jemand Zeit und Lust hat kann er gerne Kritik üben, denn nur so lernt man.
Ich brauchte für einen privaten Fall einen WLAN Hotspot der einen Internetzugang für bestimmte Geräte zulässt.
Ein ganz einfaches System, dass genauso einfach zu bedienen ist.
Umgesetzt mit einem Raspberry Pi 3b+.
Mir ist klar, dass der Pi für diesen Zweck eher ungeeignet ist, allerdings war es vorhanden und reicht als Testgerät vollkommen aus (2-10 Clients Zeitgleich).
Logging des Traffics sowie die Traffic Performance sind nicht relevant.
Es geht schlicht darum den Zugang zum Internet zu managen.
Mir ist auch bekannt, dass diese Funktion eine Firewall oder durch am Markt erhältliche AP's bereitgestellt werden kann.
Ich dachte mir bevor ich die Zeit in die Recherche und Umsetzung einer vorhandenen Lösung investieren (und es im Nachhinein dann doch nicht den Anforderungen zu 100 % entspricht, oder total oversized ist), schreib ich mir den Code selbst und lern dabei.
Anleitung Raspberry als WLAN AP betreiben von aqui:
Netzwerk Management Server mit Raspberry Pi
Raspberry Pi dient als Wlan AP und managed den Traffic.
Per default sperre ich jeglichen Traffic.
SSID und Passwort hängen aus, es kann sich also jeder der Zugang zu den Räumlichkeiten hat mit dem AP verbinden.
Will ein User Internetzugang kann er diesen (vorausgesetzt er hat einen Code) über eine Website des Pi's freischalten.
Der Code wird geprüft und dann die IP und die MAC gespeichert inkl. der Zeit bis wann der Client Zugang erhält.
Über eine Regel in den iptables wird der Zugang für den Client freigegeben.
Jede Nacht um 12 läuft ein Script, dass überprüft ob die Zeit der jeweiligen Clients abgelaufen ist.
Hier rechne ich ausschließlich in Tage, (Stundenweise ist nicht interessant, der aktuelle Tag wird nicht in die Rechnung mit einbezogen.
D.h. ein 1 Tages Pass schaltet den Internetzugang frei bis zum Ablauf des darauffolgenden Tages.
Die Codes können in einer Datei definiert werden.
Für diesen Fall habe ich einen Telegram Chat Bot eingerichtet, der folgende Funktionen bereitstellt:
- Codes eingetragen
- versendet Bestätigung wenn sich ein Client erfolgreich registriert
- Übersicht der freigeschaltenen Clients anzeigen mit Zeitangaben
- Übersicht der aktuellen Codes anzeigen
Der Code besteht aus 8 Zahlen, die ersten 6 sind individuell und die letzten 2 definieren die Dauer, die der Client Zugang erhält.
Die Codes gelangen auf 2 Wegen zu den Usern:
- Neuer Code wird per Telegram über den Chat Bot eingetragen und dann per Telegramm/Whatsapp an den User weitergeleitet.
- Codes werden vorab in der codes Datei definiert und dann ausgedruckt und im Bedarfsfall weitergegeben.
Die Codes könnten auch über eine weitere Website oder direkt durch bearbeiten der Codes Datei eingetragen werden.
Inhalt von wlangeraete.txt in der Form:
Ip-Adresse Mac-Adresse yy Tag-des-Jahres(1-365) Client-Name
192.168.xxx.xxx xx:xx:xx:xx:xx:xx 19 85 Name
Inhalt von codes.txt in der Form:
xxxxxx01 # 1 Tages Pass
xxxxxx07 # 1 Wochen Pass
xxxxxx30 # 1 Monats Pass
xxxxxx00 # 1 JahresPass
wlansysstart.sh # erstellt Forward Routen in den iptables. Wird beim Systemstart, bei neuer Userfreischaltung und beim User löschen ausgeführt.
checkgeraete.sh # wird nächtlich um 24 Uhr ausgeführt, prüft ob Client Zeit abgelaufen ist
get-mac-addr.sh # wird ausgeführt wenn ein User sich über die Website des Pi's mit einem Code registriert
Das PHP script übergibt die Client IP und den eingegebenen Code und zeigt dem User die echo Ausgabe dieses Scripts.
Deshalb interessiert mich eure Meinung zu meinem Code.
Falls jemand Zeit und Lust hat kann er gerne Kritik üben, denn nur so lernt man.
Ich brauchte für einen privaten Fall einen WLAN Hotspot der einen Internetzugang für bestimmte Geräte zulässt.
Ein ganz einfaches System, dass genauso einfach zu bedienen ist.
Umgesetzt mit einem Raspberry Pi 3b+.
Mir ist klar, dass der Pi für diesen Zweck eher ungeeignet ist, allerdings war es vorhanden und reicht als Testgerät vollkommen aus (2-10 Clients Zeitgleich).
Logging des Traffics sowie die Traffic Performance sind nicht relevant.
Es geht schlicht darum den Zugang zum Internet zu managen.
Mir ist auch bekannt, dass diese Funktion eine Firewall oder durch am Markt erhältliche AP's bereitgestellt werden kann.
Ich dachte mir bevor ich die Zeit in die Recherche und Umsetzung einer vorhandenen Lösung investieren (und es im Nachhinein dann doch nicht den Anforderungen zu 100 % entspricht, oder total oversized ist), schreib ich mir den Code selbst und lern dabei.
Anleitung Raspberry als WLAN AP betreiben von aqui:
Netzwerk Management Server mit Raspberry Pi
Raspberry Pi dient als Wlan AP und managed den Traffic.
Per default sperre ich jeglichen Traffic.
SSID und Passwort hängen aus, es kann sich also jeder der Zugang zu den Räumlichkeiten hat mit dem AP verbinden.
Will ein User Internetzugang kann er diesen (vorausgesetzt er hat einen Code) über eine Website des Pi's freischalten.
Der Code wird geprüft und dann die IP und die MAC gespeichert inkl. der Zeit bis wann der Client Zugang erhält.
Über eine Regel in den iptables wird der Zugang für den Client freigegeben.
Jede Nacht um 12 läuft ein Script, dass überprüft ob die Zeit der jeweiligen Clients abgelaufen ist.
Hier rechne ich ausschließlich in Tage, (Stundenweise ist nicht interessant, der aktuelle Tag wird nicht in die Rechnung mit einbezogen.
D.h. ein 1 Tages Pass schaltet den Internetzugang frei bis zum Ablauf des darauffolgenden Tages.
Die Codes können in einer Datei definiert werden.
Für diesen Fall habe ich einen Telegram Chat Bot eingerichtet, der folgende Funktionen bereitstellt:
- Codes eingetragen
- versendet Bestätigung wenn sich ein Client erfolgreich registriert
- Übersicht der freigeschaltenen Clients anzeigen mit Zeitangaben
- Übersicht der aktuellen Codes anzeigen
Der Code besteht aus 8 Zahlen, die ersten 6 sind individuell und die letzten 2 definieren die Dauer, die der Client Zugang erhält.
Die Codes gelangen auf 2 Wegen zu den Usern:
- Neuer Code wird per Telegram über den Chat Bot eingetragen und dann per Telegramm/Whatsapp an den User weitergeleitet.
- Codes werden vorab in der codes Datei definiert und dann ausgedruckt und im Bedarfsfall weitergegeben.
Die Codes könnten auch über eine weitere Website oder direkt durch bearbeiten der Codes Datei eingetragen werden.
Inhalt von wlangeraete.txt in der Form:
Ip-Adresse Mac-Adresse yy Tag-des-Jahres(1-365) Client-Name
192.168.xxx.xxx xx:xx:xx:xx:xx:xx 19 85 Name
Inhalt von codes.txt in der Form:
xxxxxx01 # 1 Tages Pass
xxxxxx07 # 1 Wochen Pass
xxxxxx30 # 1 Monats Pass
xxxxxx00 # 1 JahresPass
wlansysstart.sh # erstellt Forward Routen in den iptables. Wird beim Systemstart, bei neuer Userfreischaltung und beim User löschen ausgeführt.
sudo iptables -F # alle Forward Routen der iptables löschen
sudo iptables -t nat -A POSTROUTING -j MASQUERADE #maskierung
sudo sysctl -w net.ipv4.ip_forward=1 > /dev/null #weiterleitung
sudo iptables -A FORWARD -o eth0 -i wlan0 -j DROP #alles blocken
URLFILE=/home/pi/wlangeraete.txt # Liste der zugelassenen Wlan Geräte
while read line || [ "$line" != "" ] #Liste auslesen und mit dem Inhalt eine Forward Route erstellen
do
ipaddr=$(echo $line | awk '{ print $1 }')
macaddr=$(echo $line | awk '{ print $2 }')
sudo iptables -I FORWARD -o eth0 -i wlan0 -s $ipaddr -m mac --mac-source $macaddr -j ACCEPT
done < $URLFILE
checkgeraete.sh # wird nächtlich um 24 Uhr ausgeführt, prüft ob Client Zeit abgelaufen ist
typeset -i jahrist=$(date +%g) # aktuelles Jahr im Format yy speichern
# date +%j gibt den tag des Jahres 1-365 als 3 Ziffern aus(z.b.: 007, 056, 244). folgende Fallunterscheidung entfernt die Nullen am Anfang.
if [ $(echo $(date +%j) | cut -c1-2) = 00 ]; then
typeset -i datumist=$(echo $(date +%j) | cut -c3)
elif [ $(echo $(date +%j) | cut -c1) = 0 ]; then
typeset -i datumist=$(echo $(date +%j) | cut -c2-3)
else
typeset -i datumist=$(echo $(date +%j))
fi
URLFILE=/home/pi/wlangeraete.txt # Liste der zugelassenen Wlan Geräte
while read line || [ "$line" != "" ]
do
ipaddr=$(echo $line | awk '{ print $1 }') # ip aus wlangeraete.txt
macaddr=$(echo $line | awk '{ print $2 }') # mac aus wlangeraete.txt
typeset -i jahr=$(echo $line | awk '{ print $3 }') # jahr aus wlangeraete.txt
typeset -i datum=$(echo $line | awk '{ print $4 }') # tag aus wlangeraete.txt
ausdruck=$line
# Prüfen ob Client Zeit abgelaufen ist und ggf. aus Liste wlangeraete.txt löschen
if [ $jahr -lt $jahrist ]; then
sed -i '/'$ipaddr'/d' $URLFILE
elif [ $jahr = $jahrist ]; then
if [ $datum -lt $datumist ]; then
sed -i '/'$ipaddr'/d' $URLFILE
fi
fi
done < $URLFILE
bash /home/pi/wlansysstart.sh # script um iptables zu aktualisieren
get-mac-addr.sh # wird ausgeführt wenn ein User sich über die Website des Pi's mit einem Code registriert
Das PHP script übergibt die Client IP und den eingegebenen Code und zeigt dem User die echo Ausgabe dieses Scripts.
check=0 # variable für erfolgreiche Code Prüfung
URLFILE=/home/pi/codes.txt # Datei mit den Freischaltcodes
# prüfen ob der Code in der Datei enthalten ist
for i in `cat $URLFILE`; do
if [ $3 = $i ]; then
echo "Code check ok"
loeschen=$3 # Code zwischenspeichern um diesen am ende zu löschen
check=1
fi
done
# Code länge überprüfen mit Fehlerausgabe
laenge=$(expr length "$3")
if [ $laenge != 8 ]; then
echo "falsche code länge"
exit
fi
# Fehlerausgabe bei falschem Code
if [ $check != 1 ]; then
echo "falcher code"
exit
fi
ipaddress="$1" # von PHP script übergebene IP-Adresse
interface="$2" # von PHP script übergebenes Interface, in diesem Fall wlan0
# ip Adresse validieren
function valid_ip(){
local ip=$1
local stat=1
if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
OIFS=$IFS
IFS='.'
ip=($ip)
IFS=$OIFS
[[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
&& ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
stat=$?
fi
return $stat
}
# wenn ip validiert, dann Mac ermitteln
if valid_ip $ipaddress; then
result=$(/usr/sbin/arping -i $interface $ipaddress -c 6 | grep '('$ipaddress')' | grep index=0 | awk '{ print $4 }')
#echo $result;
fi
typeset -i jahr=$(date +%g) # aktuelles Jahr im Format yy speichern
# date +%j gibt die den tag des Jahres 1-365 als 3 Ziffern aus(z.b.: 007, 056, 244). folgende Fallunterscheidung entfernt die Nullen am Anfang.
if [ $(echo $(date +%j) | cut -c1-2) = 00 ]; then
typeset -i datum=$(echo $(date +%j) | cut -c3)
elif [ $(echo $(date +%j) | cut -c1) = 0 ]; then
typeset -i datum=$(echo $(date +%j) | cut -c2-3)
else
typeset -i datum=$(echo $(date +%j))
fi
dauer=$(echo $3 | cut -c7-8) # die letzten 2 Ziffern des codes speichern
# ermittlung der Dauer der Freischaltung über die letzten 2 Ziffern
if [ $dauer = 01 ]; then
echo "Dauer: 1 Tag"
datum+=1
elif [ $dauer = 07 ]; then
echo "Dauer: 1 Woche"
datum+=7
elif [ $dauer = 30 ]; then
echo "Dauer: 1 Monat"
datum+=30
elif [ $dauer = 00 ]; then
echo "Dauer: 1 Jahr"
jahr+=1
elif [ $dauer = 99 ]; then
echo "endless"
jahr=99
fi
# Falls die Tagesausgabe den Wert 365 übersteigt, wird ein Jahreswechsel gemacht
if [ $datum -gt 365 ]; then
datum=$datum-365
jahr+=1
fi
# Ermittlung des Client Namens, nur für die Übersicht
name=$(nmap -sP $ipaddress | grep 'scan report' | awk '{ print $5 }')
# Fehler falls Client Name nicht ermittelt werden konnte
if [ -z $name ]; then
echo "Error name: Freischaltung fehlgeschlagen. Bitte erneut versuchen"
exit
fi
# Fehler falls mac nicht ermittelt werden konnte
if [ -z $result ]; then
echo "Error mac: Freischaltung fehlgeschlagen, Bitte erneut versuchen"
exit
fi
# Client Daten speichern
ausgabe=$ipaddress" "$result" "$jahr" "$datum" "$name
echo $ausgabe >> /home/pi/wlangeraete.txt
# löschen des Codes
sed -i '/'$loeschen'/d' $URLFILE
echo 'Freischaltung erfolgreich'
sleep 1s
bash /home/pi/wlansysstart.sh
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 431060
Url: https://administrator.de/contentid/431060
Ausgedruckt am: 23.11.2024 um 07:11 Uhr
3 Kommentare
Neuester Kommentar
Tolles Projekt und für eine kleine Installation wie einen HotSpot an einen Kiosk usw. reicht das doch allemal auf dem RasPi
An allem gibts nichts zu meckern. Evtl. nur das du das WLAN verschlüsselst, denn das ist eigentlich völlig sinnfrei.
Wenn du das Passwort so oder so öffentlich machst ist das einen vollkommen überflüssige Hürde für User. Da ist es besser wenn du das WLAN offen betreibst wie es in der Regel auch bei Hotspots üblich ist !
Für jemander der das nachvollziehen will solltest du ggf. noch einen Tip geben wie man den RasPi als WLAN Accesspoint betreibt und wie man die Vouchers erhält.
Netzwerk Management Server mit Raspberry Pi
An allem gibts nichts zu meckern. Evtl. nur das du das WLAN verschlüsselst, denn das ist eigentlich völlig sinnfrei.
Wenn du das Passwort so oder so öffentlich machst ist das einen vollkommen überflüssige Hürde für User. Da ist es besser wenn du das WLAN offen betreibst wie es in der Regel auch bei Hotspots üblich ist !
Für jemander der das nachvollziehen will solltest du ggf. noch einen Tip geben wie man den RasPi als WLAN Accesspoint betreibt und wie man die Vouchers erhält.
Netzwerk Management Server mit Raspberry Pi