Как сделать портал для бизнеса с помощью Raspberry Pi Pico W
Если вы ведете бизнес, то создание портала захвата может стать важным инструментом для вашей сети. Поэтому в этой статье я покажу вам, как создать портал захвата с помощью Raspberry Pi Pico W.
Портал захвата - это безопасный способ предоставления WiFi гостям, клиентам или заказчикам. Он требует, чтобы пользователи входили в систему или проходили аутентификацию, прежде чем они смогут пользоваться Интернетом.
Подумайте, как это работает в аэропорту или в сети кофеен.
Портал захвата позволяет вам контролировать и наблюдать за сетью. Он также дает возможность расширить ваш бренд. Вы можете украсить портал своим логотипом.
Что делает портал в плену?
При входе в систему Pico W, выполняющую роль точки доступа, веб-страница не отображается. При использовании портала захвата, как только ваш WiFi подключится к точке доступа, появится веб-страница.
Таким образом, вы можете пропустить этап подключения к сети, а затем перейти в браузер и вручную ввести IP-адрес.
Именно в этот момент я должен отдать должное Кевину МакАлиру за его видео, которое послужило основой для этого урока.
Создание портала "в плену" с помощью Pico W - это фантастическая возможность. Портал не только необходим для сети вашего предприятия. A Raspberry Pi Pico W стоит всего несколько евро, поэтому это очень экономичное решение.
Цели этого урока
В руководстве Кевина показано, как запустить портал захвата на устройстве Apple.
В этом руководстве мы расскажем вам, как запустить всплывающий портал на устройствах Android, Windows и Apple.
Мы будем использовать Phew от Pimoroni, которая представляет собой библиотеку для веб-сервера Pico W. Это немного похоже на то, чем Express является для NodeJS.
Я протестировал свой код на четырех устройствах:
- Apple iPhone 8 с версией ОС 15.4.1 ✔️
- Планшет Amazon Fire с ОС Android 9 ✔️
- Windows 10 PC ✔️
- Google Pixel 6 с Android 13 ✔️
- Samsung Note 9 с операционной системой Android 10 ❌
Код работал на всех устройствах, кроме Samsung Note 9, и я не тестировал его на Linux.
Примеры использования?
Это довольно сложный вопрос.
Изначально я хотел создать что-то, что могло бы кого-то рикроллить, но понял, что не могу вставить видео с YouTube, так как у Pico W нет подключения к Интернету.
Затем я захотел создать портативную цифровую визитную карточку, где люди могли бы подключиться к Pico W и увидеть несколько ссылок. Что-то вроде тех каталогов Instagram со ссылками в биографии. Опять же, никакого интернета...
Я полагаю, что одним из самых больших преимуществ Pico W является то, что он позволяет управлять компонентами по беспроводной связи.
В мегаучебник по компонентамЯ рассказывал о том, как можно избежать использования физических кнопок и ручек для управления светодиодами, зуммерами и сервоприводами, используя вместо них веб-интерфейс. Если вы внедрите их в свой портал захвата, вы сможете легче управлять своими устройствами, поскольку вам не придется входить в систему 192.168.4.1 каждый раз, когда вы захотите попасть на панель управления.
Конечно, я с удовольствием послушаю, что вы думаете о возможностях портала. Оставьте комментарий ниже!
Как вызвать всплывающее окно
При подключении к беспроводной сети устройства Windows, Android и Apple пингуют разные веб-сайты.
Каждый из этих пингов требует ответа. Правильный ответ разблокирует всплывающее окно. Вот как происходит беседа в зависимости от ОС:
Microsoft Windows 10
МС: "Псс... это...connecttest.txt там?"
Пико У: "Да, 200“.
МС: "Хорошо, отвезите меня в / перенаправление“
Пико У: "Да, 302перейдите по ссылке http://pico.wireless/ где мы будем служить вам index.html“.
Amazon Fire Android 9
AMZ: "Псс... где /generate_204 там?"
Pico W: "По умолчанию я собирался сказать. 204Но я знаю, что на самом деле вы хотите 302 перенаправить на http://pico.wireless/ (который отображает index.html, он же ваша страница захвата)".
Apple iPhone 8 с iOS 15
iPhone: "Я крут и все такое, так что я просто ищу файл. /hotspot-detect.html“
Пико У: "Да, иди в http://pico.wireless/“
iPhone: "Хм, кажется, это совсем не то, что я просил, но я тебе доверяю, поэтому сейчас пойду туда".
Код ответа 200: "ОК", 204: "Нет содержимого", 302: "Найдено".
Как видите, разные устройства запрашивают разные маршруты и разные веб-страницы. И если вы ответите правильно, они вызовут всплывающее окно.
Вот краткое описание того, что вам нужно для отправки и получения:
Windows 10
URL | Срабатывание реакции |
www.msftconnecttest.com/ncsi.txt | 200 OK |
www.msftconnecttest.com/connecttest.txt | 200 OK |
www.msftconnecttest.com/redirect | 302 перенаправление (на портал для пленных, например index.html) |
Android 9, 10
URL | Срабатывание реакции |
connectivitycheck.gstatic.com/generate_204 | 302 перенаправление (на страницу портала неволи) |
Другие версии Android могут запрашивать другие URL-адреса. Я полагаю, что в новых версиях Android будет /generate_204 в качестве запасного варианта.
Вот два ресурса для старых моделей Androids:
https://lemariva.com/blog/2017/11/white-hacking-wemos-captive-portal-using-micropython
iOS 15
URL | Срабатывание реакции |
captive.apple.com/hotspot-detect.html | 200 OK (ответ с веб-страницей) |
Мой Samsung Note 9 под управлением Android 10 оказался самым сложным для взлома. Казалось бы, нужно следовать типичным для Android шаблонам, но, увы, ничего не получалось!
Мне удалось получить приглашение "Требуется вход", но только после изменения DNS на публичный IP локальной сети (IP вне диапазона '10.0.0.0/8, 172.16.0.0/12 или 192.168.0.0/16'). См. этот комментарий на Stack Exchange.
Но выполнение вышеуказанных действий сломало портал неволи на всех других устройствах...
Библиотека Pimoroni Phew для портала неволи Pico W
Пиморони Библиотека значительно упрощает создание порталов, потому что они уже сделали всю работу.
Для начала вам нужно скачать библиотеку. Я использовал версию 0.0.3. которую можно скачать здесь.
Затем извлеките файлы и загрузите их в папку с именем фух на ваш Pico W. Лично я использовал Thonny IDE, и вы можете Узнайте, как загружать файлы, здесь.
Давайте закодируем всплывающую точку доступа!
Итак, позвольте мне начать с 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")
Для ясности, я адаптировал этот код у Кевина МакАлира и изменил его для наших целей. Если вы хотите посмотреть подробное объяснение Кевина о том, как все работает, посмотрите это видео на YouTube.
Но позвольте мне вкратце рассказать о различных разделах.
Здесь есть три раздела с комментариями "#android redirects", "#apple redir" и "# microsoft windows redirects". Эти разделы обрабатывают тесты, которые выдает каждая операционная система, и отвечают на них правильным ответом.
В конце ответов они будут перенаправлены на http://{DOMAIN}/, за исключением маршрута Apple (потому что Кевин написал его так, и если он не сломан...).
Перенаправление на DOMAIN, объявленный как "pico.wireless", даст нам менее неприглядный URL.
Таким образом, вместо "www.msftconnecttest.com" в адресной строке мы увидим "pico.wireless" в адресной строке. Разумеется, об этом следует помнить при создании портала для сотрудников вашего предприятия.
Pimoroni Phew уменьшает количество кода, который вам нужно написать
Самое замечательное в Phew то, что вы пишете значительно меньше кода, чем если бы вы писали его с нуля.
Например, если бы вы хотели запустить SoftAP на Pico W, вы бы написали примерно такой код:
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
С помощью Pimoroni's Phew ваше бремя уменьшится:
ap = access_point("Pico W Captive")
На мой взгляд, самое лучшее - это dns.run_catchall() функция, выполняющая кучу жизненно важного, но сложного кода:
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 также позволяет легко писать маршруты. Все, что вам нужно сделать, это написать что-то вроде этого:
@server.route("/[your_route_here]", methods=["GET"])
def your_function_here(request):
pass
@server.catchall()
def catchall(request):
pass
Как вы можете видеть выше, создать маршрут очень просто. Все, что вам нужно сделать, это использовать @server.routeи передайте маршрут, а также методы. Затем определите функцию ниже с помощью запрос параметр.
Наконец, есть @server.catchall() функция, которая обрабатывает все маршруты, которые вы не назначили.
Это очень просто!
Посетите репозиторий Phew на Github здесь.
index.html
Это действительно простое доказательство концепции. index.html который выдает <h1> с надписью "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>
Заключение
Вот и все. Это все, что вам нужно знать, чтобы создать портал захвата на Pico W для вашего бизнеса.
Если у вас возникли вопросы, не стесняйтесь, сообщите нам об этом в комментариях ниже!
Хорошая замена пиратскому ящику (правда, без функции чата и закачки).
Это именно то, что я искал!
В основном все работает, однако сайт не открывается сам по себе, а вместо этого появляется ошибка:
2023-03-31 12:02:35 [info / 160kB] > GET /generate_204 (302 Found) [236ms]
Исключение задачи не было получено
будущее: coro=
Traceback (последний последний вызов):
Файл "uasyncio/core.py", строка 1, in run_until_complete
Файл "phew/server.py", строка 242, in _handle_request
Файл "phew/server.py", строка 161, в _parse_headers
ValueError: для распаковки требуется более 1 значения
Интересно, может быть, это как-то связано с тем, что мой старый телефон все еще работает на Android 6...
Как отредактировать этот код, чтобы включить HTML-код внутри программы? Я попробовал, но у меня ничего не получилось.
Я считаю, что программа очень запутанная.
Здравствуйте! Я буду рад помочь! Не могли бы вы описать вашу проблему более подробно и сообщить, какое устройство вы используете для портала захвата?
Привет! Я пытаюсь запустить это на Pico W. Точка доступа запускается, DNS запускается, а веб-сервер либо не запускается, либо запускается очень долго (несколько минут). Есть ли у вас какие-нибудь идеи/подсказки/предложения, почему? Спасибо!
Помогите, пожалуйста, понять, какая строка кода принудительно/автоматически открывает портал захвата в браузере клиента после успешного подключения к точке доступа? Кажется, он ничего не открывает автоматически. Я подключаюсь с ноутбука.
Спасибо за хорошее описание.
Я хотел бы добавить второй или даже третий SSID к той же точке доступа. Есть ли способ сделать это с помощью Phew?
Есть какие-нибудь мысли?
Нет, вам придется использовать raspberry pi pico для каждого ssid.