VPNScripter Скриптер для VPN-соединений под Windows

Быстро создавайте VPN-соединения в Windows в соответствии с файлом конфигурации XML

Введение

Это общий сценарий PowerShell, который автоматически создает набор VPN-соединений на основе файла конфигурации XML. Очень полезно, если вы хотите быстро настроить VPN непосредственно в Windows, без использования специального VPN-программного обеспечения, разработанного вашим поставщиком VPN.

История

VPN-соединения всегда были способом подключения к частной корпоративной сети из Интернета. В настоящее время они продаются коммерческими организациями и используются в основном в целях конфиденциальности, маршрутизации всего интернет-трафика клиента через распределенные по всему миру ретрансляционные серверы. Имеется несколько различных протоколов для VPN-соединений, и Windows в основном поддерживает все из них:

  • PPTP: Один из первых протоколов VPN, основанный на инкапсуляции (через протокол GRE) и шифровании (RC4) протокола PPP [1]. PPTP был разработан Microsoft и сейчас практически не используется из-за слабого и небезопасного алгоритма шифрования. Обычно аутентификация клиента производится с помощью логина и пароля, хотя также можно использовать клиентские сертификаты. Сетевым точкам зрения PPTP использует TCP-порт 1723 и требует перенаправления IP-протокола GRE маршрутизаторами.
  • L2TP/IPSEC: L2TP – это протокол туннелирования, который, подобно PPTP, используется для инкапсуляции протокола PPP. Поскольку L2TP небезопасный (не имеет никакого вида шифрования), чтобы обеспечить безопасность, его часто используют с другим протоколом, IPSEC [2]. Для аутентификации клиента L2TP требуется логин и пароль, а также обычно клиент и сервер используют общий PSK для установки IPSEC-туннеля, хотя клиент также может аутентифицироваться на IPSEC-сервере с помощью сертификатов. Сетевым точкам зрения L2TP использует порт UDP 1701, а IPSEC использует UDP-порты 4500 и 500 (если IP-протокол ESP не находится за NAT, его также нужно перенаправить маршрутизаторами). Это “самый массивный” протокол.
  • SSTP: Разработанный Microsoft, как PPTP и L2TP, он основан на инкапсуляции протокола PPP, используя вместо этого защищенный канал SSL/TLS для обеспечения безопасности всего трафика (тот же протоколы, используемые при использовании https на безопасных сайтах Интернета). Как и PPTP, обычно аутентификация клиента производится с помощью логина и пароля, хотя также можно использовать клиентские сертификаты. Поскольку он использует только стандартный HTTPS-порт (TCP 443), он наиболее подходящий протокол для обхода почти любых ограничений брандмауэра и также может без проблем использоваться с прокси-серверами.
  • IKEv2: Это незначительное изменение IPSEC, в котором аутентификация клиента осуществляется не только с помощью PSK или сертификата, но и с помощью стандартных учетных данных пользователя. Кроме того, IKEv2 гораздо более устойчив к изменению сетевой коннективности, что делает его хорошим выбором для мобильных пользователей, перемещающихся между точками доступа. С сетевой точки зрения IKEv2 использует UDP-порты 500 и 4500 (если IP-протокол ESP не находится за NAT, его также нужно перенаправить маршрутизаторами).

У Windows также имеется автоматический протокол, который, по сути, пытается установить VPN-соединение, пробуя все протоколы IKEv2, SSTP, L2TP/IPSEC, PPTP по порядку. Подробнее см. [3].

Использование кода

Вся конфигурация сценария происходит в XML-файле с именем vpnconfig.xml (см. ниже). В этом файле определяются наборы поставщиков VPN (Provider) и для каждого поставщика указываются наборы серверов (Server), для каждого из которых будет создано VPN-соединение в Windows. Рассмотрим узлы:

  • Provider: Этот узел соответствует поставщику VPN. Атрибуты:
    • name: Используется для генерации имени VPN-соединения в Windows
    • basedomain: Используется для получения имени хоста VPN-сервера (обычно поставщик VPN предлагает набор серверов, которые имеют общее доменное имя). Оно может быть изменено в узле сервера.
    • l2tppsk: Это предварительно назначенный ключ для соединения L2TP/IPSEC (обычно он одинаков для всех серверов поставщика).
    • user: Это имя пользователя для доступа к VPN (обычно оно одинаково для всех серверов поставщика).
    • password: Это пароль, связанный с именем пользователя (обычно он одинаков для всех серверов поставщика).
    • proto: Указывает протокол VPN, используемый для всех серверов, если поле пустое, это означает автоматический выбор.
  • Server: Этот узел соответствует серверу поставщика VPN. Атрибуты:
    • server: Указывает имя хоста сервера. Если этот атрибут не содержит символа “.”, имя хоста получается путем объединения этого поля с базовым доменным именем поставщика, в противном случае имя хоста равно этому полю.
    • proto: Указывает протокол VPN для использования. Он также переопределяет любой протокол, определенный в узле поставщика.
    • user: Это имя пользователя для доступа к VPN. Оно также переопределяет любого пользователя, определенного в узле поставщика.
    • password: Это пароль, связанный с username. Он также переопределяет любой пароль, определенный в узле поставщика.

<!-- Конфигурационный файл VpnScripter © 2016 Federico Di Marco



Provider определяет поставщиков VPN, которые у вас есть.

Каждый поставщик VPN обычно имеет набор серверов, к которым можно подключиться,

и скрипт создает VPN-подключение

для каждого сервера, указанного для каждого указанного провайдера.

Созданное подключение будет иметь:

- Имя: атрибут Server (до первой "."), + Provider (Provider name),

если прото авто или пустое,

Server + Proto + Provider name, если оно не пусто.

- Протокол: указанный в элементе сервера или, если он пустой,

указанный в элементе провайдера или, если он пустой, авто.

- L2tp PSK, пользователя, пароля: указанный в элементе сервера

или, если он пустой, указанный в элементе провайдера

(вам не нужно повторять их для всех серверов).

- Имя хоста сервера: атрибут Server + базовый домен провайдера,

если атрибут сервера не содержит ни одной "." char

иначе атрибут сервера

-->



<Providers>

  <Provider name="TestVPN1" 

  basedomain="myvpn.com" user="user01" 

  password="hottie">   

    <Server server="sw" />

    <!-- VPN будет иметь sw.myvpn.com в качестве адреса хоста

    и SW TestVPN1 в качестве имени, протокол авто -->

    <Server server="ro" proto="PPTP"/>

    <!-- Протокол сервера переопределяет протокол, указанный в провайдере (в данном случае авто) -->

    <Server server="kick-vm.myvpnext.com" 

    proto="SSTP"/>

    <!-- VPN будет иметь kick-vm.myvpnext.com в качестве адреса хоста

    и KICK-VM TestVPN1 в качестве имени -->

    <Server server="sp" proto="IKEV2" 

    user="user15" password="beer" />

</Provider>

<Provider name="TestVPN2" basedomain="myvpn2.com" 

l2tppsk="12345" user="test001" password="master">

    <Server server="karate" proto="L2TP" 

    l2tppsk="314pi"/>

    <Server server="kazu"  />

    <Server server="moon"  />

    <Server server="sun" />

</Provider>

</Providers>

Внутри архива zip вы найдете 3 файла:

  • DotRas.dll: Это .NET класс библиотеки, которая используется скриптом PowerShell для создания VPN соединений и он должен находиться в той же папке, что и скрипт.
  • vpnconfig.xml: Это вышеприведенный файл конфигурации XML, который должен быть отредактирован с учетом ваших настроек.
  • VpnScripter.ps1: Это сценарий PowerShell, который можно запустить из PowerShell или дважды щелкнуть. Он принимает необязательный параметр с именем ConfigFile, указывающий имя файла конфигурации XML, который нужно использовать (по умолчанию vpnconfig.xml). Вы можете указать флаг -Debug, чтобы получить более подробный вывод журнала.

Скрипт был протестирован в Windows 10, но также должен работать в любой версии Windows, где есть PowerShell 3.0 или выше.

Обзор реализации

В основном весь код находится в одном файле PowerShell с именем VpnScripter.ps1, который содержит смесь кода XSD, C# и PowerShell. В основном он:

  • Анализирует и проверяет файл конфигурации XML vpnconfig.xml с использованием встроенной схемы XSD, определенной внутри сценария PowerShell.

    Сама схема очень простая (например, содержит в основном операторы xs:attribute, указывающие разрешенные/необходимые атрибуты файла конфигурации) и определяет простой тип с именем NotEmptyTrimmedString, который, как следует из названия, проверяет с помощью регулярного выражения, что значение атрибута является “непустой усеченной строкой” (он используется для атрибута сервера, который должен быть “значимым”). Проверка схемы XSD выполняется с помощью сценария PowerShell функции ValidateLoadXml, которая использует стандартные функции .NET для выполнения проверки (например, C# new XmlDocument().Load(XmlReader.Create(<файл>,<настройки со схемой файлом>)))

    
    function ValidateLoadXml([string] $XmlFile, [string] $Schema) {
    
    
    
    	$verr={ 
    
    		Write-Error "Ошибка: некорректный XSD/XML Строка: $($_.Exception.LineNumber) 
    
    		Смещение: $($_.Exception.LinePosition) - $($_.Message)" 
    
    		throw [System.IO.InvalidDataException] 
    
    	}
    
    
    
    	try {
    
    		[System.Xml.XmlReaderSettings]$readsett=New-Object System.Xml.XmlReaderSettings
    
    		$readsett.Schemas.Add([System.Xml.Schema.XmlSchema]::Read
    
    		((New-Object System.IO.StringReader($Schema)),$verr))
    
    		$readsett.ValidationType=[System.Xml.ValidationType]::Schema
    
    		$readsett.add_ValidationEventHandler($verr)
    
    		$xmlconf = New-Object System.Xml.XmlDocument
    
    		$xmlconf.Load([System.Xml.XmlReader]::Create($XmlFile,$readsett))
    
    	}
    
    	catch [System.IO.InvalidDataException]  {
    
    		return $null
    
    	}
    
    	
    
    	return $xmlconf
    
    }	
  • Цикл для всех узлов Server всех узлов Provider файла конфигурации

    Как уже было сказано, как схема XSD, так и вспомогательный код .NET были встроены в скрипт PowerShell в одном почти самодостаточном (требует DotRas.dll) файле. Фактически, в PowerShell скрипты есть прекрасная функция, позволяющая включать любой код .NET, что позволяет им делать все то, что можно сделать с кодом C#. Интересно, как можно разобрать и скомпилировать код C#:

    • Сначала «загрузите» любую DLL (с помощью Add-Type -Path <имя файла dll>) или сборку (с помощью Add-Type -AssemblyName <сборка>), используемую пользовательским кодом
    • Затем разберите и скомпилируйте свой пользовательский код на C# с помощью Add-Type -ReferencedAssemblies <список ссылочных сборок> -TypeDefinition <строка, содержащая код C#> -Язык CSharp
    Add-Type -Path $psscriptroot\DotRas.dll
    Add-Type -AssemblyName System.Xml
    Add-Type -ReferencedAssemblies $psscriptroot\DotRas.dll,System.Xml 
             -TypeDefinition $Source -Язык CSharp

    Интересные факты

    Внешний библиотека DotRas.dll была использована, потому что, кажется, нет способа настроить учетные данные (логин и пароль) с помощью стандартной команды PowerShell Add-VpnConnection, пожалуйста, дайте мне знать, если вы найдете способ.

    Репозиторий

    Вы можете найти репозиторий с исходным кодом на GitHub. Если вы хотите добавить предопределенный файл настроек для вашего поставщика VPN со всеми серверами или улучшить код, добро пожаловать.

    История

    • V1.0 (2 декабря 2016 г.)
      • Первый релиз
    • V1.1. (7 декабря 2016 г.)
      • Добавлено переопределение l2tppsk, Пользователь и пароль в узлах сервера
      • Добавлена проверка XML по средствам XSD и простые проверки пользователь/пароль/l2tppsk параметров
    • V1.2 (27 марта 2017 г.)
      • Добавлен раздел “Обзор реализации”

    Ссылки

    • [1] PPP – это старый точка-точка протокол, исторически используемый для подключения к Интернет-провайдеру с помощью модемов. Он позволяет установить соединение между двумя конечными точками.
    • [2] IPSEC – это зашифрованный туннель между двумя конечными точками, основанный на наборе правил (называемых безопасностные ассоциации), устанавливающих шифрование и алгоритмы целостности, которые должны использоваться в туннеле и сетевые пакеты, которые должно быть туннелировано (например, все пакеты TCP, TCP, адресованные определенному порту и т. д.). По сути, он инкапсулирует TCP/UDP в новый зашифрованный IP-пакет (ESP). Алгоритмы, используемые для шифрования и проверки целостности сообщений, устанавливаются посредством протокола взаимной аутентификации, называемого IKE. Так как клиент и сервер в основном аутентифицируются взаимно по сертификатам, IPSEC обычно используется в VPN сетях типа lan-to-lan (например, для подключения к сети двух разных организаций) и не в сценарии клиент-to-lan, однако для этого типа сценария возможна аутентификация с помощью PSK (предварительно распределенного ключа или общего секретного ключа), хотя это обеспечивает более низкую безопасность.
    • [3] Протоколы туннелирования VPN от Microsoft

Leave a Reply

Your email address will not be published. Required fields are marked *