Дистанционная работа в компаниях все больше становится распространённой в последнее время. Системным администраторам нужно организовывать на домашних компьютерах пользователей подключение по VPN к сети компании. Время настройки занимает от 10 минут и это если все пойдет гладко, пользователь сообразит как скачать Any Desk или какой другой клиент для удаленного подключения, потом факт стабильного интернета играет роль, ну и конечно же настройка самого VPN подключения — вбиваем адрес, метод шифрования, логин, пароль, ключ.

А если пользователей 10 и более? Это уже нужно потратить больше времени, а если им всем нужно утром срочно все настроить? Тут немного подумав, я решил написать достаточно простой, но в то же время полезный скрипт на Power Shell а потом упаковал его в файлик .exe.

Прошу строго не судить, надеюсь материал кому-нибудь пригодится.

Процесс создания скрипта с комментариями:

Повышаем привилегии до администратора:

if (!(net session)) {$path =  "& '" + $myinvocation.mycommand.definition + "'" ; Start-Process powershell -Verb runAs -ArgumentList $path ; exit}

Разрешаем выполнение локальных скриптов:

Set-ExecutionPolicy RemoteSigned -Force

Установить переменные для VPN-подключения:

# Имя подключения
$VPNconnectionSSTP = "VPN_SSTP"
$VPNconnectionL2TP = "VPN_L2TP"

# тип подключения       
$VPNtypeSSTP = "sstp"                           
$VPNtypeL2TP ="l2tp"

# ip адрес или доменное имя                           
$SRVaddressSSTP = "ip_addr"
$SRVaddressL2TP = "ip_addr"

# DNS суффикс
$dnssuf = "domain.local"

# ключ l2tp
$l2tp_key = "ключ"

# метод аутентификации
$auth_method = "MSChapv2"

# сертификат .cer открываем через блокнот и копируем от начала до конца
$vpn_cert = "-----BEGIN CERTIFICATE-----
сам сертификат (скопировать содержимое открыв его через текстовый редактор)
-----END CERTIFICATE-----"

Сохраняем сертификат в директории пользователя:

$vpn_cert | Out-File -FilePath "$env:HOMEPATH\vpn_cert.cer" -Encoding utf8

Создаем SSTP-соединения SSTP и L2TP соответственно:

Add-VpnConnection -Name $VPNconnectionSSTP -ServerAddress $SRVaddressSSTP -TunnelType $VPNtypeSSTP -AuthenticationMethod $auth_method -EncryptionLevel "Optional" -DnsSuffix $dnssuf -SplitTunneling -IdleDisconnectSeconds 900 -RememberCredential -AllUserConnection

Add-VpnConnection -Name $VPNconnectionL2TP -ServerAddress $SRVaddressL2TP -TunnelType $VPNtypeL2TP -AuthenticationMethod $auth_method -L2tpPsk $l2tp_key -EncryptionLevel "Optional" -DnsSuffix $dnssuf  -SplitTunneling -IdleDisconnectSeconds 900 -RememberCredential -AllUserConnection

Устанавливаем сертификат в доверенные корневые сертификаты пользователя:

certutil -f -addstore root "$env:HOMEPATH\vpn_cert.cer"

Возвращаем политику выполнения скриптов по умолчанию

Set-ExecutionPolicy Default –Force

Все! Скрипт готов. Сохраняем его с расширением .PS1

P.S.Можно запускать так и не менять executionpolicy на машине:

powrshell -f "path\to\script.ps1" -executionpolicy bypass

Также можем сделать из него EXE файлик для удобства:

Программа называется PS2EXE есть на гите

Также было предложено пользователем Artem @pr0l проверять наличие созданного vpn соединения на случай смены сертификата, ключа шифрования или какого другого важного параметра.

if (Get-VpnConnection -Name $vpn_name -AllUserConnection -ErrorAction Ignore -Verbose)
{ Remove-VpnConnection -Name $vpn_name -AllUserConnection -ErrorAction Ignore -Verbose -Force

# Удаляем сертификат
Remove-Item -Path HKLM:\SOFTWARE\Microsoft\SystemCertificates\ROOT\Certificates\32323F22E9065D0157DE9B902020DA41A12B4E53 -ErrorAction Ignore -Verbose
}
else {}

# дальше ниже создаем новое соединение

Еще дополнение от @SlavaHU если кому понадобится добавления маршрута в подсеть:

$VPNconnectionL2TPDestPrefix = "192.168.6.0/24"

Add-VpnConnectionRoute -ConnectionName $VPNconnectionL2TP -DestinationPrefix $VPNconnectionL2TPDestPrefix

Комментарии (32)


  1. PaveTranquil
    09.01.2023 08:20
    +2

    Недурно) Но, думаю, после разрешения на выполнение скриптов, надо бы обратно вернуть к исходному состоянию — иначе теперь ПК уязвим на исполнение несанкционированных скриптиков.


    1. leonid_seredkin Автор
      09.01.2023 08:22

      Спасибо за комментарий, поправил


      1. Nday001
        09.01.2023 12:22
        +2

        Есть нюанс, что скрипт может упасть в процессе работы и тогда executionpolicy не вернётся к исходному состоянию. Хотя вообще эта меру безопасности очень сомнительная.

        Можно запускать так и не менять executionpolicy на машине:

        powrshell -f "path\to\script.ps1" -executionpolicy bypass


        1. leonid_seredkin Автор
          09.01.2023 12:38

          Спасибо, добавил в статью))


  1. avelor
    09.01.2023 10:42
    +1

    альтернативно - можно закинуть rasphone.pbk с сертификатом (можно зашить в бинарь, можно sfx собрать..), ну или воспользоваться инструментом CMAK, тогда можно и кастомизировать окно подключения (например добавить телефон техподдержки). так же как и при создании пошиком, удобно сразу добавить маршруты для реализации split-tunnel, только ЕМНИП пошиком докидывание маршрутов работает начиная с вин10


    1. pr0l
      09.01.2023 11:41
      +1

      1. Для создания впн соединения не всегда нужны админские права

      2. СМАК вспотеешь собирать, проще PS скриптом.

      3. Сертификат можно сразу в бинарном виде из скрипта добавлять локальному пользователю в реестр.

      4. В любом случае логин и пароль в windows10 придется вводить руками или запускать так же из консоли "rasdial.exe vpn_name login password"

      У меня в статье более расширено описано как подключаться через скрипт. https://habr.com/ru/post/693056/

      Хотя смотрю она у тебя и так в закладках)

      Это для раздела всего компьютера, раздел пользователя будет другой

      # создаем ветку с названием сертификата 32323F22E9065D0157DE9B902020DA41A12B4E53

      New-Item -Path HKLM:\SOFTWARE\Microsoft\SystemCertificates\ROOT\Certificates -name 32323F22E9065D0157DE9B902020DA41A12B4E53 -Verbose -Force

      # создаем раздел в созданной ветке. Файл бинарный, нужно добавить "0x" перед каждым байтом сертификата

      New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\SystemCertificates\ROOT\Certificates\32323F22E9065D0157DE9B902020DA41A12B4E53 -Name Blob -PropertyType "Binary" -Value ([byte[]] (0x04,0x00,0x00,0x00, ..... ,0x61,0xa4)) -Force -Verbose


      1. avelor
        09.01.2023 12:52
        +1

        как будто вводить руками пароль это что-то плохое :D мне чем нравится отдавать pbk - это просто файл забрали, двойным кликом запустили, подключились, также отключились. а с CMAK-ом было весело когда были популярны х86 десктопы. приходилось делать два CMAK-а, и опять же запихивать в автоустановщик с выбором разрядности системы.

        сейчас практикую больше впн-ы без клиентских настроек-конфигов-прочих подпрыгиваний, вроде any\open connect


        1. pr0l
          09.01.2023 12:55

          может у тебя kerberos проверка логина и пароля? У себя я коннект делаю теневым, без участия пользователя. Каждый комп со своими данными. Есть инет подключится, пропадет, будет долбится пока не подключится. В итоге пользователь не влияет на подключение


          1. avelor
            09.01.2023 13:13

            не, такое практикую разве что по серту (на комп) и с лимитированным доступом. на полноценный впн осознанно запрос пароля + второго фактора, безопасность должна быть безопасной:)


  1. Stas_VTK
    09.01.2023 11:45
    +1

    Мой вариант для дистанционной работы: выдал нуждающимся (благо, что их можно по пальцам одной руки пересчитать:) загрузочную флешку с кастомизированным образом LUbuntu. На рабочем столе всего 2 ярлыка: запуск ssh туннеля и rdp к серверу, там и там - с паролем. Запускается на чем угодно. Пользователи рады.


    1. leonid_seredkin Автор
      09.01.2023 11:58

      Отличный вариант, тоже планируем внедрить такой подход к удаленке


    1. pr0l
      09.01.2023 12:00

      )) могу научить SSTP на убунте поднимать


      1. leonid_seredkin Автор
        09.01.2023 12:17

        Спасибо, попробую, если что напишу))


  1. Vzhik53
    09.01.2023 11:45
    +1

    Повышаем привилегии до администратора:

    После этого VPN соединения создаются в профиле администратора. А у пользователя, для которого и предназначался скрипт, их не будет.


    1. pr0l
      09.01.2023 11:58

      если создавать с параметром add-VpnConnection "-AllUserConnection" будет доступен для всех


    1. leonid_seredkin Автор
      09.01.2023 12:04

      Спасибо, добавлю в статью


  1. Lukerman
    09.01.2023 11:46

    Спасибо за статью ! Я тут семейную сетку конфигурирую с шарой на VPS, есть пара проблемных пользаков, понял что поправить !


  1. Ufo28
    09.01.2023 11:46

    Можно разрешать выполнение скрипта из скрипта?

    А EXE-файлик как делать? Хотя-бы ссылку.


    1. leonid_seredkin Автор
      09.01.2023 11:56

      Добрый день, PS2EXE программа называется, я ей делал, на гите есть


    1. pr0l
      09.01.2023 12:01

      можно словить кучу проблем, тк этот ехе файл будут детектить как вирус. Он не подписан, он исполняет что-то с привилегиями администратора. Не самый лучший вариант.


  1. ildarz
    09.01.2023 12:27

    Повышаем привилегии до администратора

    Зачем?

    Set-ExecutionPolicy Unrestricted -Force

    Опять же - зачем? Тем более в ситуации, когда вы это пишете ВНУТРИ скрипта, который планируете запускать (небезопасно и бессмысленно одновременно).

    Out-File -FilePath "$env:HOMEPATH\vpn_cert.cer" -Encoding utf8

    Зачем тут UTF-8? Формат файла сертификата в указанном виде - закодированный в base64 ASCII .


    1. leonid_seredkin Автор
      09.01.2023 12:43

      Зачем?

      В конце возвращаем политику выполнения в дефолт

      Зачем тут UTF-8?

      Если честно, по другому кажется не получалось... давно это делал, но так же работает))? Спорить не буду, попробую. Спасибо за комментарий


      1. ildarz
        09.01.2023 15:03

        В конце возвращаем политику выполнения в дефолт

        1. А если у вас скрипт посреди исполнения прервется по любой причине (вылетит по ошибке, скажем), что будет? :)

        2. А зачем вы вообще меняете политику, какой конкретно смысл несет эта команда у вас в скрипте?

          Не надо заниматься шаманством, не понимая в точности, что делает та или иная команда в том или ином конкретном случае. Это в лучшем случае просто загромождает скрипт, в худшем - может привести к совершенно неожиданным для вас последствиям.


        1. leonid_seredkin Автор
          09.01.2023 15:39

          Согласен, безопасность должна быть безопасной, но данный скрипт повторюсь, ориентирован на малюсенькую задачу, облегчить настройку подключения vpn на домашнем пк. Изменил в статье на RemoteSigned, думаю будет в самый раз))


  1. pr0l
    09.01.2023 12:52
    +1

    ну и было бы не дурно, раз у тебя так много пользователей, подумать над тем что у тебя уже есть такое соединение. В твоем скрипте оно не даст создаться и пользователь будет пытаться подключаться со старыми данными.

    Нужна проверка, если такое соединение есть, то удалять его и создавать новое.

    if (Get-VpnConnection -Name $vpn_name -AllUserConnection -ErrorAction Ignore -Verbose)
    { Remove-VpnConnection -Name $vpn_name -AllUserConnection -ErrorAction Ignore -Verbose -Force

    # Удаляем сертификат
    Remove-Item -Path HKLM:\SOFTWARE\Microsoft\SystemCertificates\ROOT\Certificates\32323F22E9065D0157DE9B902020DA41A12B4E53 -ErrorAction Ignore -Verbose
    }
    else {}

    # дальше ниже создаем новое соединение


    1. leonid_seredkin Автор
      09.01.2023 14:18

      Так идея скрипта, однократно настроить соединение до компании на домашнем пк пользователя, запросив только логин и пароль


      1. pr0l
        09.01.2023 16:30
        +1

        Просто ты еще не столкнулся с тем что сертификат просрочился, маршрут нужно сменить, общий ключ изменился и тп.


        1. leonid_seredkin Автор
          09.01.2023 16:37

          А, ты про это)) тогда, да, можно такую проверку прикрутить)) добавлю в статью, спасибо


  1. SlavaHU
    09.01.2023 17:17
    +1

    А я еще добавляю в аналогичный скрипт маршрутизацию. Типа:

    $VPNconnectionL2TPDestPrefix = "192.168.6.0/24"

    Add-VpnConnectionRoute -ConnectionName $VPNconnectionL2TP -DestinationPrefix $VPNconnectionL2TPDestPrefix

    Понятно, что не во всех случаях это актуально, но у меня VPN для доступа только к рабочей подсети, а не к тому, чтобы через нее все тиктоки смотрели...


    1. leonid_seredkin Автор
      10.01.2023 03:36

      Спасибо, добавил


  1. whoiam_frontend
    10.01.2023 03:27
    +1

    На основе этого всего и создаются трояны-шпионы. В фоновом процессе подобный скрипт следит за трафиком. Некоторые антивирусы считают подобные скрипты за угрозы, а не ВПН.


  1. W3n8f34
    11.01.2023 14:23

    впны на личных компах это зло