Wie man ein Captive Portal für sein Unternehmen mit einem Raspberry Pi Pico W erstellt

Raspberry Pi Pico W Captive Portal einrichten

Wenn Sie ein Unternehmen betreiben, kann die Einrichtung eines unverschlüsselten Portals ein wichtiges Werkzeug für Ihr Netzwerk sein. In diesem Artikel zeige ich Ihnen, wie Sie ein firmeneigenes Portal mit einem Raspberry Pi Pico W einrichten können.

Ein Captive Portal bietet eine sichere Möglichkeit, Gästen, Kunden oder Klienten WiFi anzubieten. Es erfordert, dass sich die Benutzer anmelden oder authentifizieren, bevor sie das Internet nutzen können.

Denken Sie daran, wie es auf einem Flughafen oder bei einer Coffeeshop-Kette funktioniert.

Ein firmeneigenes Portal ermöglicht es Ihnen, Ihr Netz zu kontrollieren und zu überwachen. Es bietet auch die Möglichkeit, Ihre Marke zu erweitern. Sie können das firmeneigene Portal mit Ihrem Logo individuell gestalten.

Was macht ein unverschlüsseltes Portal?

Wenn Sie sich bei einem Pico W anmelden, der als Zugangspunkt fungiert, wird Ihnen keine Webseite angezeigt. Wenn ein Captive Portal implementiert ist, wird eine Webseite angezeigt, sobald Ihr WiFi eine Verbindung zu Ihrem Hotspot herstellt.

Daher können Sie den Schritt überspringen, eine Verbindung zum Netzwerk herzustellen und dann in Ihrem Browser eine IP-Adresse manuell einzugeben.

An dieser Stelle muss ich ein Lob aussprechen Kevin McAleer für sein Video, das als Grundlage für diesen Lehrgang dient.

Die Einrichtung eines firmeneigenen Portals mit einem Pico W ist eine fantastische Gelegenheit. Ein firmeneigenes Portal ist nicht nur für das Netzwerk Ihres Unternehmens unerlässlich. A Raspberry Pi Pico W kostet höchstens ein paar Euro, ist also eine äußerst kostengünstige Lösung.

Ziele für dieses Lernprogramm

Kevins Anleitung zeigt Ihnen nur, wie Sie ein unverschlüsseltes Portal auf einem Apple-Gerät auslösen können.

In diesem Tutorial erfahren Sie, wie Sie das Popup-Portal auf Android-, Windows- und Apple-Geräten aktivieren können.

Wir werden Phew von Pimoroni verwenden, eine Bibliothek für einen Pico W Webserver. Es ist ein bisschen wie das, was Express für NodeJS ist.

Ich habe meinen Code auf vier Geräten getestet:

  • Apple iPhone 8 mit OS Version 15.4.1 ✔️
  • Amazon Fire Tablet mit Android 9 ✔️
  • Windows 10 PC ✔️
  • Google Pixel 6 mit Android 13 ✔️
  • Samsung Note 9 mit Android 10 ❌

Der Code funktionierte auf allen außer auf meinem Samsung Note 9, und ich habe ihn nicht auf Linux getestet.

Anwendungsfälle?

Das ist ein bisschen schwierig.

Ursprünglich wollte ich etwas erstellen, das jemanden zum Lachen bringt, aber mir wurde klar, dass ich kein YouTube-Video einbetten kann, da der Pico W keine Internetverbindung hat.

Dann wollte ich eine tragbare digitale Visitenkarte erstellen, bei der die Leute eine Verbindung mit dem Pico W herstellen und ein paar Links sehen können. So ähnlich wie diese Instagram-Link-in-Bio-Verzeichnisse. Wieder kein Internet...

Einer der größten Vorteile des Pico W besteht wohl darin, dass man die Komponenten drahtlos steuern kann.

Unter unser Komponenten-Mega-Tutorialhabe ich darüber gesprochen, wie Sie die Verwendung von physischen Tasten und Knöpfen zur Steuerung von LEDs, Summern und Servos vermeiden können, indem Sie stattdessen eine Webschnittstelle verwenden. Wenn Sie diese in Ihr Captive Portal implementieren, können Sie Ihre Geräte einfacher steuern, da Sie sich nicht jedes Mal bei 192.168.4.1 anmelden müssen, wenn Sie ein Bedienfeld aufrufen möchten.

Natürlich würde ich gerne hören, was Ihrer Meinung nach mit einem unverschlüsselten Portal möglich ist. Hinterlassen Sie unten einen Kommentar!

So lösen Sie das Pop-up aus

Wenn Sie eine Verbindung zu einem drahtlosen Netzwerk herstellen, pingen Windows-, Android- und Apple-Geräte unterschiedliche Websites an.

Jeder dieser Pings erfordert eine Antwort. Die richtige Antwort schaltet das Pop-up frei. So läuft die Konversation je nach Betriebssystem ab:

Microsoft Windows 10

MS: "Psst... ist /connecttest.txt dort?"

Pico W: "Ja, 200“.

MS: "OK, bringen Sie mich zu /umleiten

Pico W: "Ähm, ja, 302, gehen Sie zu http://pico.wireless/ wo wir Sie bedienen werden index.html“.

Amazon Fire Android 9

AMZ: "Psst... wo ist /generieren_204 dort?"

Pico W: "Standardmäßig wollte ich sagen 204aber ich weiß, was Sie wirklich wollen, ist 302 weiterleiten zu http://pico.wireless/ (was index.html, auch bekannt als Ihre unverschlüsselte Seite, wiedergibt)"

Apple iPhone 8 mit iOS 15

iPhone: "Ich bin cool und so, ich suche nur die Datei /hotspot-detect.html

Pico W: "Ja, geh zu http://pico.wireless/

iPhone: "Hmm, das scheint etwas ganz anderes zu sein als das, wonach ich gefragt habe, aber ich vertraue dir, also werde ich jetzt dorthin gehen."

Antwortcode 200: "OK", 204: "Kein Inhalt", 302: "Gefunden".

Wie Sie sehen können, fragen verschiedene Geräte nach verschiedenen Routen und verschiedenen Webseiten. Und wenn Sie richtig antworten, lösen sie das Pop-up aus.

Hier finden Sie eine Zusammenfassung dessen, was Sie zum Senden und Empfangen benötigen:

Windows 10

URLReaktion auslösen
www.msftconnecttest.com/ncsi.txt200 OK
www.msftconnecttest.com/connecttest.txt200 OK
www.msftconnecttest.com/redirect302-Weiterleitung (zum unverschlüsselten Portal, z. B. index.html)

Android 9, 10

URLReaktion auslösen
connectivitycheck.gstatic.com/generate_204302-Umleitung (zur Seite des unverschlüsselten Portals)

Andere Android-Versionen fragen möglicherweise andere URLs ab. Ich glaube, die neueren Android-Versionen haben /generieren_204 als Ausweichmöglichkeit.

Hier sind zwei Ressourcen für ältere Androiden:

https://lemariva.com/blog/2017/11/white-hacking-wemos-captive-portal-using-micropython

https://enterprisenetworkingatlarge.wordpress.com/2018/04/21/captive-portal-detection-on-android-and-others-client-vendors-vs-ap-vendors/

iOS 15

URLReaktion auslösen
captive.apple.com/hotspot-detect.html200 OK (Antwort mit einer Webseite)

Mein Samsung Note 9 mit Android 10 war am schwersten zu knacken. Angeblich würde man den typischen Android-Mustern folgen, aber leider hat nichts funktioniert!

Ich habe es geschafft, die Aufforderung "Anmeldung erforderlich" zu erhalten, aber erst nachdem ich den DNS auf eine öffentliche LAN-IP geändert habe (eine IP außerhalb des Bereichs "10.0.0.0/8, 172.16.0.0/12 oder 192.168.0.0/16"). Siehe diesen Stack Exchange-Kommentar.

Aber wenn ich das oben beschriebene tue, wird das unverlierbare Portal eines jeden anderen Geräts zerstört...

Pimoroni Phew Bibliothek für Pico W Captive Portal

Pimoronis Puh Bibliothek ist es viel einfacher, ein unverschlüsseltes Portal zu erstellen, da sie die ganze Arbeit bereits erledigt haben.

Zuerst müssen Sie die Bibliothek herunterladen. Ich habe die Version 0.0.3 verwendet die hier heruntergeladen werden kann.

Entpacken Sie dann die Dateien und laden Sie den Ordner mit dem Namen puh auf Ihrem Pico W. Ich persönlich habe die Thonny IDE verwendet und kann Hier erfahren Sie, wie Sie Dateien hochladen können.

Am Ende des Tutorials sollten Sie ein Verzeichnis haben, das wie folgt aussieht.

Codieren wir das Hotspot-Pop-up!

Lassen Sie mich also beginnen mit main.py:

from phew import logging, server, access_point, dns
from phew.template import render_template
from phew.server import redirect

DOMAIN = "pico.wireless"  # This is the address that is shown on the Captive Portal


@server.route("/", methods=['GET'])
def index(request):
    """ Render the Index page"""
    if request.method == 'GET':
        logging.debug("Get request")
        return render_template("index.html")

# microsoft windows redirects
@server.route("/ncsi.txt", methods=["GET"])
def hotspot(request):
    print(request)
    print("ncsi.txt")
    return "", 200


@server.route("/connecttest.txt", methods=["GET"])
def hotspot(request):
    print(request)
    print("connecttest.txt")
    return "", 200


@server.route("/redirect", methods=["GET"])
def hotspot(request):
    print(request)
    print("****************ms redir*********************")
    return redirect(f"http://{DOMAIN}/", 302)

# android redirects
@server.route("/generate_204", methods=["GET"])
def hotspot(request):
    print(request)
    print("******generate_204********")
    return redirect(f"http://{DOMAIN}/", 302)

# apple redir
@server.route("/hotspot-detect.html", methods=["GET"])
def hotspot(request):
    print(request)
    """ Redirect to the Index Page """
    return render_template("index.html")


@server.catchall()
def catch_all(request):
    print("***************CATCHALL***********************\n" + str(request))
    return redirect("http://" + DOMAIN + "/")


# Set to Accesspoint mode
# Change this to whatever Wifi SSID you wish
ap = access_point("Pico W Captive")
ip = ap.ifconfig()[0]
# Grab the IP address and store it
logging.info(f"starting DNS server on {ip}")
# # Catch all requests and reroute them
dns.run_catchall(ip)
server.run()                            # Run the server
logging.info("Webserver Started")

Um das klarzustellen: Ich habe diesen Code von Kevin McAleer übernommen und für unsere Zwecke abgeändert. Wenn Sie sich Kevins ausführliche Erklärung ansehen möchten, wie die Dinge funktionieren, Sehen Sie sich dieses YouTube-Video an.

Aber lassen Sie mich kurz auf die einzelnen Abschnitte eingehen.

Es gibt drei Abschnitte mit Kommentaren "#android redirects", "#apple redir" und "# microsoft windows redirects". Diese Abschnitte behandeln die Tests, die jedes Betriebssystem ausführt, und antworten mit der richtigen Antwort.

Am Ende der Antworten werden sie an http://{DOMAIN}/ weitergeleitet, mit Ausnahme der Apple-Route (weil Kevin sie so geschrieben hat, und wenn sie nicht kaputt ist...).

Eine Umleitung zu DOMAIN, deklariert als "pico.wireless", würde uns eine weniger unansehnliche URL geben.

Anstatt "www.msftconnecttest.com" in der Adressleiste zu sehen, wird also "pico.wireless" in der Adressleiste angezeigt. Dies ist natürlich etwas, das Sie für das firmeneigene Portal beachten sollten.

Pimoroni Phew reduziert den Code, den Sie schreiben müssen

Das Schöne an Phew ist, dass Sie deutlich weniger Code schreiben, als wenn Sie ihn von Grund auf neu schreiben würden.

Wenn Sie zum Beispiel SoftAP auf dem Pico W starten möchten, würden Sie einen Code schreiben, der in etwa so aussieht:

import network
# start up network in access point mode
wlan = network.WLAN(network.AP_IF)
wlan.config(essid=ssid)
if password:
    wlan.config(password=password)
else:
    wlan.config(security=0)  # disable password
wlan.active(True)
return wlan

Mit Pimoroni's Phew reduziert sich Ihre Belastung auf ein Minimum:

ap = access_point("Pico W Captive")

Meiner Meinung nach ist der beste Teil die dns.run_catchall() Funktion, die eine Menge wichtigen, aber komplizierten Code ausführt:

import uasyncio, usocket
from . import logging

async def _handler(socket, ip_address):
  while True:
    try:
      yield uasyncio.core._io_queue.queue_read(socket)
      request, client = socket.recvfrom(256)
      response = request[:2] # request id
      response += b"\x81\x80" # response flags
      response += request[4:6] + request[4:6] # qd/an count
      response += b"\x00\x00\x00\x00" # ns/ar count
      response += request[12:] # origional request body
      response += b"\xC0\x0C" # pointer to domain name at byte 12
      response += b"\x00\x01\x00\x01" # type and class (A record / IN class)
      response += b"\x00\x00\x00\x3C" # time to live 60 seconds
      response += b"\x00\x04" # response length (4 bytes = 1 ipv4 address)
      response += bytes(map(int, ip_address.split("."))) # ip address parts
      socket.sendto(response, client)
    except Exception as e:
      logging.error(e)

def run_catchall(ip_address, port=53):
  logging.info("> starting catch all dns server on port {}".format(port))

  _socket = usocket.socket(usocket.AF_INET, usocket.SOCK_DGRAM)
  _socket.setblocking(False)
  _socket.setsockopt(usocket.SOL_SOCKET, usocket.SO_REUSEADDR, 1)
  _socket.bind(usocket.getaddrinfo(ip_address, port, 0, usocket.SOCK_DGRAM)[0][-1])

  loop = uasyncio.get_event_loop()
  loop.create_task(_handler(_socket, ip_address))

Phew macht es auch einfach, Routen zu schreiben. Alles, was Sie tun müssen, ist, etwas wie dieses zu schreiben:

@server.route("/[your_route_here]", methods=["GET"])
def your_function_here(request):
  pass

@server.catchall()
def catchall(request):
  pass

Wie Sie oben sehen können, ist das Erstellen einer Route ganz einfach. Alles, was Sie tun müssen, ist die Verwendung von @server.routeund geben Sie eine Route sowie die Methoden an. Dann definieren Sie unten eine Funktion mit dem Anfrage Parameter.

Schließlich gibt es noch die @server.catchall() Funktion, die alle nicht zugewiesenen Routen bearbeitet.

Puh, das macht es super einfach!

Besuchen Sie das Github Repo von Phew hier.

index.html

Es ist ein ganz einfaches Proof-of-Concept index.html die einen <h1> mit der Aufschrift "Pico W Captive Portal".

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Pico W Captive Portal</title>
  </head>
  <body>
    <h1>Pico W Captive Portal</h1>
  </body>
</html>

Schlussfolgerung

Da haben Sie es also. Das ist alles, was Sie wissen müssen, um ein firmeneigenes Portal auf einem Pico W für Ihr Unternehmen einzurichten.

Wenn Sie Fragen haben, zögern Sie nicht, uns diese in den Kommentaren unten mitzuteilen!

8 Kommentare

  1. Veröffentlich von cinos am Januar 8, 2023 um 4:11 pm

    Ein guter Ersatz für eine Piratenbox (allerdings ohne Chatfunktion und Upload).

  2. Veröffentlich von OkinKun am März 31, 2023 um 5:07 pm

    Das ist genau das, wonach ich gesucht habe!
    Die meisten Dinge funktionieren, aber die Website öffnet sich nicht von selbst, sondern es wird ein Fehler angezeigt:

    2023-03-31 12:02:35 [info / 160kB] > GET /generate_204 (302 Found) [236ms]
    Aufgabenausnahme wurde nicht abgerufen
    Zukunft: coro=
    Traceback (letzter Aufruf):
    Datei "uasyncio/core.py", Zeile 1, in run_until_complete
    Datei "phew/server.py", Zeile 242, in _handle_request
    Datei "phew/server.py", Zeile 161, in _parse_headers
    ValueError: zum Entpacken werden mehr als 1 Werte benötigt

    Ich frage mich, ob es vielleicht etwas damit zu tun hat, dass mein altes Telefon noch Android 6. ist.

  3. Veröffentlich von Dingleberry am Juni 21, 2023 um 10:57 pm

    Wie kann man diesen Code bearbeiten, um den HTML-Code in das Programm einzubinden? Ich habe es ausprobiert, aber es hat nicht funktioniert.

    Ich finde den Programmablauf sehr verwirrend.

    • Veröffentlich von Adam Bobeck am Juni 26, 2023 um 2:51 pm

      Hallo! Ich helfe gerne! Könnten Sie Ihr Problem genauer beschreiben und mir sagen, welches Gerät Sie für das Captive Portal verwenden?

  4. Veröffentlich von NewbiePicoWHacker am Oktober 1, 2023 um 3:36 pm

    Guten Tag! Ich versuche, dies auf einem Pico W. laufen zu lassen. die AP startet, die DNS startet, der Webserver entweder nie startet oder nehmen eine looooooong Zeit (mehrere Minuten) zu starten. Haben Sie irgendwelche Ideen/Hinweise/Vorschläge, warum? Vielen Dank!

  5. Veröffentlich von Prithwiraj Bose am November 5, 2023 um 3:43 pm

    Können Sie mir bitte helfen, zu verstehen, welche Codezeile das unverschlüsselte Portal im Browser des Kunden erzwingt/automatisch öffnet, nachdem die Verbindung zum Hotspot erfolgreich war? Es scheint nicht automatisch etwas zu öffnen. Ich stelle die Verbindung von meinem Laptop aus her.

  6. Veröffentlich von Peter am November 24, 2023 um 8:13 pm

    Danke für die gute Beschreibung.

    Ich würde gerne eine zweite oder sogar dritte SSID zum selben AP hinzufügen. Gibt es eine Möglichkeit, das mit Phew zu tun?

    Haben Sie eine Idee?

    • Veröffentlich von Toby am Mai 28, 2024 um 5:13 pm

      Nein, Sie müssten für jede ssid einen Raspberry Pi Pico verwenden.

Hinterlassen Sie einen Kommentar