Skip to content

Latest commit

 

History

History
197 lines (136 loc) · 11.4 KB

File metadata and controls

197 lines (136 loc) · 11.4 KB

English README | Technical Reference

RPi VPN Gateway

Raspberry Pi 4 настроен как VPN-шлюз с раздельной маршрутизацией: весь трафик, не относящийся к российским IP-диапазонам, выходит через туннель AmneziaWG; российские IP-диапазоны выходят напрямую через провайдера. Для всех устройств в LAN работа шлюза прозрачна.


Как это работает

RPi выступает шлюзом по умолчанию для всех устройств в локальной сети. Трафик делится на два пути:

  • Не-RU трафик выходит через VPN-туннель AmneziaWG (awg0)
  • Российские IP-диапазоны (загружаются ежедневно с russia.iplist.opencck.org) выходят напрямую через провайдера
  • Устройства в LAN не требуют индивидуальной настройки — разделение трафика полностью прозрачно
Интернет
  
Роутер (192.168.1.1)  подключение к провайдеру
   eth0
RPi4 (192.168.1.254)  VPN-шлюз
  
Устройства в LAN (шлюз по умолчанию = 192.168.1.254 через DHCP роутера)

Не-RU  awg0  AmneziaWG VPN (endpoint: <VPN_SERVER_IP>:<port>)
RU-подсети  eth0  провайдер напрямую (через 192.168.1.1)

Установка

1. SSH-псевдоним

Добавьте в ~/.ssh/config на вашем Mac:

Host pi4
    HostName 192.168.1.254
    User ar
    IdentityFile ~/.ssh/id_ed25519

Проверка: ssh pi4 "echo ok" — должна выполниться без запроса пароля.

2. Конфигурация

VPN-ключи (.env.secrets):

cp .env.secrets.example .env.secrets
# Заполните AWG_PRIVATE_KEY, AWG_PUBLIC_KEY, AWG_PRESHARED_KEY (44-символьный base64 каждый)

Шаблон конфигурации AmneziaWG (src/configs/amnezia.key.template.txt): содержит специфичные для сервера параметры обфускации (Jc, Jmin, Jmax, S1, S2, H1–H4) и адрес endpoint. Скопируйте блоки [Interface] и [Peer] из клиентской конфигурации вашего AmneziaWG-сервера, затем замените значения ключей на плейсхолдеры {{PrivateKey}}, {{PublicKey}}, {{PresharedKey}}deploy.sh подставит их во время деплоя.

Конфигурация сети (.env): зафиксирована в репозитории, безопасно редактировать. Обновите, если ваша сеть отличается от настроек по умолчанию:

SSH_HOST="pi4"              # SSH-псевдоним RPi (из ~/.ssh/config)
RPI_LAN_IP=192.168.1.254    # IP-адрес RPi в LAN
KEENETIC_GW=192.168.1.1     # Шлюз провайдера (ваш роутер)
VPN_SERVER_IP=<your-server-ip>  # IP-адрес AmneziaWG-сервера — задаётся в .env.secrets
CRON_UPDATE_HOUR=5          # Час (0–23) ежедневного обновления списка RU-адресов

Опционально — кастомные маршруты через провайдера (src/configs/isp-routes-custom.txt): IP-диапазоны, которые всегда выходят через провайдера, минуя VPN, — добавляются поверх автозагружаемого списка RU. Создайте из примера при необходимости:

cp src/configs/isp-routes-custom.txt.example src/configs/isp-routes-custom.txt

Опционально — кастомные маршруты через VPN (src/configs/vpn-routes-custom.txt): IP-диапазоны, которые принудительно направляются через VPN, даже если они есть в автозагружаемом списке RU. Наивысший приоритет — перекрывает все ISP-маршруты. Создайте из примера при необходимости:

cp src/configs/vpn-routes-custom.txt.example src/configs/vpn-routes-custom.txt

После правки любого из этих файлов используйте bash src/deploy-routes.sh вместо полного bash src/deploy.sh. Скрипт копирует только два файла кастомных маршрутов и запускает routing.sh --no-update — без установки AmneziaWG, валидации ключей и настройки systemd. Занимает секунды вместо минут.

Опционально — исключения из списка RU-адресов (src/configs/ru-list-exclude.txt): IP-диапазоны, которые нужно убрать из загружаемого списка RU на стороне сервера (используется, когда список RU ошибочно включает диапазон, который должен туннелироваться). Создайте из примера при необходимости:

cp src/configs/ru-list-exclude.txt.example src/configs/ru-list-exclude.txt

Все три файла добавлены в .gitignore. Полный воркфлоу: REFERENCE.md.

3. Настройка роутера (Keenetic)

Шлюз — установите RPi как шлюз по умолчанию для LAN:

  1. http://192.168.1.1 → Домашняя сеть → Сегменты → По умолчанию → Параметры IP
  2. Установите Адрес шлюза равным 192.168.1.254 → Сохранить
  3. Устройства в LAN применят настройку при следующем обновлении DHCP-аренды (или переподключите Wi-Fi)

DNS — нужен для отображения доменных имён в splitgate status:

  1. Домашняя сеть → Сегменты → По умолчанию → DNS-сервер → установите 192.168.1.254 → Сохранить

Откат: очистите поле «Адрес шлюза» в роутере (верните 192.168.1.1).

4. Запустите деплой

bash src/deploy.sh            # развернуть всё + активировать маршрутизацию
bash src/deploy.sh --no-run   # только развернуть файлы (используйте до поднятия туннеля)
bash src/deploy-routes.sh     # быстрая выгрузка только файлов кастомных маршрутов (после правки isp-routes-custom.txt или vpn-routes-custom.txt)

5. Поднимите туннель

ssh pi4 "sudo awg-quick up awg0"   # поднять VPN-туннель (ручной шаг — не идемпотентен)
ssh pi4 "sudo awg show"            # проверить рукопожатие с пиром

Команды

Запускаются на RPi через SSH. splitgate — диспетчер CLI, установленный в /usr/local/bin/splitgate.

Команда Что делает
splitgate status Последние соединения с маршрутизацией VPN/ISP и организацией
splitgate watch Трафик в реальном времени
splitgate rollback Полностью отменить VPN-шлюз
splitgate routing Пересобрать маршруты раздельной маршрутизации
splitgate update Обновить список RU-адресов сейчас
# Просмотр последних соединений
ssh pi4 "splitgate status"
ssh pi4 "splitgate status --via=vpn --last=100"
ssh pi4 "splitgate status --summary"                        # топ-20 организаций по соединениям

# Просмотр трафика в реальном времени
ssh pi4 "splitgate watch"
ssh pi4 "splitgate watch --src 192.168.1.x --tag VPN"

# Откат
ssh pi4 "splitgate rollback"

Полный справочник CLI, проверка маршрутизации, решение проблем →


Демон мониторинга маршрутов

splitgate-watch.service запускает watch-routes.py --daemon как постоянный systemd-сервис и пишет лог соединений в /etc/splitgate/logs/watch-YYYY-MM-DD.log (новый файл каждый день, хранение 14 дней). Разворачивается на этапе 28 скрипта deploy.sh.

# Управление сервисом
ssh pi4 "systemctl status splitgate-watch"
ssh pi4 "sudo systemctl restart splitgate-watch"

# Просмотр лога за сегодня
ssh pi4 "tail -f /etc/splitgate/logs/watch-$(date +%F).log"

# Найти ISP-маршруты без активного соединения (✗ = не найдено в conntrack)
ssh pi4 "grep '[ISP] ✗' /etc/splitgate/logs/watch-$(date +%F).log"

Каждая строка лога содержит тег маршрутизации, статус соединения, источник/назначение, протокол:порт и организацию:

2026-05-29T10:14:00 [ISP]  192.168.1.237  yandex.ru TCP:443 | TELETECH, RU
2026-05-29T10:14:05 [ISP]  192.168.1.237  github.com TCP:443 | FASTLY, US

= соединение найдено в conntrack (ESTABLISHED/TIME_WAIT); = не найдено (UDP-соединения всегда показывают ).

Воркфлоу настройки — если строки [ISP] ✗ указывают на RU-подсети, идущие через ISP, а должны через VPN, раскомментируйте нужный блок в src/configs/vpn-routes-custom.txt и перезапустите routing.sh.


Лог-файлы

Файл Путь на RPi Назначение
install.log /etc/splitgate/logs/install.log Вывод routing.sh и update-vpn-routes — источник загрузки, исключённые CIDR, количество маршрутов
watch-YYYY-MM-DD.log /etc/splitgate/logs/watch-2026-05-29.log Ежедневный лог соединений, записываемый splitgate-watch.service в режиме демона
watch-error.log /etc/splitgate/logs/watch-error.log Вывод stderr от watch-routes.py --daemon (ошибки запуска, исключения Python)
# Просмотр лога установки/маршрутизации
ssh pi4 "sudo tail -20 /etc/splitgate/logs/install.log"
ssh pi4 "sudo grep vpn-routes /etc/splitgate/logs/install.log | tail -10"

# Просмотр лога слежения за сегодня
ssh pi4 "sudo tail -f /etc/splitgate/logs/watch-$(date +%F).log"