Избирательный запрет IP на облачный Windows Server 2012 через RDP



    Предприятие состоит из офиса и удаленных магазинов. Однажды работник увел базу клиентов на флешке. После этого все срочно перешли на удаленный рабочий стол с отключенным локальным интерфейсом. Но нужно еще больше контроля админам! Под катом описан способ немного повысить безопасность и контроль ситуации.

    Сервер Windows Server 2012 R2 Standard.

    PowerShell версия
    PSVersion 4.0
    WSManStackVersion 3.0
    SerializationVersion 1.1.0.1
    CLRVersion 4.0.30319.42000
    BuildVersion 6.3.9600.18773
    PSCompatibleVersions {1.0, 2.0, 3.0, 4.0}
    PSRemotingProtocolVersion 2.2

    Все это делалось предыдущим админом на скорую руку, поэтому сейчас вся инфраструктура стоит на костылях. Затем я пришел всё это поддерживать. Одна из новых задач — на облачный рабочий стол офисным менеджерам можно заходить только с офиса. Дома нельзя. При этом оставить избранным возможность работать из дому. А удаленные магазины вообще не трогать. Обычно это делается через политики фаервола или через домен. Так как блокировка нужна избирательная, домена нет, а сервер облачный, то пришлось искать необычные решения.

    Я никогда не писал в PowerShell, поэтому сделал платный запрос техникам нашего хостинга. Но пока они соображали, я набросал быстрое и рабочее решение. Вот схема:

    Создаем папочку для скриптов. Добавляем сам скрипт:

    #saved as UTF8
    #
    $username = "username"			# Системное имя пользователя
    $localnet = "1.2.3.4"	# Разрешенный IP
    
    $lastevent = Get-EventLog Security -Message "*$username*адрес:*.*.*.*" -Newest 1	# Последнее удачное событие входа
    $IP = $lastevent.message.substring($lastevent.message.indexof("Сетевой адрес:")+15,$lastevent.message.indexof("Порт:")-$lastevent.message.indexof("Сетевой адрес:")-18)
    $IDbyName = ((query session $username)[1] -split '\s+')[3]							# Вытягиваем адрес "обрезанием" события
    
    if ($IDbyName -notlike $null) {if ($IP -notlike $localnet) {						# Проверка и выбрасывание
    	logoff $IDbyName
    	"`n---------" | Out-File "C:\SCRIPTFOLDER\Scripts\log.txt" -Append
    	Get-Date | Out-File "C:\SCRIPTFOLDER\Scripts\log.txt" -Append
    	"Сессия RDP завершена`nUSER: $username `nIP: $ip" | Out-File "C:\SCRIPTFOLDER\Scripts\log.txt" -Append
    }}

    Скрипт не самый гибкий, но работающий на ура. Теперь об автоматизации. Заходим в планировщик заданий. Создаем вручную событие, а лучше импортировать через этот task.xml

    task.xml
    <?xml version="1.0" encoding="UTF-16"?>
    <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
      <RegistrationInfo>
        <Date>2018-08-09T15:44:22.8651577</Date>
        <Author>ServerName\AdminUser</Author>
        <Description>Запретить определенным пользователям заходить только с разрешенного IP</Description>
      </RegistrationInfo>
      <Triggers>
        <EventTrigger>
          <Enabled>false</Enabled>
          <Subscription><QueryList><Query Id="0" Path="Security"><Select Path="Security">*[System[(Level=4 or Level=0) and (band(Keywords,9007199254740992)) and (EventID=4648) and TimeCreated[timediff(@SystemTime) &lt;= 3600000]]]</Select></Query></QueryList></Subscription>
        </EventTrigger>
        <SessionStateChangeTrigger>
          <Enabled>true</Enabled>
          <StateChange>RemoteConnect</StateChange>
          <UserId>ServerName\username</UserId>
        </SessionStateChangeTrigger>
        <LogonTrigger>
          <Enabled>true</Enabled>
          <UserId>ServerName\username</UserId>
        </LogonTrigger>
      </Triggers>
      <Principals>
        <Principal id="Author">
          <UserId>ServerName\AdminUser</UserId>
          <LogonType>Password</LogonType>
          <RunLevel>HighestAvailable</RunLevel>
        </Principal>
      </Principals>
      <Settings>
        <MultipleInstancesPolicy>Parallel</MultipleInstancesPolicy>
        <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
        <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
        <AllowHardTerminate>true</AllowHardTerminate>
        <StartWhenAvailable>false</StartWhenAvailable>
        <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
        <IdleSettings>
          <StopOnIdleEnd>true</StopOnIdleEnd>
          <RestartOnIdle>false</RestartOnIdle>
        </IdleSettings>
        <AllowStartOnDemand>true</AllowStartOnDemand>
        <Enabled>false</Enabled>
        <Hidden>false</Hidden>
        <RunOnlyIfIdle>false</RunOnlyIfIdle>
        <WakeToRun>false</WakeToRun>
        <ExecutionTimeLimit>PT1H</ExecutionTimeLimit>
        <Priority>7</Priority>
        <RestartOnFailure>
          <Interval>PT1M</Interval>
          <Count>3</Count>
        </RestartOnFailure>
      </Settings>
      <Actions Context="Author">
        <Exec>
          <Command>PowerShell</Command>
          <Arguments>-File "C:\SCRIPTFOLDER\Scripts\kickUsername.ps1"</Arguments>
        </Exec>
      </Actions>
    </Task>


    Не забудьте переправить ServerName на системное имя сервака, AdminUser на системное имя исполняющего админа и username на системное имя пользователя, которого нужно ограничить.
    После создание таска появляется окно:



    Триггеры запуска:

    1. При удаленном подключении к пользовательскому сеансу username
    2. При входе username

    Действие: запуск программы PowerShell с аргументом -File «C:\SCRIPTFOLDER\Scripts\kickUsername.ps1»

    Обязательно выполнять от админа с наивысшими правами. Нажимаем ОК, вводим пароль админа. Задача готова! Теперь при попытке подключения ограниченного пользователя с чужих IP-адресов его будет выкидывать, а нам будет писать лог в папочку со скриптами.

    Для ограничения нового юзера нужно повторить процесс (хотел сделать список запретов в файлике, но не хватает опыта и времени). На этом всё.

    Критика очень приветствуется, т.к. это мой первый код на PowersHell. Также я осознаю, что данный способ не защищает ценную информацию на 100%. Зато нечестные сотрудники будут вынуждены делать свои темные дела на рабочем месте, а это более опасно для них. Приятного использования!
    Поделиться публикацией
    Комментарии 26
      +2
      Отличное чтиво на пятницу на вечер, люблю мусор в такое время ))
      Все это делалось предыдущим админом на скорую руку, поэтому сейчас вся инфраструктура стоит на костылях.

      а ещё всегда в очереди перед банкоматом тупой, слева на дороге лихач и соседи всегда мешают
      +
      Затем я пришел всё это поддерживать.

      :)

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

      А вышеописанное точно не городушки?
        0
        Предприятие работает больше 5 лет в трех городах и большую часть времени вообще без IT-шников. Точнее был один чувак из другого города, но он приезжал на точку, кидал провода через головы посреди офиса и уезжал. За это время без контроля вся инфраструктура превратилась в раковую опухоль, исправить что-то не поломав систему невозможно. Если есть конкретное замечание по скрипту — пожалуйста, я жду. А обсуждать «городушки» не нужно.
        +1
        Открываем мануал по RDGW и перестаем изобретать велосипед…
          0
          Я перерыл всё в поисках ограничений пользователей. IP в черный список — пожалуйста, но вот пользователей не так просто.
            –1
            не нужно привязываться к ip, проверяйте членство в группах компьютеров откуда идёт подключение и пользователей. надо сделать политику на устройство с проверкой на членство в группе АД и пользователей определённой группы. и вторую политику без проверки устройства, но с проверкой группы пользователей 2. тогда первые будут ходить только с доменных машин, а вторые отовсюду. но я опрометчиво посчитал что у вас есть АД и сервер на хостинге в домене. Если нет, то я не прав, но костыль ваш тоже не очень… тогда можно смотреть авторизацию по сертификатам. в шедулере сейчас есть дыра с повышением прав, ваш костыль просто подарок.
              +1
              Домена нет, сертификаты игнорируем, разные группы на каждой рабочей станции. Такой зоопарк.
                0
                Может первым пунктом следует причесать зоопарк насколько возможно? Домен поднять? VPN организовать? А если пользователь подключился к ВПН — то он и с ресурсами «локалки» может полноценно работать, например?
                Потом и удаленно админить будет легче…

                Я, конечно, понимаю, что все зависит от руководства — сам пришел в контору с одним б/у сервером, без ИБП, с RAID0 из шести дисков (т.е. три RAID0-тома по два диска в каждом) и без бэкапов (на тот-же RAID0-том, ведь не считается?). «Да у нас шесть лет уже всё работает, какой ИБП, мы сервер на Авито дешевле купили, чем этот ИБП?» Но диск умер, денек бухгалтерия со всеми покуковала — и всё сразу сдвинулось с мертвой точки…
          +2
          «Запретить определенным пользователям заходить только с разрешенного IP» — очень двойственная фраза.
          Может означать оно из двух:
          1. запретить пользователю заходить с оставшихся разрешенными IP (т.е. заблокировать его нахрен вообще), или
          2. Больше не проверять, разрешен IP или нет (т.е. пускать отовсюду).

          В любом случае — душевное название, душевное…
            0
            Переписал одну половину, но оставил другую. На работоспособность не влияет.
              0
              На работоспособность не влияет.

              Работоспособность — это прекрасно. Но важнее все-таки, когда админ понимает, что именно делает скрипт. Для понимания очень важны точные описания.

              Допустим, вас переманили в фирму «Рога и Копыта плюс». Вместо вас пришел юный падаван с желанием во всем разобраться. Открывает он список задач и видит ваше «запретить заходить с разрешенных». Поймет ли он, для чего нужна эта задача, или ему надо будет в скрипт смотреть? :)

              Впрочем, ситуация не ограничивается приходом нового админа. Вы сами вполне можете забыть про всю эту машинерию на пару лет (работает и прекрасно). Но вот — вдруг — что-то где-то поломалось, юзер не может зайти, надо срочно фиксить, все вокруг бегают с криками «давай-давай!», а начальство тяжело дышит из-за плеча. Сможете ли вы быстро и безошибочно разобраться в полузабытых скриптах и задачах, особенно если за годы их много накопилось?
                0
                Всё верно, но на момент написание вообще не было времени что-либо перечитывать. Так что спасибо за замечание, буду исправлять.
            0
            Может, лучше разобраться с файерволлом? Сервак, торчащий голой задницей RDP в интернет — не очень безопасно изначально.
              0
              На сервак заходят с разных городов и с домов. Публичный IP обязателен. В данный момент работаю над переводом внеофисных точек работу без RDP.
                0
                Я так понимаю, вариант организовать VPN для этого не рассматривался?
                  0
                  VPN для офиса уже настроен, магазины пока нет. Как изначально рассматривалось уже никто не знает. После воровства срочно нужно было всем запретить доступ к локальным компам.
                  0
                  А хотя бы «завернуть» его в SSH с туннелированием портов? Иначе через пару месяцев вас удивят логи файрвола по порту 3389, а еще через годик-другой может очень удивить потеря/шифрование критичных данных с требованием выкупа.
                0
                Как уже заметили, неверен сам подход, но, если уж хотите только по скрипту, то пожалуйста.

                1. У вас триггер на определенное событие, но в скрипте вы почему-то проверяете не его, а последнее похожее (они совершенно не обязательно совпадут). Ссылайтесь сразу непосредственно на правильное событие, как-то так — blogs.technet.microsoft.com/wincat/2011/08/25/trigger-a-powershell-script-from-a-windows-event

                2. Парсить message — не очень хорошая идея в плане переносимости и поддерживаемости скрипта. Лучше брать непосредственно нужные поля из события.

                3. Если используете не командлеты PS, а вызовы внешних команд, лучше это делать через вызов cmd /c «command [parameter]… » — избежите разных интересных проблем (совпадение алиаса командлета с именем внешней команды, неверную обработку параметров, и т.п.).

                4. «Обязательно выполнять от админа с наивысшими правами. » — от SYSTEM запускайте. Лучше не использовать рабочие учетки для запуска задач — либо делать специальные служебные, либо пользоваться встроенными.
                  0
                  Спасибо, возьму на заметку.
                  0
                  Я дико извиняюсь, простите. Но что такое разрешенный IP?
                  Пул IP? Какой он? Вот у меня к примеру дома пул IP это 10.0.0.0/8 (от так мне удобно в жизни).
                  Если он совпадет с тем что Вы разрешили?

                  Есть мнение что все же лучше VPN (тот же PPTP, кривой косой, но лучше чем никто)
                    0
                    Офис имеет постоянный белый IP. Изнутри офиса менеджеры могут заходить. С любого другого адреса — нельзя. Сервер облачный, если что.
                      0
                      Я это и имел в виду, то есть у Вас есть пул IP который разрешен, к примеру 192.168.100.0/24 если у меня дома такой же пул и я работаю у Вас в компании то в теории я из дома могу зайти?

                      P.S. Сори, понял, Вы чекаете белый статический IP. Гм, тогда как из дома то работать? Ручками пишете IP нужных людей?
                        0
                        Читайте статью. Скрипт затрагивает конкретных пользователей. Остальныe могут работать с дому или в командировкe
                          0

                          Читать статью конечно можно. Но только из комментариев становится понятно что скрипт применяется только к конкретным пользователям. Эти пользователи могут подключаться только с белого IP офиса. Ко всем остальным — удаленным пользователям и магазинам он не применяется.


                          Вот вначале это Одна из новых задач — на облачный рабочий стол офисным менеджерам можно заходить только с офиса. Дома нельзя. При этом оставить избранным возможность работать из дому. А удаленные магазины вообще не трогать. по привычке читается что скрипт для избранных менеджеров работающих с белых IP.


                          После воровства срочно нужно было всем запретить доступ к локальным компам.

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

                    0
                    192.168.100.0/24 это серый адрес. При выходе в интернет используется публичный. У вас дома публичный адрес отличается от нашего, так что не зайдете.
                      +2
                      Знатный велосипед, однако.
                      Сделайте хотя бы VPN между офисом и магазинами, на базе Mikrotik получится довольно недорого и безопасно (например L2TP + IPSec). Поднимите Active Directory и всех пользователей туда — получите единое пространство для авторизации и управление правами/доступами). Если требуется подключение извне (всегда есть какие-нибудь путешествующие менеджеры), настройте RDGW и опубликуйте приложения. Если так уж надо выставить в интернет RDP — можно использовать EvlWatcher для блокировки ботов.
                        0
                        Я думаю, что если стоит задача разрешить какой-то порт(3389) на доступ с определённых IP это прежде всего задача сетевая, которая должна решаться на сетевом оборудовании, а не скриптами на винде(ну… странный выбор)

                        Глобально правильнее(на мой взгяд) сделать офис, магазины, облако в одном пространстве сети ( к примеру, с помощью GRE+IPSEC+OSPF). Далее уже через ACL нарулить чё-куда-кому.
                        Для мигрирующих менеджеров точно таким же образом организовать vpn(к примеру Openvpn), с резервированными адресами и опять же, списком доступа.

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

                        Самое читаемое