Обязательно следует прочитать дополнения к этой статье, разрешающие возникшие проблемы с linkd.

Решил добить идею. Раньше уже писал о реализации белых списков для exchange 2003. Также писал о доступе к этому списку через ADSI средствами powershell.

Exchange в борьбе со спамом: автоматический белый список отправителей (sender whitelist)Есть ещё одна идея в плане автоматизации процесса. Пользователям лень сообщать о своих “важных” контактах, легче по факту неполучения важной информации устроить маленький скандал. Пусть лень. Попробуем использовать их собственные действия для выявления “важных” адресов. Предлагаю доработать сценарий, анализирующий журналы SMTP с целью контроля почты, и выявлять адреса, на которые мы отправляем почту успешно, (за исключением отправки от postmaster и от <>), и эти адреса автоматически добавлять в наш белый список. Причём предварительно проверяя, нет ли в списке уже шаблона для домена адреса. Естественно, по всем таким «добавкам» следует посылать отчёт администраторам по почте. В отчёте также сразу предлагать замену нескольких адресов одного домена на один адрес (шаблон домена вида *@domain), если таковые имеют место быть при «добавлении». Автоматически этого делать нельзя из-за таких доменов как rambler (от имени которого масса спамеров работает) и других крупных сервисов со слишком мягкой spf политикой.
То есть, по сути, предлагаю реализовать автоматический белый список, как это реализовано в большинстве антиспам решений.

Дорабатывать мы будем тот же самый наш скрипт по контролю за почтовым трафиком.

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

From: postmaster@novgaro.ru [mailto:postmaster@novgaro.ru]
To: postmaster@novgaro.ru
Subject: [ГАРО-ITG] Обновление автоматического белого списка отправителей

При проверке исходящих сессий в журнале SMTP сервера обнаружены адреса контрагентов. Ниже — анализ соответствия существующему белому списку:

Вновь вводимые (не соответствуют белому списку) (75):
6334033@mail.ru (1)
alex@3xweb.ru (1)
barbara.marchesini@ravaglioli.com (4)
….
Соответствуют шаблону *@mbi-spedition.de (2):
dementev@mbi-spedition.de (2)
riesen@mbi-spedition.de (3)
Соответствуют шаблону *@samirogroup.com (1):
Serena.Fabbri@samirogroup.com (4)
….

Вновь вводимые записи включены в белый список. Новое состояние белого списка:
*@abuse.net
*@allsoft.ru
*@beeline.ru
250280@rambler.ru
4634006@rambler.ru
6334033@mail.ru
alex@3xweb.ru
….

Предлагаем объединить ряд записей в белом списке одним шаблоном по домену:

- Заменить на шаблон *@abs.msk.ru следующие шаблоны (2):
ee@abs.msk.ru
red@abs.msk.ru
- Заменить на шаблон *@mail.ru следующие шаблоны (15):
6334033@mail.ru
GARO38@mail.ru
….

С Уважением,
postmaster@novgaro.ru.

Из текста письма вырезал лишние данные (…), но суть понятна.

Теперь сценарий (точнее – выдержка):

# ============================================================================================================
# теперь осуществим поиск всех успешных (без кодов 4ХХ и 5ХХ) попыток отправки почты с целью автоматического
# обновления белого списка
# предложение следующее. Осуществим поиск всех исходящих предложений RCPT TO. Далее - найдём на них полученные
# ответы. Если ответ на RCPT TO был положительный, включаем этот адрес в кандидаты в белый список.
# с целью подготовки информационного письма администраторам осуществим поиск всех исходящих сессий на адреса-
# кандидаты и приведём их в письме.
# Далее, проанализируем кандидатов на предмет совпадения с шаблонами, уже находящимися в белом списке. Если
# совпадение обнаружено, адрес включаем в информационное письмо, с указанием шаблона, которому он соответствует
# (группируем по шаблонам). В белый список его уже не добавляем.
# И последнее. Анализируем объединение исходного и нового списков, выделяем шаблоны с общим доменом. И в
# письме предлагаем заменить адреса с общим доменом на шаблон для домена (указывая адреса и предлагаемый шаблон)

$reMailAddr = "(?<addr>(?<lname>[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*)@(?<domain>(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+(?:aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|[a-zA-Z]{2})))"

$outputMailSuccess = Get-ProblemRecords `
	-queryWhere `
@"
	(Direction = 'OutboundConnectionCommand') AND (RequestType = 'RCPT')
"@ `
	-logName $logName

$addrStr = ($sessionLog | where { $_.RequestType -eq 'RCPT' } | select -first 1).Response
$outputMailSuccess.facts | select -first 2
	$newAddrs = $outputMailSuccess.facts | % {
		$collectResponse = $false
		$addrStr = ""
		# ещё нужно проверить, что это не DSN
		if (($_.sessionLog `
			| ? {($_.Direction -eq "OutboundConnectionCommand") -and ($_.RequestType -eq "MAIL")} `
			| select -first 1 `
		).RequestParams -match $reMailAddr) {
			if (-not ("postmaster@novgaro.ru" -contains $matches["addr"])) {					$emailFromAddr = $matches["addr"]
				$emailFromLName = $matches["lname"]
				$emailFromDomain = $matches["domain"]
				$_.sessionLog | % {
					if (($collectResponse) -and ($_.Direction -eq "OutboundConnectionResponse") -and ($_.Response -match "^250")) {
						if ($addrStr -match $reMailAddr) {
							$emailAddr = $matches["addr"]
							$emailLName = $matches["lname"]
							$emailDomain = $matches["domain"]
						} else {
							$emailAddr = ""
							$emailLName = ""
							$emailDomain = ""
						}

						$resObj = new-Object System.Management.Automation.PSObject
						$resObj | add-member -memberType NoteProperty -name FromAddr -value $emailFromAddr
						$resObj | add-member -memberType NoteProperty -name FromLName -value $emailFromLName
						$resObj | add-member -memberType NoteProperty -name FromDomain -value $emailFromDomain
						$resObj | add-member -memberType NoteProperty -name ToAddr -value $emailAddr
						$resObj | add-member -memberType NoteProperty -name ToLName -value $emailLName
						$resObj | add-member -memberType NoteProperty -name ToDomain -value $emailDomain
						write-output $resObj
					}
					$collectResponse = ($_.RequestType -eq "RCPT")
					if ($collectResponse) {
						$addrStr = $_.RequestParams
					} else {
					}
				}
			}
		} else { # отправитель - <>, это - DSN
	}
}

# загрузим контрольный список шаблонов адресов из AD
$exchSenderFilterConfig = [ADSI]"LDAP://CN=Default Message Filter,CN=Message Delivery,CN=Global Settings,CN=NovGARO,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=novgaro,DC=ru"
$exchTurfListNames = $exchSenderFilterConfig.msExchTurfListNames

# проведём проверку нового списка на повторения и на соответствия шаблонам адресов из AD
$newAddrsGrouped = $newAddrs | group ToAddr | sort name | % {
	$newAddr = $_.name
	$matchedWildcard = ( $exchTurfListNames | ? { $newAddr -like $_ } | select -first 1)
	if ($matchedWildcard) {
		$_ | add-member -memberType NoteProperty -name matchedWildcard -value $matchedWildcard
	}
	$_
}

# объединяем
$exchTurfListNames = ($exchTurfListNames + ($newAddrsGrouped | ? {-not $_.matchedWildcard} | % {$_.name})) | sort | %{$("$_")}

# обработаем белый список, выделим домены
$newTurfList = $exchTurfListNames | % {
	$test = $_ -match reMailAddr
	$resObj = new-Object System.Management.Automation.PSObject
	$resObj | add-member -memberType NoteProperty -name Wildcard -value $matches["addr"]
	$resObj | add-member -memberType NoteProperty -name Domain -value $matches["domain"]
	$resObj
}

# отправляем письмо администраторам
if ($outputMailSuccess.factsCount) {
	$SMTPclient.Send( `
		$emailFrom, `
		$emailTo, `
		"[ГАРО-ITG $($myinvocation.mycommand.name)] Обновление автоматического белого списка отправителей", `
@"
При проверке исходящих сессий в журнале SMTP сервера обнаружены адреса контрагентов. Ниже - анализ соответствия
существующему белому списку:

$($newAddrsGrouped | group matchedWildcard | sort name | % {
	if ($_.name) {
		"`nСоответствуют шаблону $($_.name) ($($_.count)):"
	} else {
		"`nВновь вводимые (не соответствуют белому списку) ($($_.count)):"
	}
	$_.group | % {
		"`n`t$($_.name) ($($_.count))"
	}
})

Вновь вводимые записи включены в белый список. Новое состояние белого списка:
$($exchTurfListNames | % {
	"`n`t$_"
})

Предлагаем объединить ряд записей в белом списке одним шаблоном по домену:

$($newTurfList | group Domain | ?{$_.count -ge 2} | sort name | %{
	"`n- Заменить на шаблон *@$($_.name) следующие шаблоны ($($_.count)):"
	$_.group | sort Wildcard | % {
		"`n`t$($_.wildcard)"
	}
})

P.S. Скрипт: $($myinvocation.mycommand.path)

С Уважением,
postmaster@novgaro.ru.
"@ `
)
}

# сохраняем новый белый список в AD
$exchSenderFilterConfig.msExchTurfListNames = $exchTurfListNames
$exchSenderFilterConfig.SetInfo()

Благодаря информации Xaegr о именованных группах захвата в регулярных выражениях (рекомендую прочитать весь цикл статей указанного автора о регулярных выражениях – ясно, понятно, с изюмом), реализовал выделение e-mail адресов и их частей (домена, lname) в более читабельном варианте.

Опубликовать комментарий

XHTML: Вы можете использовать следующие HTML теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Tags Связь с комментариями статьи:
RSS комментарии
Обратная ссылка