VPN-клиент для Windows своими руками: L2TP, PPTP, маршруты и Telegram-уведомления

от автора

История из практики

Рабочая задача: развернуть VPN на MikroTik с поддержкой L2TP и PPTP, авторизация — через Radius.
В роли серверов — стандартные для нас RouterOS CCR1016-12G. Параллельно возникло требование: подобрать клиент под Windows, чтобы можно было просто передать пользователям исполняемый файл, и они могли подключиться — без инструкций, .bat-файлов и шаманства.

Ключевое условие — не палить IPSEC_KEY.

Звучит несложно. Но, как это часто бывает, при попытке найти готовое решение стало ясно: либо его нет, либо оно недостаточно гибкое.

Ну и поехали. Ситуация была, скажем так, срочной. Почему — может, расскажу позже в Telegram-канале.

Результат: написал собственный VPN-клиент.
Ну как «написал» — взял PowerShell-скрипты, обернул в GUI на Python и получил рабочее приложение.

Почему не C#?
Потому что я умею в сети, а не в Cи-шарпы.
Python — мой максимум, и этого хватило, чтобы всё заработало.

Если вы думаете: «Очередной велосипед», — возможно, этот метериал не для вас.
Но если остались — покажу, как (не без помощи AI) я сделал удобный VPN-клиент, поделюсь исходниками и покажу, как собрать .exe под себя — с иконкой, версией и без лишнего гемора.

Приложение работает на Windows 10+ и выполняет следующее:
создаёт L2TP или PPTP-подключение средствами Windows;
добавляет маршруты (192.168.0.0/16, 10.0.0.0/8);
включает Split Tunneling — интернет остаётся через локального провайдера.

Ключевое: весь трафик не уходит в туннель а только трафик до серых сетей.
Плюс — Telegram-уведомления о подключениях: IP, гео, ОС, AS.
Не столько ради мониторинга, сколько для дебага и отладки.

Полный код и инструкции доступны:


Загрузка конфигурации

if getattr(sys, 'frozen', False):     config_path = os.path.join(sys._MEIPASS, 'config.json') else:     config_path = 'config.json'  with open(config_path, 'r') as f:     config = json.load(f) 

Для сборки приложения через pyinstaller, путь к файлам будет отличаться. Это условие — чтобы искать config.json в нужном месте в обоих случаях.

По простому можно запустить код через PyCharm и протестировать что все работает перед сборкой приложения (PyCharm запускать тоже от администратора).

Переменные и константы

TELEGRAM_TOKEN = config['TELEGRAM_TOKEN'] ... SERVERS = {     "111.111.111.111": {"name": "SERVER1", "gateway": "10.22.22.1"},     ... }

Все данные — в конфиге. Здесь мы храним Telegram-данные, IP-серверов и их шлюзы.

Проверка прав администратора

def is_admin():     return ctypes.windll.shell32.IsUserAnAdmin() != 0

VPN-команды требуют прав администратора. Если их нет — приложение сразу завершится.

Интерфейс на ttkbootstrap

root = ttk.Window(themename="darkly") app = VPNManagerApp(root) self.login_entry = ttk.Entry(root, bootstyle="info")

Используем ttkbootstrap — он делает обычный tkinter более симпатичным. Тема «darkly» даёт тёмный вид.
Добавляем поля ввода логина/пароля, выбор сервера, кнопки подключения и отключения.

Работа с VPN

subprocess.call("rasdial /disconnect", shell=True) command = f"rasdial \"{interface_name}\" {login} {password}"

Используем rasdial и Add-VpnConnection через PowerShell для создания, подключения и удаления VPN-соединений.
После подключения добавляются маршруты через route add.

Telegram-уведомления

await bot.send_message(chat_id=TELEGRAM_CHAT_ID, text=message, parse_mode="Markdown")

После подключения отправляется информация в Telegram: IP, страна, ОС, логин.

Логирование и безопасность

if hide_sensitive:     message = message.replace(IPSEC_KEY, "[HIDDEN]")

Чтобы лог не слил пароль или PSK — замещаем конфиденциальные данные.

Что в итоге

Это приложение:

  • создаёт VPN соединение (L2TP/PPTP)

  • подключает его через rasdial

  • добавляет маршруты

  • логирует каждый шаг

  • отправляет информацию о подключении в Telegram

  • показывает красивый GUI на Python


🚀 Сборка VPN-клиента в .exe: от иконки до метаданных

После того как мы написали рабочий VPN GUI-клиент, пора собрать его в .exe, чтобы можно было запускать на любом Windows-компьютере без Python и консоли.

Разберем по шагам, как именно я это делал.

version.txt — метаинформация

StringStruct('FileDescription', 'VPN-клиент для Windows с GUI и Telegram-уведомлениями') ... StringStruct('CompanyName', 'netscripor') 

Файл version.txt задаёт, что будет отображаться в свойствах .exe:

  • имя продукта;

  • автор;

  • версия;

  • описание;

  • иконка и прочее. Полный пример — в репозитории.

Команда сборки с PyInstaller

pyinstaller --onefile --noconsole --uac-admin --icon=vpn.ico --version-file=version.txt --add-data "pp.png;." --add-data "vpn.ico;." --add-data "config.json:." "main.py"

Разберем, что делает каждая часть:

Аргумент

Назначение

—onefile

Всё в одном .exe без папки dist

—noconsole

Не открывать черное окно консоли при запуске

—uac-admin

Требовать права администратора при запуске

—icon=vpn.ico

Иконка приложения

—version-file=version.txt

Метаданные для свойства файла

—add-data «pp.png;.»

Картинка логотипа в GUI

—add-data «vpn.ico;.»

Иконка в окне программы

—add-data «config.json;.»

Конфиг-файл (внимание: подставляется тестовая версия!)

main.py

Главный исполняемый файл

После выполнения команды в каталоге dist/ появится main.exe, готовый к запуску. Он будет:

  • выглядеть как полноценное Windows-приложение (с иконкой и описанием),

  • требовать админ-доступ при запуске,

  • не показывать консоль,

  • работать независимо от наличия Python на ПК.

📌 Заключение

Да, это не Enterprise-решение.
Но оно решает конкретную задачу: простой, автономный, настраиваемый VPN-клиент под Windows с поддержкой Split Tunneling и Telegram-логированием. И главное — его можно дорабатывать под себя.

Если статья была полезной — звёздочку на GitHub и подписку в Telegram я восприму с благодарностью.


ссылка на оригинал статьи https://habr.com/ru/articles/928242/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *