В рамках этой статьи хочется поделиться способом решения проблемы, которую я сам себе поставил, а именно: иметь возможность подключения к RepkaPi при её включении без заранее известного и доступного Wi-Fi.
Отдельно отмечу, что все описанные ниже действия проводились в только что установленной RepkaOS на Repka Pi 3 (2Gb ОЗУ; 1.4 ГГц). Если вы используете не RepkaOS или у вас Repka другой версии, то вам могут потребоваться какие-то дополнительные/иные действия.
Постановка проблемы #
Представим следующую ситуацию: вы вынесли свою репку из дома и включили её в каком-то новом месте. Например, вы переехали в новую квартиру и, разумеется, ещё не добавили Wi-Fi сеть, или вы отправились в какую-то поездку и у вас возникла необходимость взять репку с собой (возможно, на ней какой-нибудь сервер, например, Conan server). Как итог, ваша репка работает, но подключится по SSH вы не можете, а это значит, что вам нужно достать клавиатуру и монитор, чтобы это сделать. В лучшем случае вы будете иметь их под рукой, а в худшем вам ещё придётся везти их с собой.
В идеале же нам бы очень хотелось иметь возможность перенести устройство в любое место и иметь возможность подключится к нему по ssh. А имея возможность подключения по ssh, мы уже можем сделать всё, что нам заблагорассудится.
Лирическое отступление #
Ранее я находил способ решения этой задачи, описанный для Raspberry Pi. Этот способ предполагал множество телодвижений, которые в конечном итоге позволяли подключаться к устройству через, например, PuTTY через serial port, если не ошибаюсь. Результат, откровенно говоря, не поражал воображение.
Не так давно я достал запылившуюся репку, перезаписал RepkaOS и решил заново всё настроить. Снова искать статьи с описанным выше решением было примерно никакого желания, так что я решил обратиться к нейросети. Честно говоря, не питал больших надежд, но результатом был приятно удивлён.
Установка необходимых пакетов #
sudo apt-get update
sudo apt-get install network-manager dnsmasq
Прим.
Возможно так же необходим пакет hostapd.
Настройка #
Настройте точку доступа через NetworkManager #
Создайте профиль для точки доступа:
sudo nmcli con add type wifi ifname wlan0 con-name Hotspot autoconnect no \
ssid RepkaPi-AP \
802-11-wireless.mode ap \
802-11-wireless.band bg \
ipv4.method shared \
ipv4.addresses 192.168.4.1/24 \
wifi-sec.key-mgmt wpa-psk \
wifi-sec.psk "12345678"
Кратко пройдёмся по параметрам:
- con-name (Hotspot) — имя профиля сети, по которому мы будем запускать её далее.
- ssid (RepkaPi-AP) — имя сети, которая будет запущена при включении точки доступа.
- ipv4.addresses (192.168.4.1/24) — IP-адрес репки в создаваемой сети (а заодно и маска /24).
- wifi-sec.psk ("12345678") — пароль
Настройка dnsmasq #
Откройте конфигурационный файл для редактирования:
sudo nano /etc/dnsmasq.conf
В него добавьте:
listen-address=127.0.0.1
server=8.8.8.8
server=8.8.4.4
interface=wlan0
dhcp-range=192.168.4.2,192.168.4.20,255.255.255.0,24h
Кратко пройдёмся по параметрам:
- listen-address=127.0.0.1 — тут должен быть именно localhost (127.0.0.1). Если я правильно помню, то это нужно для корректной работы в связке с systemd-resolved, которую мы по умолчанию имеем в системе и (лично я) не хотим удалять.
- dhcp-range=192.168.4.2,192.168.4.20,255.255.255.0,24h — репка будет раздавать IP-адреса от 192.168.4.[2-20].
Настройка systemd-resolved #
Открываем конфигурационный файл:
sudo nano /etc/systemd/resolved.conf
Добавляем:
DNS=127.0.0.1
DNSStubListener=no
Перезапускаем демонов (службы) dnsmasq и systemd-resolved:
sudo systemctl restart systemd-resolved dnsmasq
Создание скрипта для проверки сети #
Создайте скрипт /usr/local/bin/wifi_checker.sh
:
sudo nano /usr/local/bin/wifi_checker.sh
Содержание скрипта
#!/bin/bash
AP_NAME="Hotspot"
CHECK_INTERVAL=30
MAX_ATTEMPTS=3
CONNECT_TIMEOUT=20 # Увеличено время ожидания подключения
# Функция проверки подключения с проверкой IP-адреса
is_connected() {
# Проверяем наличие IP-адреса и доступность интернета
if ip -4 addr show wlan0 | grep -q "inet" && ping -c1 -W2 8.8.8.8 >/dev/null; then
return 0
else
return 1
fi
}
# Функция подключения к сети
scan_and_connect() {
# Сканируем сети и выводим результат
nmcli device wifi rescan --refresh 2>/dev/null
# Получаем список сохраненных сетей (исключая точку доступа)
saved_networks=$(nmcli -t -f NAME con show | grep -v "^$AP_NAME$")
for network in $saved_networks; do
echo "Проверка доступности сети: $network"
# Ищем SSID среди доступных сетей
if nmcli -t -g SSID dev wifi list | grep -q "^$network$"; then
echo "Подключаемся к $network..."
nmcli con up "$network" >/dev/null 2>&1 &
sleep $CONNECT_TIMEOUT
if is_connected; then
echo "Успешно подключено к $network"
return 0
else
echo "Ошибка подключения к $network"
nmcli con down "$network" >/dev/null 2>&1
fi
fi
done
return 1
}
# Основной цикл
attempt=0
while true; do
if is_connected; then
echo "Активное подключение: $(nmcli -t -f DEVICE,CONNECTION dev status | grep wlan0 | cut -d: -f2)"
# Если подключение активно, сбрасываем счетчик и ждем
attempt=0
sleep $CHECK_INTERVAL
continue
fi
echo "Нет подключения. Поиск сетей (попытка $((attempt + 1))/$MAX_ATTEMPTS)..."
if scan_and_connect; then
attempt=0
sleep $CHECK_INTERVAL
continue
else
attempt=$((attempt + 1))
fi
if [ $attempt -ge $MAX_ATTEMPTS ]; then
echo "Запуск точки доступа $AP_NAME..."
nmcli con down "$(nmcli -t -f NAME con show --active | grep -v "^$AP_NAME$")" >/dev/null 2>&1
nmcli con up "$AP_NAME"
break # Выход из цикла после активации AP
fi
sleep $CHECK_INTERVAL
done
Сделайте скрипт исполняемым:
sudo chmod +x /usr/local/bin/wifi_checker.sh
Настройка службы для автоматического запуска #
Создайте службу systemd:
sudo nano /etc/systemd/system/wifi-checker.service
Добавьте:
[Unit]
Description=Wi-Fi Checker and AP Fallback via NetworkManager
After=NetworkManager.service
[Service]
ExecStart=/usr/local/bin/wifi_checker.sh
Restart=no
[Install]
WantedBy=multi-user.target
Запустите службу:
sudo systemctl daemon-reload
sudo systemctl enable wifi-checker
sudo systemctl start wifi-checker
Разрешите управление Wi-Fi через NetworkManager #
Убедитесь, что NetworkManager управляет интерфейсом wlan0
:
sudo nmcli dev set wlan0 managed yes
Перезагрузка и тестирование #
sudo reboot
Для отладки проверьте логи:
journalctl -u wifi-checker -f
Дополнительные команды #
-
Список сохраненных сетей:
nmcli con show
-
Добавить новую сеть:
nmcli dev wifi connect "SSID" password "пароль"
-
Ручной запуск AP:
nmcli con up Hotspot