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

Случилась (да и регулярно случается) со мной подобная история. Не скажу, что я изобрёл что-то новое и выдающееся. Скорее наоборот – воспользовался трудами коллег, найденными в просторах интернета и в кладезях премудрости Хабра. Но мне удалось объединить их для решения вполне конкретной и достаточно интересной задачи. Далее я опишу конкретное решение конкретной задачи по управлению паролями пользователей в Active Directory. Точнее, автоматизацию проверки срока действия этих паролей и генерации новых паролей. В качестве признательности коллегам я счёл необходимым опубликовать это решение здесь, в надежде, что оно кому-то пригодится или послужит источником новых идей.

Итак, существует некая организация с могучей и разветвлённой филиальной сетью. Филиалов много по всей нашей необъятной Родине и все они разнокалиберны. Большая часть из них включена в корпоративную сеть с доменной структурой, но множество подключено по принципу home-office. В дополнение к тому многие сотрудники постоянно находятся в длительных командировках без возможности подключаться к доменной сети и к интернету вообще.

В результате часто возникает проблема просроченных паролей. Политикой компании определён запрет на бессрочные пароли, а требования с строгости паролей достаточно суровы, что вызывает у пользователей сложности с их придумыванием и заменой. Соответственно, ничтоже сумняшеся свою головную боль они радостно перекладывают на IT поддержку, звоня и требуя сменить их уже недействующий пароль. Регулярно. Надоело.

Итак, что же мне захотелось сделать? Мне нужно средство, которое:
• само проверяло срок истечения действия пароля пользователя;
• предварительно предупреждало его о дате смены пароля по электропочте;
• предлагало пользователю вариант нового пароля;
• если пользователь не успел сменить пароль, автоматически заменяло его на новый;
• уведомляло пользователя о новом пароле посредством SMS.

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

В результате получился скрипт, а точнее — два скрипта. Почему так, объясняется просто – так сложилось исторически. Дело в том, что проверку паролей производит скрипт на виртуальной машине, расположенной в одном филиале, а рассылкой уведомлений по SMS занимается другая машина, расположенная в противоположной части страны. Из-за условий мобильного оператора иначе делать было нерентабельно.

Далее привожу оба скрипта целиком, которые я максимально прокомментировал. Выглядят они немного кучеряво. У меня не было особой потребности их причёсывать, поскольку работают они хорошо и в таком виде:

# Скрипт производит проверку паролей, срок действия которых истекает завтра,
# отсылает владельцу новый пароль по email,
# и автоматически заменяет, если срок действия паролей истёк. 
#
# функция записи логов.
$dt=Get-Date -Format "dd-MM-yyyy"
$setupFolder = "c:\Active_Directory\Log"
New-Item -ItemType directory -Path $setupFolder -Force | out-null #Создаю директорию для логов
$global:logfilename="C:\Active_Directory\Log\"+$dt+"_LOG.log"
[int]$global:errorcount=0 #Ведем подсчет ошибок
[int]$global:warningcount=0 #Ведем подсчет предупреждений
function global:Write-log	# Функция пишет сообщения в лог-файл и выводит на экран.
{param($message,[string]$type="info",[string]$logfile=$global:logfilename,[switch]$silent)	
    $dt=Get-Date -Format "dd.MM.yyyy HH:mm:ss"	
    $msg=$dt + "`t" + $type + "`t" + $message #формат: 01.01.2001 01:01:01 [tab] error [tab] Сообщение
    Out-File -FilePath $logfile -InputObject $msg -Append -encoding unicode
    if (-not $silent.IsPresent) 
    {
        switch ( $type.toLower() )
        {
            "error"
            {			
                $global:errorcount++
                write-host $msg -ForegroundColor red			
            }
            "warning"
            {			
                $global:warningcount++
                write-host $msg -ForegroundColor yellow
            }
            "completed"
            {			
                write-host $msg -ForegroundColor green
            }
            "info"
            {			
                write-host $msg
            }			
            default 
            { 
                write-host $msg
            }
        }
    }
}

#Функция генератора сложных паролей
function global:Get-RandomPassword
 {
<# Функция генератора паролей PasswordLength - длина пароля #>
[CmdletBinding()]
 param(
 [Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true)]
 [ValidateRange(4,15)]
 [Int]
 $PasswordLength
 )
 Begin{}
 Process{
$numberchars=0..9 | % {$_.ToString()}
 $lochars = [char]'a' .. [char]'z' | % {[char]$_}
 $hichars = [char]'A' .. [char]'Z' | % {[char]$_}
 $punctchars = [char[]](33..47)
$PasswordArray = Get-Random -InputObject @($hichars + $lochars + $numberchars + $punctchars) -Count $PasswordLength
$char1 = Get-Random -InputObject $hichars
 $char2 = Get-Random -InputObject $lochars
 $char3 = Get-Random -InputObject $numberchars
 $char4 = Get-Random -InputObject $punctchars
$RndIndexArray = Get-Random (0..($PasswordLength-1)) -Count 4
$PasswordArray[$RndIndexArray[0]] = $char1
 $PasswordArray[$RndIndexArray[1]] = $char2
 $PasswordArray[$RndIndexArray[2]] = $char3
 $PasswordArray[$RndIndexArray[3]] = $char4
return [system.string]::Join('', $PasswordArray)
}
 End{}
 }

#SMTP адрес почтового сервера
$smtpServer = "mail.domain.local"
#создаем объект письмо
$msg = new-object Net.Mail.MailMessage
$msgr = new-object Net.Mail.MailMessage
#создаем объект почтовый сервер
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
# Функция для сообщения пользователю
Function EmailStructure($to,$expiryDate,$upn)
{
	$msg.IsBodyHtml = $true
	$msg.From = "ITHelpDesk@domain.local"
    $msg.To.Clear()
	$msg.To.Add($to)
	$msg.Subject = "Password expiration notice"
	$msg.Body =
     "<html><body><font face='Arial'>This is an automatically generated message from Company IT Service.<br><br>
     <b>Please note that the password for your account <i><u>domain\$upn</u></i> will expire on $expiryDate.</b><br><br>
     System automatically generated a new password for you. <br>
     You can use password - <b>$generated_password</b><br>
     Please change your password immediately or at least before this date as you will be unable to access the service without contacting your administrator.<br>
     If you will not change your password, System set it automatically.<br>
     </font></body></html>"}

# Функция для отчёта администратору
Function EmailStructureReport($to)
{
	$msgr.IsBodyHtml = $true
	$msgr.From = "PasswordChecker@domain.local"
	$msgr.To.Add($to)
	$msgr.Subject = "Script running report"
	$msgr.Body = 
"<html><body><font face='Arial'><b>This is a daily report.<br>
<br>Script for check expiried passwords has successfully completed its work.
<br>$NotificationCounter users have recieved notifications:<br>
<br>$ListOfAccounts<br><br></b></font></body></html>"}

# Подключаем модуль для работы с Active Directory
Import-Module activedirectory
# получаем список всех активированных российских пользователей, у которых установлен срок действия пароля
$NotificationCounter = 0
$OU = "OU=Russia,DC=local,DC=domain"
$ADAccounts = Get-ADUser -LDAPFilter "(objectClass=user)" -searchbase $OU -properties PasswordExpired, employeeNumber, PasswordNeverExpires, PasswordLastSet, Mail, mobile, Enabled | Where-object {$_.Enabled -eq $true -and $_.PasswordNeverExpires -eq $false}

# для каждого пользователя
foreach ($ADAccount in $ADAccounts) 
#проверяем политику сложности пароля
{
 $accountFGPP = Get-ADUserResultantPasswordPolicy $ADAccount
                if ($accountFGPP -ne $null)
		  {
                 $maxPasswordAgeTimeSpan = $accountFGPP.MaxPasswordAge
		  }
		else
		  {
                 $maxPasswordAgeTimeSpan = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
           }
#Заполняем переменные пользовательскими данными
	$samAccountName = $ADAccount.samAccountName
	$userEmailAddress = $ADAccount.mail
	$userPrincipalName = $ADAccount.UserPrincipalName
   	$userStorePassword = $ADAccount.employeeNumber
	$usermobile = $ADAccount.mobile
	# Для каждого из пользователей, не успевшего сменить пароль
	if ($ADAccount.PasswordExpired)
	   {
                # Считываем пароль из атрибутного поля AD
	# Если нет ранее сохранённого пароля, устанавливаем пароль по умолчанию - Pa$$w0rd
	if ($userStorePassword -eq $NULL -or $useStorePassword -eq " ")
		{
			$userStorePassword = "Pa$$w0rd"		}
        # Заменяем пароль на новый
        $newpwd = ConvertTo-SecureString -String $userStorePassword -AsPlainText –Force
        Set-ADAccountPassword -Identity $samAccountName -NewPassword $newpwd –Reset
	# Сохраняем новый пароль и номер мобильного телефона в TXT файл
    
	if ($usermobile -ne $NULL)
	       {   
		$SMSfile="C:\ActiveDirectory\SMS_notice.txt"
		$SMSMessage=$usermobile + "," + $userStorePassword
	        Out-File -FilePath $SMSfile -InputObject $SMSMessage -Append -encoding unicode
		}
       # Делаем запись в журнале
        write-log "for $samAccountName will set a stored password - $userStorePassword. Message send to mobile - $usermobile"
        write-log "---------------------------------------------------------------------------------------------------------"
	      
        # Очищаем атрибутное поле AD
        Set-ADUser $samAccountName -employeeNumber $null
	   }
	else
        # Для всех тех, у кого пароль истекает завтра, то есть $DaysToExpireDD меньше 2
	   {
	   $ExpiryDate = $ADAccount.PasswordLastSet + $maxPasswordAgeTimeSpan
	   $TodaysDate = Get-Date
	   $DaysToExpire = $ExpiryDate - $TodaysDate
       #Вычисляем дней до просрочки в DaysToExpireDD в формате дней
	   $DaysToExpireDD = $DaysToExpire.ToString() -Split ("\S{17}$")
            if (($DaysToExpire.Days -le 2))
            		{
                    Write-log "The password for account $samAccountName expires on: $ExpiryDate. Days left: $DaysToExpireDD
# Генерируем новый пароль в переменную $generated_password
                    $generated_password = Get-RandomPassword 10
                   write-log "Generated password: $samAccountName - $generated_password"
		   write-log "-----------------------------------------------------------------------------------------"

                    # Записываем новый пароль в атрибутное полe AD. Будем пользоваться атрибутом employeeNumber
                    Set-ADUser $samAccountName -employeeNumber $generated_password
                    # отсылаем письмо с предупреждением пользователю 
                     if ($userEmailAddress) #проверяем наличие адреса электронной почты у пользователя.
			                 {
	                        EmailStructure $userEmailAddress $expiryDate $samAccountName
	                       $smtp.Send($msg)
                               write-log "NOTIFICATION - $samAccountName :: e-mail was sent to $userEmailAddress"
                               $NotificationCounter = $NotificationCounter + 1
                               $ListOfAccounts = $ListOfAccounts + $samAccountName + " - $DaysToExpireDD days left. Sent to $userEmailAddress<br>"			}
                  		     }
			}
		}
#Отправляем список новых паролей на сервер, который занимается отправкой SMS
# Если список существует
If (Test-Path $SMSfile) 
    {
    Copy-Item -Path $SMSfile -Destination \\SMS-Send-Server.domain.local\C$\ActiveDirectory\SMS_notice.txt
# Удаляем файл со списком новых паролей  
  Remove-Item $SMSfile 
    }
# отсылаем копию отчёта администратору 
Write-log "SENDING REPORT TO IT DEPARTMENT"
EmailStructureReport("ITHelpdesk@domain.local")
$smtp.Send($msgr)

Этот скрипт добавим в Планировщик Заданий Windows, настроив его на выполнение в нужное нам время. Например, ночью.

К сожалению, скрипт проверяет просроченные пароли в момент своего выполнения. Так что если срок действия пароля истекает днём, то он его не будет учитывать. Но ведь нам это и не требуется, ибо в рабочее время сотрудник может поменять пароль самостоятельно.

В результате мы получаем список мобильных номеров пользователей, которым установлен новый пароль. Этот список мы отправим на сервер, к которому подключен GSM-модем. А там этим списком займется уже следующий скрипт.

#
#Скрипт получает список мобильный номеров и сообщений из файла и рассылает пользователям
#
# указываем, где хранится файл со списком
$sms_text_filename = "SMS_notice.txt"
$PathToSmsPrepareToSend = "C:\ActiveDirectory" + "\" + $sms_text_filename
$dt=Get-Date -Format "dd.MM.yyyy"
# указываем, куда мы будем сохранять журнал событий
$of="C:\ActiveDirectory\Log\"+$dt+"_LOG.log"
# Проверяем наличие списка сообщений
If (Test-Path $PathToSmsPrepareToSend)
{
    $SMS = Import-Csv $PathToSmsPrepareToSend -Header mobile, newpassword
# для каждой строки из списка сообщений
    foreach ($SM in $SMS)
    { 
        # $mobileForSMS = $SM.mobile
        # $passwordFroSMS = $SM.newpassword  
        #  echo $mobileForSMS
        # Объявляем экземпляр класса SerialPort
        $serialPort = new-Object System.IO.Ports.SerialPort
        # Устанавливаем переменные настроек порта, к которому подключен модем
<# 
!!!Важно!!! USB-модем использует три COM порта. Нам нужен тот, который отображается в Диспетчере устройств в настройках модема. Если воткнуть GSM-модем в другой USB порт, то номер COM порта изменится.
#>
        $serialPort.PortName = "COM3"
        $serialPort.BaudRate = 115200
        $serialPort.WriteTimeout = 500
        $serialPort.ReadTimeout = 3000
        $serialPort.DtrEnable = "true"
        # Открываем порт
        # $serialPort.Open()
        # Сохраняем номер телефона и сообщение в переменные
        # Удаляем лишние пробелы в номере телефона
        $phoneNumber = [Regex]::replace($SM.mobile,'\s','')
        $textMessage = "Your new password - " + $SM.newpassword
        try {
            $serialPort.Open()
            }
        catch 
            {
            # Ждём 5 секунд и пытаемся снова
            Sleep -Milliseconds 500
            $serialPort.Open()
            }
        If ($serialPort.IsOpen -eq $true) 
        {
            # Указываем модему, что будем использовать режим AT-команд
            $serialPort.Write("AT+CMGF=1`r`n")
            Sleep -Milliseconds 500
            # Отправляем данные в модем
            # Сначала номер  телефона в международном формате
            # и символы  <CL> в конце
            $serialPort.Write("AT+CMGS=`"$phoneNumber`"`r`n")
            # Даём модему время на обработку
            Sleep -Milliseconds 500
            # Записываем в модем наше сообщение
            $serialPort.Write("$textMessage`r`n")
            Sleep -Milliseconds 500
            # отсылаем в модем Ctrl+Z в качестве завершения сообщения.
            $serialPort.Write($([char] 26))
            # подождём, пока модем отошлёт сообщение
            Sleep -Milliseconds 500
        }
        # Закрываем порт
        $serialPort.Close()
        if ($serialPort.IsOpen -eq $false) 
        {
	# записываем результат в журнал
            $dts=Get-Date -Format "dd.MM.yyyy HH:mm:ss"
            $msg=$dts+" :Message "+$textMessage+" send to "+ $phoneNumber
            Out-File -FilePath $of -InputObject $msg -Append -encoding unicode
        }
        Sleep -Milliseconds 1000
    } #Конец цикла обработки строки из списка
# переименовываем файл списка сообщений для сохранения в истории
$newname =$dt+"_"+$sms_text_filename
rename-item -path $PathToSmsPrepareToSend -newname $newname
}  #Конец проверки существования списка
Else
# Если списка сообщений не существует
{
# Делаем запись в журнале, что сообщений для отправки не было
$dts=Get-Date -Format "dd.MM.yyyy HH:mm:ss"
$msg=$dts + " :No data to send SMS"
Out-File -FilePath $of -InputObject $msg -Append -encoding unicode
}

Скрипты проверены в боевых условиях и показали себя с наилучшей стороны.

Я не буду объяснять, почему сделал именно так, поскольку задача была достаточно конкретна. И решение получилось вполне конкретное.

Но я буду рад любым советам по улучшению или оптимизации скриптов.

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


  1. blind_oracle
    07.04.2015 19:57

    У нас управление паролями реализовано через web-интерфейс (PHP), LDAP и всякие шелл-скрипты.

    Пользователь может сменить свой пароль в любое время, но не реже чем раз в 180 дней + ведётся статистика по его предыдущим паролям, чтобы не повторялись последние столько-то штук + проверяется наличие его логина, транслитерированного ФИО и т.п. в пароле в различных вариациях.

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

    А так как у вас в статье — муторно очень, нужна база актуальных мобильных, да и доверять отправку паролей СМС как-то не айс.


    1. Razaz
      07.04.2015 22:04
      +1

      Ну мобилки можно актуализировать в том же AD(это то же LDAP). При отправке СМС я бы ставил атрибут об обязательной смене пароля при логине.

      А так все эти поделки от лукавого — полно нормальных IDM с SelfService пользователей.


    1. ader Автор
      08.04.2015 07:19

      У пользователей конечно же есть возможность работать с паролями через web. Это решение — лишь дополнение к другим инструментам.
      Интересно было решить данную задачу именно встроенными инструментами: AD + powershell, без использования сторонних программ и сервисов.


  1. kuber
    08.04.2015 06:29
    +3

    Скажите, а может проще убрать требование к периодической смене пароля, раз уж Вы так легкомысленно относитесь к безопасности?
    Отсылать новый пароль в открытом виде по электронной почте (надеюсь, что у вас хотя бы свой почтовый сервер) или в открытом виде в смс, через стороннюю организацию это очень легкомысленно.
    А пароль от электронной почты пользователь меняет как часто или Вы это вообще не регламентируете? Тогда это вообще «отлично».


    1. ader Автор
      08.04.2015 07:26

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


      1. siv237
        08.04.2015 07:56
        +1

        Рискую нарваться на критику, но все-же скажу. Периодическая принудительная смена паролей простым пользователям в большинстве случав зло!
        Вот человек-пользователь. Он далек в своих помыслах от каких-то там требований к безопасности информационных ресурсов и прочим абстрактным для него вещам. Его основной мотив — простота и путь наименьшего сопротивления. Если ему приходится придумывать пароль самому, он придумает его таким образом, что-бы его легко запомнить. Пароли 123, 111 или просто 1 — наиболее логичный выбор для них. Такой пароль легко запомнить.
        Хорошо, говорит админ схватившись за голову. Вот вам ограничение на длинну — не меньше n символов. Ок отвечает пользователь и задает цифрами дату своего рождения или рождения ребёнка. Он инстинктивно стремиться поставить пароль, который он запомнит.
        Ладно говорит админ и задаёт критерий сложности к паролю и тут происходит перелом в безопасности. Суть его в том, что человек уже не может запомнить пароль который и вбил то с трудом. И что он делает? Правильно он его записывает на бумажке. Кладет он её в лучшем случае под клавиатуру. В худшем на липкий листок наклеивает прямо на монитор или клавиатуру.
        Тут добавляем требование — менять пароли периодически и получаем гарантированный результат. Никто больше не пытается запомнить пароль, а те кто честно пытаются это сделать и не записывать, начинают вам названивать и просить сменить. Отлично, приехали. начинаем административную борьбу!
        Начинаем, жаловаться руководству, оно делает вид что согласно и ай-ай и надо бы всех наказать, а сами краем глаза такой-же листочек замечаете у директора под клавиатурой.

        Всё-таки, что-то не так написано в учебниках по безопасности. Правила не работают. Слепое следование казалось бы очевидным любому админу правилам безопасности приводит в большинстве случаев к резкому падению той самой безопасности.

        В итоге моё личное мнение:
        1. Пароль должен быть такой, который пользователь легко и с радостью запомнит (делаем цифры).
        2. Пароль должен быть таким, чтобы по словарю его было не подобрать ну и брутфорс небыл слишком быстрым, не быстрее и дешевле чем выпытать из данного юзера свой пароль методами социальной инженерии (проверяем пароль по словарю самых частых паролей).
        3. Раздельная политика для системных паролей и пользовательских. Часто получается так, что как раз админы ставят пароли себе попроще и не вводят политику смены паролей для серверных задач (чтоб все не слетело и не забыть если что).


        1. Retifff
          08.04.2015 09:53
          +1

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


        1. anton1234
          08.04.2015 12:09
          -2

          Конечно же вы нарветесь на критику.
          Для начала вы исходите из того, что пользователи неадекватные, низкоквалифицированные люди. Это далеко не всегда так. Большинству вполне реально объяснить зачем нужны сложные пароли и почему их нужно менять. В финансовой и ит сфере с этим как правило нет проблем. Но это больше к социальной инженерии относится. А теперь техническая критика.
          1. Сложный пароль на бумажке это гораздо безопаснее простого в памяти. Достаточно обеспечить физическую безопасность бумажки.
          2.Ваше личное мнение. П1 и п2 несовместимы. Никак, вообще совсем никогда.
          В плане безопасности пароля уже придумано целых 2 решения которые решают большинство проблем.
          1. Двухфакторная авторизация. Раздайте всем по токену с простым пинкодом. Хотя это и близкий эквивалент пароля на бумажке в смысле необходимости обеспечения физической безопасности материального объекта.
          2. Были проведены исследования длины пароля. 20 символов даже при использовании словарных слов обеспечивают достаточную безопасность. Запомнить фразу из 3-4 слов способен любой.


          1. anton1234
            08.04.2015 12:34

            image


        1. SinTeZoiD
          15.04.2015 13:13

          Немного поздновато, но всё же. Я думаю тут самое место для этой истории.

          1.1

          Однажды Сисадмин пожаловался Учителю:

          – Мы выдали всем нашим пользователям индивидуальные пароли, а они не желают хранить их в тайне. Записывают на листочках и приклеивают к мониторам. Что нам делать? Как заставить их?

          Инь Фу Во спросил:

          – Сначала скажи, почему они это делают.

          Сисадмин подумал и ответил:

          – Может быть, они не считают пароль ценным?

          – А разве пароль сам по себе ценный?

          – Не сам по себе. Ценна информация, которая под паролем.

          – Для кого она ценна?

          – Для нашего предприятия.

          — А для пользователей?

          – Для пользователей, видимо, нет.

          – Так и есть, – сказал Учитель. – Под паролем нет ничего ценного для наших работников. Надо, чтоб было.

          – Что для них ценно? – спросил Сисадмин.

          – Догадайся с трёх раз, – рассмеялся Учитель.

          Сисадмин ушёл просветлённый и сделал на корпоративном портале персональные странички для всех работников. И на тех страничках был указан размер зарплаты. Узнав об этом, все пользователи забеспокоились о своих паролях. На другой день в курилке обсуждали размер зарплаты Главбуха. На третий день ни у кого не было видно листочков с паролями.


      1. kuber
        08.04.2015 07:57

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

        >> Почтовый сервер у нас свой и пароли к почтовым аккаунтам меняются каждый месяц.
        В таком случае, я не рекомендую вам и вашим коллегам ссорится с администратором почтового сервера, потому что благодаря вам он со временем получит доступ к паролям всех ваших пользователей.
        Расскажите о ежемесячной процедуре смены пароля для почтового ящика?


        1. ader Автор
          08.04.2015 08:30

          Идея про генератор паролей вполне здаравая, спасибо. Я обязательно постараюсь её реализовать.


          1. kuber
            08.04.2015 10:11
            +1

            Пожалуйста, но все же расскажите как у вас реализована ежемесячная смена пароля от электронного ящика?


            1. ader Автор
              08.04.2015 10:44

              Пользователи заходят в панель управления аккаунтом и меняют пароль.


              1. kuber
                08.04.2015 10:59
                +1

                Каждый месяц, в принудительном порядке?
                Мне кажется, что отдел IT не очень любят в вашей организации. ;)


                1. ader Автор
                  08.04.2015 11:08

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


      1. ildarz
        08.04.2015 11:07

        Никак. Весь смысл парольной защиты базируется на том, что пароль должен быть известен только пользователю, и он не должен нигде храниться в открытом виде. А делать обязательную смену паролей и при этом генерить их самому и рассылать — это просто профанация. Зачем вы вообще пароли меняете? Формальное требование? Если да, то формально вы его реализовали, но реально безопасность никак не повысили, скорее понизили. :)


      1. Vinchi
        08.04.2015 17:11

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


  1. skazi_premiere
    08.04.2015 11:41

    Есть давно придуманный пароль «Pa$$word» который упоминается на всех курсах M$, скрипт выполняет сброс на этот пароль или какой-либо другой стандартизированный для вашей организации, и устанавливает признак на смену пароля при первом входе. Высылаете SMS о необходимости сменить пароль (на тот, который придумает он сам).
    Мы например в инструкции сразу писали базовый пароль и все пользователи его знали.

    Список простых паролей соответствующих стандартной политике, 8 символов.
    Многие возможно слышали о таких вещах на курсах.
    Помойка1
    Помойка2
    Помойка3


    Помойка24
    «Мой предыдущий пароль»


    1. Vinchi
      08.04.2015 17:17

      Если будет сброс на стандартный пароль, то это дыра в безопасности. Сотрудник в отпуске, ему сбросили пароль на стандартный, теперь можно пройтись по всем логинам AD и среди них точно найдется несколько тех, кто еще не сменил со стандартного.
      Вобщем пароль свой должен знать только сотрудник, даже helpdesk ни в коем случае его знать не должен.
      Для привелегированных пользователей (т.е. у тех у кого есть хотя бы чуть более высокие права чем у рядового пользователя) — обязательно необходимо внедрять токены или другой способ двухфакторной аутентификации.
      Пароли надо передавать тоже не в чистом виде а одноразовыми ссылками. Сервис одноразовых ссылок использовать свой. Пример onetimesecret.com/ — у него есть исходники. Берете и разворачиваете у себя на серверах.