Авторизация по Bluetooth: «если мой телефон рядом — заходи»
А что если не карту прикладывать, а просто заходить в админку, когда твой телефон лежит рядом с Raspberry Pi? Блютус же видит все устройства в эфире — почему бы не использовать это как «присутствие-ключ»?
Проверил — да, работает. Просто, бесплатно (если телефон уже есть), и без лишних модулей.
Как это работает
- Raspberry Pi сканирует Bluetooth-эфир каждые несколько секунд.
- Если в списке появляется твой MAC-адрес (например, телефона) — пишет
1в файлbt_auth.txt. - Если твоего устройства нет в эфире — пишет
0. - PHP (или любой другой веб-интерфейс) читает этот файл и решает: показывать форму или нет.
Плюсы и минусы
| Плюсы | Минусы |
|---|---|
| Не надо носить карту — телефон всегда с собой | Блютус нужно включить на телефоне |
| Работает на любом Raspberry Pi с BLE (3B+, 4, Zero W и т.д.) | Не самый быстрый отклик (сканирование раз в 5–10 сек) |
| Никаких дополнительных затрат | MAC-адрес можно подменить (не для high-security сценариев) |
Что нужно
- Raspberry Pi с встроенным Bluetooth (например, Pi 3B+, Pi 4 или Zero W)
- Включённый Bluetooth на устройстве-ключе (телефон, часы и т.п.)
- Утилита
bluetoothctl(есть по умолчанию в Raspberry Pi OS)
Python-скрипт для сканирования
Создаём bt_presence.py:
#!/usr/bin/env python3
import subprocess
import time
# Замени на MAC-адрес своего телефона (например, AA:BB:CC:DD:EE:FF)
MY_DEVICE_MAC = "AA:BB:CC:DD:EE:FF".lower()
AUTH_FILE = "/var/www/html/bt_auth.txt"
def is_device_near():
try:
result = subprocess.run(["bluetoothctl", "scan", "on"],
capture_output=True, text=True, timeout=8)
# На самом деле scan on не даёт результата сразу — лучше использовать discovery
except:
pass
# Используем более надёжный способ: discovery + list
try:
subprocess.run(["bluetoothctl", "discoverable", "off"], stdout=subprocess.DEVNULL)
subprocess.run(["bluetoothctl", "scan", "off"], stdout=subprocess.DEVNULL)
subprocess.run(["bluetoothctl", "scan", "on"], stdout=subprocess.DEVNULL)
time.sleep(6)
result = subprocess.run(["bluetoothctl", "devices"],
capture_output=True, text=True, timeout=5)
return MY_DEVICE_MAC in result.stdout.lower()
except Exception as e:
print("Ошибка сканирования:", e)
return False
# Сбрасываем статус при старте
with open(AUTH_FILE, "w") as f:
f.write("0")
print("Сканю Bluetooth на наличие устройства:", MY_DEVICE_MAC)
while True:
near = is_device_near()
status = "1" if near else "0"
with open(AUTH_FILE, "w") as f:
f.write(status)
print(f"Статус: {'рядом' if near else 'не рядом'}")
time.sleep(10)
⚠️ Чтобы узнать MAC-адрес телефона:
- Android: Настройки → О телефоне → Информация о статусе → Адрес Bluetooth
- iPhone: к сожалению, Apple рандомизирует MAC в эфире — такой способ не сработает. Только Android/Windows/Linux-устройства.
PHP-проверка (пример)
<?php
$allowed = file_get_contents('/var/www/html/bt_auth.txt') === "1";
if (!$allowed) {
die("Доступ только при наличии твоего телефона рядом!");
}
?>
<h2>Привет! Твой телефон рядом — добро пожаловать.</h2>
Как запустить в фоне
chmod +x bt_presence.py
nohup python3 bt_presence.py &
Или лучше — создать systemd-сервис, чтобы скрипт стартовал при загрузке.
Важно!
- Не все устройства «видны» в эфире — убедись, что на телефоне включён Bluetooth и он обнаруживаем (хотя бы временно для теста).
- На некоторых системах может потребоваться запуск от root или добавление пользователя в группу
bluetooth. - Для большей надёжности можно использовать
hcitool lescanили библиотекуbluepy, но это уже сложнее.
В итоге — у тебя получается «умный замок» без замка: подошёл к Raspberry Pi с телефоном → сайт открыл админку. Ушёл — закрылось. Почти как в фильмах!
Комментарии
Пока нет комментариев. Будьте первым!