ORF –  достаточно лёгкий антиспам, который позволяет, не сильно загружая систему, хорошо прореживать трафик нежелательной корреспонденции. Он имеет замечательный фильтр, название которого я вынес в заголовок – HELO Domain Blacklist.

Простейшая smtp-сессия выглядит следующим образом:

1 220 my.server1.name Microsoft ESMTP MAIL Service ready
2 EHLO remote.server2.name
3 250 my.server1.name Hello [2.2.2.2]
4 MAIL FROM:user@remote.server2.name
5 250 2.1.0 Sender OK
6 RCPT TO:user@my.server1.name
7 250 2.1.5 Recipient OK

Фактически, уже на втором шаге мы имеем информацию по серверу отправителю, на основании которой мы можем делать заключение – хотим мы принимать от него сообщения или нет. Для этого мы можем использовать либо базы DNSBL, которые содержат адреса нехороших серверов, либо на основе каких-то правил самостоятельно анализировать имя сервера, который открыл с нами smtp-сессию. Фильтр HELO Domain Blacklist в ORF как раз и позволяет сформулировать такие правила и на основе их выполнения сбрасывать smtp-сессию, либо продолжать её (пометив письмо).

Фильтр содержит набор предопределённых условий:

  • Blacklist if the HELO/EHLO domain… is malformed – помечать в случае использования “неправильного” имени домена в HELO/EHLO
  • Blacklist if the HELO/EHLO domain… is the same as the recipient domain – помечать, если домен внешнего сервера отправителя совпадает с доменом сервера получателя
  • Blacklist if the HELO/EHLO domain… is not an FQDN – помечать, если в HELO/EHLO содержится не FQDN-имя

И набор условий, которые заданы пользователем (User-Defined HELO domain blacklist). Я использовал следующие регэкспы:

  1. .*(d{1,3})D(d{1,3})D(d{1,3}).*..*$
  2. .*(-|.|^)(access|adsl|athedsl|broadband|cable|catv|chello|client|clients|cpe|dhcp|dial|dialup|dsl|dyn|dynamic|dynamicIP|mod em|modems|node|pool|pools|ppp|pppd|pppoe|pppool|range|static|staticIP|user|xdsl|0x[0-9abcdef]{8})(-|.|d).*..*$
  3. .*(d{7}).*..*..*$
  4. .*(.|^)(home.nl|shawcable.net|fallback.pochta.ru|tpnet.pl|net.pl|net.il|pppool.de|chello.DD|orange.DD|ne.jp|rr.com| mundo-r.com|volia.net|free.fr)$
  5. .*(?<!.ad|.ae|.al|.am|.at|.au|.az|.ba|.be|.bg|.biz|.bs|.by|.ca|.ch|.cn|.com|.cy|.cz|.de|.dk|.dm|. do|.dz|.edu|.ee|.eg|.er|.es|.et|.fi|.fr|.ge|.gi|.gov|.gr|.hk|.hr|.ht|.hu|.ie|.il|.in|.is|.it|.jm| .jo|.kg|.kr|.kw|.kz|.li|.lt|.lu|.lv|.ma|.mc|.md|.mn|.mt|.mv|.my|.net|.nl|.no|.org|.pt|.qa|.ro|.r u|.sa|.se|.sg|.si|.sk|.su|.sy|.sz|.tj|.tm|.tr|.tw|.ua|.uk|.us|.uz|.va|.ye|.yu)$
  6. .*[^a-z0-9-.].*
  7. .*..*..*..*..*..*

Подробнее:

  1. Комбинация из “(1-2-3 значное число)(не цифра)(1-2-3 значное число)(не цифра)(1-2-3 значное число)”. Если имя сервера попадает под это условие – то потенциально оно сформировано на базе ip-адреса и, скорее всего, сервер с таким именем будет слать спам.
  2. В имени отправляющего сервера содержится любое слово из access, adsl, athedsl, broadband, cable, catv, chello, client, clients, cpe, dhcp, dial, dialup, dsl, dyn, dynamic, dynamicIP, modem, modems, node, pool, pools, ppp, pppd, pppoe, pppool, range, static, staticIP, user, xdsl, а также конструкцию, похожую на шестнадцатеричный ip-адрес. То есть сервер отправитель с очень большой вероятностью является клиентом домашних сетей, либо некорпоративным клиентом интернет-провайдеров. То есть с очень большой вероятностью не должен слать почту на внешние smtp-серверы. И скорее всего он будет рассылать спам.
  3. В имени отправляющего сервера содержится конструкция из семи цифр подряд в имени хоста (не домена). То есть отправитель умудрился скорее всего засунуть в имя сервера свой номер телефона, что вроде как запрещено по RFC. Поэтому сервер скорее всего рассылает спам.
  4. Список доменов, с которых не хотим принимать почту.
  5. Список доменов первого уровня, с которых хотим получать почту. Фактически регэксп содержит отрицание списка, то есть если сервер отправителя не содержится в одном из этих доменов, то он потенциальный спамер.
  6. В имени сервера отправителя содержатся символы, которые не входят в набор разрешённых (латинские буквы, цифры, знаки “-” и “.”). Сервер – потенциальный спамер.
  7. Домены слишком глубокой вложенности (host.subdomain1.subdomain2.subdomain3.subdomain4.subdomain5.com).

Регэкспы не мои.

Какие-то из них можно применять, какие-то нет. Категорически рекомендую их перенастраивать под себя. Очень полезны – первый и второй. Скоро станет бесполезен шестой (когда массово можно будет использовать нелатинские символы в именах почтовых серверов). Когда я использовал ORF, фильтрация по HELO/EHLO отбивала примерно 45% входящего smtp-трафика, примерно столько же приходилось на DNSBL. Остальные механизмы давали единичные срабатывания.

Exchange Management Shell в Exchange 2010 запускается следующим скриптом (посмотреть можно в свойствах ярлыка):

... -command ". '.RemoteExchange.ps1'; Connect-ExchangeServer -auto"

Фактически при запуске шелла используется функция Connect-ExchangeServer с ключом auto. Сама функция описана в скрипте ConnectFunctions.ps1, который находится в папке с бинарными файлами (там же где и скрипт RemoteExchange.ps1). Ключ auto в свою очередь обращается к функции _AutoDiscoverAndConnect, которая описана в том же файле:

if ($Auto)
{
_AutoDiscoverAndConnect $credential $Forest -useWIA:$useWIA
}

Теперь самое интересное – при запуске этой функции мы используем функции, которые позволяют определить хост, на котором запускается скрипт, лес и структуру окружающих его сайтов с тем, чтобы подключить клиента к “ближайшему” серверу Exchange. Почему я написал “ближайший” в кавычках станет ясно в конце этой небольшой статьи. Итак, по порядку.

Хост получаем через функцию _GetHostFqdn примерно следующим образом:

[System.Net.Dns]::GetHostByName("LocalHost").HostName

Лес определяем через функцию _GetLocalForest:

[System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain().Forest.Name

Сайты ищем через функцию _GetSites. Функция эта фактически возвращает массив, состоящий из имён сайтов. Первый член массива – текущий сайт, в котором находится сервер, с которого мы запускаем EMS:

$localSite=[System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite()

Следующие – так называемые смежные сайты (AdjacentSites). Здесь мы берём все сайт-линки для нашего текущего сайта (фактически те, в которых он имеется в наличии) и вытаскиваем из них либо первый, либо второй сайт и добавляем его имя в наш массив. Выглядит это следующим образом:

if ($localSite.SiteLinks -ne $null)
{
foreach ($siteLink in $localSite.SiteLinks)
{
$siteDN = $null
# block going backwords
if (($siteLink.Sites[0] -ne $null) -and ($siteLink.Sites[0].Name -ne $localSite.Name))
{
$siteDN = $siteLink.Sites[0].GetDirectoryEntry().DistinguishedName
}
elseif ($siteLink.Sites[1] -ne $null)
{
$siteDN = $siteLink.Sites[1].GetDirectoryEntry().DistinguishedName
}
if ($siteDN -ne $null)
{
[void] $SiteList.Add($siteDN)
}
}
}

Ну и наконец, добавляем в массив символ *, которым будут обозначаться все остальные сайты, не попавшие в смежные сайты:

[void] $SiteList.Add("*")

Тут возникает первый момент, который пока мне остался непонятным. Если у нас сайт-линков несколько, то они попадают все в свойство SiteLinks нашего текущего сайта. Выглядеть это будет примерно так:

[PS] C:Windowssystem32>$localSite | fl SiteLinks

SiteLinks : {SITELINK1, SITELINK2, SITELINK3}

То есть фактически это будет массив. Как в нём группируются сайт-линки (в каком порядке перечисляются) – непонятно. А ведь от этого зависит какой сайт-линк будет обрабатываться первым, какой вторым итд. Аналогичный момент возникает с массивом сайтов в сайт-линке:

[PS] C:Windowssystem32>$localSite.SiteLinks[0] | fl Sites

Sites : {SITE1, SITE2, SITE3}

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

Возвращаясь к нашей функции. После получения списка сайтов мы пробуем получить список серверов Exchange в каждом из них через функцию _GetExchangeServersInSite. Функция эта ищет все объекты класса msExchExchangeServer в сайте старше определённой версии. Например, для Exchange Server 2010 SP3 это будет выглядеть так:

$configNC=([ADSI]"LDAP:/$Forest/RootDse").configurationNamingContext
$search = new-object DirectoryServices.DirectorySearcher([ADSI]"LDAP:/$Forest/$configNC")
$search.Filter = "(&(objectClass=msExchExchangeServer)(versionNumber>=1937801568)
(msExchServerSite=$siteDN))"
$search.PageSize=1000
$search.PropertiesToLoad.Clear()
[void] $search.PropertiesToLoad.Add("msexchcurrentserverroles")
[void] $search.PropertiesToLoad.Add("networkaddress")
[void] $search.PropertiesToLoad.Add("serialnumber")
$search.FindAll()

И наконец со списком серверов доходим до функции _ConnectToAnyServer, которая и занимается созданием удалённого (через New-PSSession) подключения к первому доступному из списка серверу Exchange. Причём, сначала пытаемся подключаться к серверам с ролью CAS, затем ко всем остальным.

К чему я это веду. А к тому что, данная процедура не предусматривает оценки стоимости сайт-линков, а тупо перебирает доступные объекты. В итоге администратор удалённого сайта может попытаться подключаться к серверам Exchange, которые находятся совсем не в ближайшем к нему (по стоимости) сайте, а совсем даже на другой континент, например.

Это к слову о пользе правильной архитектуры сайтов AD.

Забавно, но в Технете указан не совсем правильный способ определения размера логов действий администратора. Предлагается считать полный размер папки RecoverableItems:

Get-MailboxFolderstatistics "Guid of arbitration mailbox" -FolderScope RecoverableItems 
–IncludeAnalysis

Фактически, папка RecoverableItems содержит в себе несколько подпапок (AdminAuditLogs, Deletions, Purges, Versions) и нас интересует статистика только по одной – AdminAuditLogs. Поэтому более правильной будет команда:

Get-MailboxFolderStatistics "Guid of arbitration mailbox" -FolderScope RecoverableItems | 
? {$_.Name -like "AdminAuditLogs"}

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

Get-MailboxFolderStatistics "Guid of mailbox" -FolderScope RecoverableItems | 
? {$_.Name -like "Audits"}

e2010Ранее я вскользь касался момента с переносом общих папок из базы на одном сервере в базу на другом сервере. Использование скрипта MoveAllReplicas.ps1 помогает в большинстве случаев. Но иногда, возникает ситуация, когда конкретная реплика общей папки не удаляется из базы общих папок. То есть в свойствах общей папки в репликах отсутствует некоторая база общих папок, но де-факто реплика из этой базы по какой-то причине не удалилась. Если таких папок немного, то можно их выгрузить в pst-файл и папку пересоздать. Если таких папок много – то приходится искать другие механизмы. Самый простой – попробовать добавить реплику общей папку в проблемную базу и удалить её через скрипт RemoveReplicaFromPFRecursive.ps1. Проще всего это сделать через PowerShell:

#$PFs - содержит список неудалившихся реплик
$PFs = Get-PublicFolderStatistics -Server pfserver -ResultSize unlimited | Get-PublicFolder
#$PFDB - база, которую вычищаем
$PFDB = Get-PublicFolderDatabase -Server pfserver

foreach ($PF in PFs) {
#Получаем список реплик и добавляем в них проблемную базу
$repl = Get-PublicFolder -Identity $PF.Identity -Server pfserver
$repl.Replicas+= $PFDB.Identity
Set-PublicFolder -Identity $PF.Identity -Replicas $repl.Replicas

#Обновляем содержимое проблемных реплик
Update-PublicFolder -Identity $PF.Identity -Server pfserver;
}

По итогам выполнения скрипта запускаем процедуру удаления реплики:

.RemoveReplicaFromPFRecursive.ps1 -TopPublicFolder  -ServerToRemove pfserver

После этого ждём, пока отработает этот скрипт. Можно отслеживать процесс относительно интерактивно. Для этого необходимо повысить уровень логгирования для баз общих папок на проблемном сервере:

Set-EventLogLevel 'psserverMSExchangeIS9001 PublicReplication*' -Level High

События в логе с номером 3005 будут сигнализировать о том реплика общей папки была удалена из базы общих папок на проблемном сервере:

Log Name:      Application
Source:        MSExchangeIS Public Store
Event ID:      3005
Task Category: Replication AD Updates
Level:         Information
Keywords:      Classic
User:          N/A
Computer:      psserver
Description:
A replica of public folder (6-6891E5C6D7) IPM_SUBTREESome Folder
was removed.
Database PF-DATABASE.

В один прекрасный день от офицера службы информационной безопасности поступает интересное письмо. На почтовых серверах в Security log появляются странные события о сбое в процессе аутентификации:

Log Name:      Security
Source:        Microsoft-Windows-Security-Auditing
Event ID:      4625
Task Category: Logon
Level:         Information
Keywords:      Audit Failure
User:          N/A
Computer:      mailserver1.domain.com
Description:
An account failed to log on.

Subject:
Security ID:         SYSTEM
Account Name:        MAILSERVER1$
Account Domain:      DOMAIN
Logon ID:            0x3E7

Logon Type:                3

Account For Which Logon Failed:
Security ID:         NULL SID
Account Name:
Account Domain:

Failure Information:
Failure Reason:      Account currently disabled.
Status:              0xC000006E
Sub Status:          0xC0000072

Process Information:
Caller Process ID:   0x1c64
Caller Process Name: C:WindowsSystem32inetsrvw3wp.exe

Network Information:
Workstation Name:    MAILSERVER1
Source Network Address:    -
Source Port:         -

Detailed Authentication Information:
Logon Process:             Authz
Authentication Package:    Kerberos
Transited Services:  -
Package Name (NTLM only):  -
Key Length:          0

Вопрос – что это и что с этим делать?

Из интересного, на что стоит сразу обратить внимание – учётная запись, для которой произошёл сбой аутентификации в событии не указывается. Следовательно придётся исследовать что же это за учётная запись использовалась. Второе – для аутентификации использовался Керберос. Следовательно первая зацепка есть. Включаем дополнительное логгирование для Керберос на сервере, на котором ловим ошибки, как это описывается тут. По завершении процесса необходимо будет не забыть выключить дополнительное логгирование.

После включения параллельно с событием в Security Log начало появляться следующее событие в Event Log:

Log Name:      System
Source:        Microsoft-Windows-Security-Kerberos
Event ID:      3
Task Category: None
Level:         Error
Keywords:      Classic
User:          N/A
Computer:      mailserver1.domain.com
Description:
A Kerberos error message was received:
on logon session
Error Code: 0x12 KDC_ERR_CLIENT_REVOKED
Extended Error: 0xc0000072 KLIN(0)
Client Realm:
Client Name:
Server Realm: DOMAIN.COM
Server Name: mailserver1$@DOMAIN.COM
Target Name: mailserver1$@DOMAIN.COM@DOMAIN.COM

А вот это уже интересно. Есть замечательный документ, который я категорически рекомендую – Troubleshooting Kerberos Errors. Он утверждает, что в данной ситуации необходимо слушать трафик. Чем я и занялся. Спустя некоторое время, оба верхних события появились в логах. Network Monitor при этом выловил 2 пакета – запрос на получение билета (TGS Request) и ошибку (KRB_ERROR). Ошибка не очень интересна, потому что дополнительной информации, кроме KDC_ERR_CLIENT_REVOKED она не даёт. А вот TGS Request даёт дополнительную информацию:

- Kerberos: TGS Request Realm: DOMAIN.COM Sname: mailserver1$DOMAIN.COM
- TgsReq: Kerberos TGS Request
- KdcReq: KRB_TGS_REQ (12)
- PaData:
+ PaData: PA-TGS-REQ (1)
- PaData: PA-FOR-USER (129)
- PaForUser:
+ UserName: SM_63b993a3b98c43b2b
+ UserRealm: DOMAIN

В PaData содержится метод PA-FOR-USER, который содержит данные учётной записи, которая используется при запросе билета. В данном случае это – DOMAINSM_63b993a3b98c43b2b или, говоря человеческим языком – SystemMailbox{e0dc1c29-89c3-4034-b678-e6c29d823ed9}, стандартная учётка, которая используется Exchange-сервером при поисковых запросах. Так как по умолчанию она выключена, то KDC возвращает в итоге ошибку, а в лог идёт фраза “Account currently disabled”. Абсолютно правильное поведение KDC, как это описано тут.

Следующий вопрос – зачем сервер пытается для этой учётки получить билет Керберос я пока оставлю без ответа.

Полезные ссылки:
How to enable Kerberos event logging
Troubleshooting Kerberos Errors
Check Account Policy for Every Session Ticket Request
PA-FOR-USER

Примерно полтора года назад с одной из прошивок raid-контроллера на серверы IBM приехала принудительная поддержка 512e. После чего, серверы в DAG превратились в тыкву относительно бесполезные куски железа. Было:

c:>fsutil fsinfo ntfsinfo c:
...
Bytes Per Sector  :               512
Bytes Per Physical Sector :       512
...

Стало:

c:>fsutil fsinfo ntfsinfo c:
...
Bytes Per Sector  :               512
Bytes Per Physical Sector :       4096
...

Эффект это производило ошеломительный. Локальная копия базы сразу отказывалась реплицироваться на таком “обновлённом” сервере. Достаточно подробно причины произошедшего и что с этим делать были разобраны в посте, опубликованном в блоге команды Exchange спустя примерно полгода после выпуска “волшебных” прошивок.

Кейс переварился. Проблему забороли. Но IBM оказался хитрее. Он выпустил очередную прошивку, которая исправляла косяки прошивки, вышедшей полтора года назад. 🙂

Было:

c:>fsutil fsinfo ntfsinfo c:
...
Bytes Per Sector  :               512
Bytes Per Physical Sector :       4096
...

Стало:

c:>fsutil fsinfo ntfsinfo c:
...
Bytes Per Sector  :               512
Bytes Per Physical Sector :       512
...

Эффект оказался не менее ошеломительным. Локальная копия базы сразу отказалась реплицироваться. Бинго!

ServeRAID SAS/SATA M5014, M5015 and M5025 controllers experienced a change in its firmware code beginning with version 12.12.0-0111, 12.12.0-0126 and 12.12.0-0133 to support 512e and 4k hard drives that is currently not offered by IBM.

There are no plans to support 512e or 4096 sector size hard drives for the IBM ServeRAID M5014, M5015 or M5025 SAS/SATA controllers.

Голубой гигант ну-у-у очень неторопливо исправляет свои баги.

Стандартная, вроде бы, ситуация с добавлением нового узла (из другого датацентра) в DAG вываливается ошибкой:

Error: An error occurred while attempting a cluster operation. Error: Cluster API
'"AddClusterNode() (MaxPercentage=12) failed with 0x35. Error: The network path was not found

DagTask ситуацию не особо проясняет:

[] ClusterSetupProgressCallback( eSetupPhase = ClusterSetupPhaseValidateNodeState,
ePhaseType = ClusterSetupPhaseStart, ePhaseSeverity = ClusterSetupPhaseInformational,
dwPercentComplete = 12, szObjectName = MBX3, dwStatus = 0x0 )
[] ClusterSetupProgressCallback( eSetupPhase = ClusterSetupPhaseValidateNodeState,
ePhaseType = ClusterSetupPhaseContinue, ePhaseSeverity = ClusterSetupPhaseFatal,
dwPercentComplete = 12, szObjectName = MBX3, dwStatus = 0x35 )
[] ClusterSetupProgressCallback( eSetupPhase = ClusterSetupPhaseValidateNodeState,
ePhaseType = ClusterSetupPhaseEnd, ePhaseSeverity = ClusterSetupPhaseFatal,
dwPercentComplete = 12, szObjectName = MBX3, dwStatus = 0x35 )
[] ClusterSetupProgressCallback( eSetupPhase = ClusterSetupPhaseFailureCleanup,
ePhaseType = ClusterSetupPhaseStart, ePhaseSeverity = ClusterSetupPhaseInformational,
dwPercentComplete = 12, szObjectName = MBX3, dwStatus = 0x0 )
[] ClusterSetupProgressCallback( eSetupPhase = ClusterSetupPhaseFailureCleanup,
ePhaseType = ClusterSetupPhaseEnd, ePhaseSeverity = ClusterSetupPhaseInformational,
dwPercentComplete = 12, szObjectName = , dwStatus = 0x0 )

[] The preceding log entry comes from a different process running on computer 'MBX2.domain.ru'
[] The operation wasn't successful because an error was encountered. You may find more
details in log file "C:ExchangeSetupLogsDagTasksdagtask____.log".
[] WriteError! Exception = Microsoft.Exchange.Cluster.Replay.DagTaskOperationFailedException:
A database availability group administrative operation failed. Error: The operation failed.
CreateCluster errors may result from incorrectly configured static addresses. Error:
An error occurred while attempting a cluster operation. Error: Cluster API '"AddClusterNode()
(MaxPercentage=12) failed with 0x35. Error: The network path was not found"' failed. --->
Microsoft.Exchange.Cluster.Replay.AmClusterApiException: An Active Manager operation failed.
Error An error occurred while attempting a cluster operation. Cluster API '"AddClusterNode()
(MaxPercentage=12) failed with 0x35. Error: The network path was not found"' failed.. --->
System.ComponentModel.Win32Exception: The network path was not found

Видно, что добавление в DAG прерывается на фазе проверки (eSetupPhase = ClusterSetupPhaseValidateNodeState). Ради интереса попробовал запустить проверку узлов из оснастки Failover Cluster. Проверка проходит.

Потом подумал на проблему с разным количеством сетевых интерфейсов на Primary Active Manager и новом узле DAG. В Planning for High Availability and Site Resilience явно не указано, что количество сетевых интерфейсов на всех узлах DAG должно быть одинаково. Однако, знающие люди сказали, что в DAG можно добавлять серверы с разным количеством сетевых интерфейсов, хотя, вроде бы, это и не поддерживаемая конфигурация.

Пришлось слушать трафик. Тут пошли более интересные результаты. например:

1027     ip2     ip3     SMB2     SMB2:C   TREE CONNECT (0x3), Path=\MBX3IPC$
1028     ip3     ip2     SMB2     SMB2:R   TREE CONNECT (0x3), TID=0x11
1029     ip2     ip3     SMB2     SMB2:C   IOCTL (0xb), FID=0xFFFFFFFFFFFFFFFF
1030     ip3     ip2     SMB2     SMB2:R  - NT Status: System - Error,
Code = (34) STATUS_ACCESS_DENIED  IOCTL (0xb)

PAM пытается подключиться к IPC$ на новом узле и получает ACCESS_DENIED. Согласно спецификации SMB3 запрос IOCTL, в котором содержится FID=0xFFFFFFFFFFFFFFFF фактически является запросом на согласование Security-диалектов между узлами перед разрешением SMB-сессии. Подробнее эта процедура описана тут. ACCESS_DENIED возвращается, в частности, когда сервер не может подтвердить запрос, и, скорее всего, это является следствием того, что возникла ошибка аутентификации.

Тут внезапно оказывается, что между датацентрами есть небольшое расхождение во времени (около минуты). Это быстро исправляют. Ошибка уходит…

Полезные ссылки:
SMB3 Secure Dialect Negotiation
Planning for High Availability and Site Resilience
[MS-SMB2]: Server Message Block (SMB) Protocol Versions 2 and 3

Недавно сталкивался с одной проблемой, связанной с недоконфигурацией NLB. Исходные данные: каждый сервер имеет два сетевых адаптера, помещённых в одну подсеть/вилан. Один из сетевых адаптеров используется для обработки клиентского трафика, второй для коммуникации между узлами NLB-кластера. На базе второго адаптера строится NLB-кластер, дефолтный шлюз прописан, соответственно, на адаптере для обработки клиентского траффика. Примерная схема может выглядеть так:

nlb-2nic

В этой схеме, начиная с Windows Server 2008 мы будем иметь следующее:

  • связь с кластерным ip-адресом из той же сети, где расположены узлы NLB, будет работать без каких-либо проблем
  • связь с кластерным ip-адресов из внешней сети (клиент обращается через маршрутизатор) будет отсутствовать
  • если мы переносим дефолтный шлюз с клиентского адаптера на кластерный, то связь с кластерным ip-адресом появляется

Внешний клиент пытается попасть на кластерный адаптер, но так как шлюза на нём не прописано, то пакет отбрасывается. Связано это с тем, что IP forwarding, включенный по умолчанию в Windows 2003 Server, позволявший отвечать клиенту через дефолтный шлюз, начиная с Windows Server 2008 выключен по умолчанию. А раз он выключен, то надо его включить. Например через netsh:

netsh interface ipv4 set interface "Cluster NIC" forwarding=enabled

или сразу через ключ в реестре:

Key name: HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesTcpipParameters
Value Name: IpEnableRouter
Data Type: REG_DWORD
Value: 1

Полезные ссылки:
Balancing Act: Dual-NIC Configuration with Windows Server 2008 NLB Clusters

e2010 В Exchange 2010 при удалении сообщений из почтового ящика пользователя сообщение фактически не удаляется, а перемещается в скрытую папку Recoverable Items. Письмо хранится в этой папке ещё некоторое время (по умолчанию 14 дней), после чего специальным ассистентом перемещается в другую скрытую папку Purge, откуда уже по возможности почтовым сервером письмо окончательно удаляется. Фактически, пользователь не имеет права ничего удалять из своего почтового ящика. Все операции, связанные с удалением производятся почтовой системой по истечении сроков хранения данных. Иногда это приводит к забавным случаям.

Пример: у нас имеется почтовый ящик, который принимает большой объём входящей корреспонденции. Специальный робот через pop3 забирает эту почту (и фактически удаляет из почтового ящика). В некоторый момент робот начинает ругаться на то, что он не может с сервера удалить сообщение. Статистика по почтовому ящику показывает:

Get-Mailbox mailbox | Get-MailboxStatistics | fl TotalDeletedItemSize

TotalDeletedItemSize    : 30 GB

Стандартная квота на размер папки, в которую перемещаются сообщения после удаления пользователем составляет 30 Гб. При превышении этой квоты пользователь ничего не сможет удалить из почтового ящика, пока соответствующий ассистент на сервере не удалит сообщения с истёкшим временем хранения. Но есть лазейка для администратора – он может специальным командлетом почистить сообщения из папки Recoverable Items:

Search-Mailbox -Identity mailbox -SearchDumpsterOnly -DeleteContent

Ключ SearchDumpsterOnly говорит о том, что поиск производится только по Recoverable Items. Ключ DeleteContent указывает на необходимость удаления того, что найдено в Recoverable Items.

Для того, чтобы избежать повторения ситуации есть два способа – увеличить лимит на папку Recoverable Items, либо снизить время хранения в ней сообщений.

Первый вариант:

Set-Mailbox mailbox -RecoverableItemsQuota 50GB -UseDatabaseQuotaDefaults $false

Второй вариант (например, уменьшаем срок хранения до одного дня):

Set-Mailbox mailbox -UseDatabaseRetentionDefaults $false -RetainDeletedItemsFor 1.00:00:00 

Полезные ссылки:
Clean Up the Recoverable Items Folder
Understanding Recoverable Items

MVP_640x255

Картинка нажимабельна. Из спикеров заострю внимание на Олеге Крылове, который будет палить ТЗ привезённые с MEC 2014. Я, к сожалению, время проведения мероприятия упустил, так что Олег будет отдуваться там один.