Search
Write a publication
Pull to refresh

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

Level of difficultyHard
Reading time4 min
Views8.2K

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

Рабочая задача: развернуть 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 я восприму с благодарностью.

Tags:
Hubs:
0
Comments11

Articles