Включил очистку DNS на Windows Server 2025 — и пропала A-запись сервера со статическим IP
Эта статья — для администратора, который включил автоматическую очистку устаревших DNS-записей, а после очередного цикла обнаружил: сервер доступен по IP, но не находится по имени. Я разберу, почему машина с вручную заданным адресом получает динамическую DNS-запись, как Windows Server вычисляет её возраст, какие события искать в журналах и в каком порядке включать scavenging в существующей зоне. В основе — обезличенный случай IT-стартапа «Кодекс-Лаб», 15 разработчиков: одна агрессивная настройка удалила 1417 записей и на сорок минут остановила внутренние сервисы.
Статический IP и статическая DNS-запись — разные вещи
Звонок в 9:40: «Сервис не запускается, пишет, что сервер не найден». По IP сервер отвечает, порт приложения открыт. По имени — ошибка разрешения. Открываем DNS Manager и видим, что A-записи сервера в зоне нет. Накануне администратор включил автоматическую очистку устаревших записей, но сначала не связал два события: «У сервера же статический IP, значит scavenging его не касается». Именно эта предпосылка и была ошибочной.
Статический IP описывает конфигурацию сетевого интерфейса: адрес указан вручную и не выдан DHCP. Статическая DNS-запись описывается совсем другим признаком — нулевой отметкой времени. Windows-компьютер с вручную назначенным IP по умолчанию всё равно пытается динамически зарегистрировать A- и PTR-записи. DNS Client выполняет периодическое обновление регистрации каждые 24 часа, а также реагирует на запуск компьютера, изменение адреса и принудительный вызов регистрации.
Когда запись создаётся посредством dynamic DNS, сервер присваивает ей ненулевой timestamp. Такая запись участвует в aging и может быть удалена scavenging независимо от того, пришёл адрес по DHCP или был введён администратором. Microsoft прямо относит к зоне риска Windows-машины со статически настроенными адресами, которые динамически регистрируются в DNS. Записи, созданные вручную с нулевым timestamp, очистка не рассматривает, пока последующее разрешённое динамическое обновление снова не сделает отметку времени ненулевой.
Проверка в графической консоли занимает несколько секунд. В DNS Manager нужно включить View → Advanced, открыть свойства записи и посмотреть флажок Delete this record when it becomes stale. Установленный флажок означает, что запись имеет отметку времени и может стареть. Снятие флажка обнуляет timestamp, однако само по себе не запрещает машине позднее выполнить авторизованное динамическое обновление и снова назначить записи ненулевую отметку.
В PowerShell у объектов, возвращаемых Get-DnsServerResourceRecord, статическая запись обычно отображается с пустым свойством Timestamp, тогда как у динамической видны дата и час. Внутри DNS нулевой timestamp означает защиту от scavenging. Отметки динамических записей имеют часовую гранулярность; при назначении времени через интерфейс значение округляется вниз до текущего часа. Поэтому в расчётах я беру значение из самой записи, а не фактическую минуту, когда клиент отправил обновление.
- Статический IP — способ настройки сетевого интерфейса; он ничего не говорит о timestamp в DNS.
- Нулевой timestamp — запись не является кандидатом на scavenging.
- Дата и час в Timestamp — запись динамическая и может быть удалена после истечения интервалов.
- Флажок Delete this record when it becomes stale управляет отметкой времени, но не запрещает будущие динамические обновления.
- Windows по умолчанию обновляет регистрацию A- и PTR-записей каждые 24 часа, если DNS-регистрация интерфейса включена.
Разбор случая: IT-стартап «Кодекс-Лаб», 15 разработчиков
В IT-стартапе «Кодекс-Лаб», где работают 15 разработчиков, использовалась AD-интегрированная зона corp.codex-lab.test. Два контроллера домена работали на Windows Server 2025 Standard: CDL-DC01 с адресом 10.20.0.11 и CDL-DC02 с адресом 10.20.0.12. Сервер приложений CDL-AP01, сервер СУБД CDL-SQL01, файловый сервер и несколько узлов сборки имели адреса, заданные вручную. Максимальная аренда DHCP составляла восемь дней.
Небольшая численность команды здесь обманчива. Разработчики регулярно создавали тестовые виртуальные машины, временные стенды и одноразовые агенты сборки. За девять лет в зоне накопилось около 2600 A-записей, хотя постоянно работающих систем было гораздо меньше. Мусор действительно мешал разбору зоны, поэтому желание включить очистку было разумным. Ошибкой оказался не сам scavenging, а выбранные интервалы и отсутствие предварительной инвентаризации.
Администратор включил автоматический scavenging, задал No-refresh interval равным двум часам, Refresh interval — тоже двум часам, а период запуска очистки — одним суткам. Затем применил серверные значения ко всем существующим AD-интегрированным зонам. Параметр -ApplyOnAllZones существует и делает именно это: распространяет настройки aging на зоны сервера. Для боевой среды такая команда без предварительного просмотра опасна.
# Антипример: интервалы слишком короткие для обычной регистрации Windows
Set-DnsServerScavenging -ComputerName "CDL-DC01" `
-ScavengingState $true `
-NoRefreshInterval 02:00:00 `
-RefreshInterval 02:00:00 `
-ScavengingInterval 1.00:00:00 `
-ApplyOnAllZones `
-PassThruПоследний разрешённый refresh записи CDL-AP01 прошёл в понедельник в 06:12, а в timestamp осталось 06:00. При двухчасовых интервалах запись стала устаревшей, когда текущее время стало больше 10:00: timestamp плюс два часа No-refresh плюс два часа Refresh. Следующий серверный цикл очистки прошёл во вторник в 02:15 и удалил запись. Периодическая регистрация раз в 24 часа не успела защитить её: четырёхчасовое окно жизни было короче стандартного интервала клиента.
В журнале DNS Server появилось событие 2501 с числом 1417. Утром не разрешались имена сервера приложений, СУБД, файлового сервера, принт-сервера, NAS и терминального узла. Часть записей контроллеров домена восстановилась быстрее: Netlogon регистрирует контроллерные SRV, CNAME и некоторые A-записи при запуске службы и затем раз в час. Полагаться на такое самовосстановление всё равно нельзя — набор регистраций DNS Client и Netlogon различается.
Я сначала выключил автоматическую очистку на обоих DNS-серверах, а уже затем восстанавливал имена. На Windows-серверах принудительно запустил регистрацию, после чего проверил результат непосредственно на обоих авторитетных DNS-серверах. Если запись не возвращалась из-за прав или отключённой регистрации интерфейса, создавал её вручную и отдельно решал, должна ли она в дальнейшем оставаться статической.
Set-DnsServerScavenging -ComputerName "CDL-DC01" -ScavengingState $false -PassThru
Set-DnsServerScavenging -ComputerName "CDL-DC02" -ScavengingState $false -PassThruipconfig /registerdnsResolve-DnsName "CDL-AP01.corp.codex-lab.test" -Server 10.20.0.11
Resolve-DnsName "CDL-AP01.corp.codex-lab.test" -Server 10.20.0.12Простой внутренних приложений составил около сорока минут. Примерно 900 из 1417 удалённых записей действительно относились к выключенным стендам и старым машинам. Остальные требовали проверки или восстановления. Цифры хорошо показывают проблему агрессивной очистки: она способна одновременно удалить настоящий мусор и рабочую инфраструктуру, поэтому большое число удалений само по себе не доказывает, что настройка была удачной.
- Симптом инцидента: сервис доступен по IP, но имя не разрешается, а A-записи нет на авторитетных серверах.
- Первое действие — остановить автоматический scavenging на каждом DNS-сервере, где он включён.
- Затем нужно запустить регистрацию на пострадавших Windows-машинах и проверить ответ каждого авторитетного сервера.
- Событие 2501 подтверждает цикл, в котором были удалены записи; 2502 означает, что цикл прошёл без удалений.
- Большое число удалённых записей требует аудита, а не автоматического вывода об успешной уборке.
Арифметика устаревания и границы интервалов
Условие устаревания у Windows DNS формальное: текущая дата и время сервера должны быть больше суммы timestamp, No-refresh interval и Refresh interval. Равенства недостаточно — в документации используется строгое сравнение. После достижения этой границы запись лишь становится кандидатом на удаление. Она исчезнет, когда сервер, которому разрешено чистить зону, выполнит подходящий цикл scavenging и пройдут остальные защитные проверки.
При стандартных значениях семь дней No-refresh и семь дней Refresh запись становится устаревшей после четырнадцати дней без принятого обновления. Если период автоматического scavenging также равен семи дням, удаление обычно произойдёт в одном из последующих циклов. Верхняя оценка при стабильном расписании составляет примерно 21 день от timestamp: четырнадцать дней старения и до семи дней ожидания цикла. Перезапуск службы DNS сбрасывает расписание автоматической очистки, поэтому календарное время может сдвинуться.
No-refresh — это не период, когда запрещены любые изменения. DNS-сервер подавляет refresh, то есть обновление, при котором имя и данные записи остаются прежними, а клиент хочет изменить только timestamp. Это уменьшает репликационный трафик в AD. Настоящий update, например изменение IP-адреса записи, принимается и во время No-refresh, если запрос разрешён политикой динамического обновления.
После No-refresh начинается Refresh interval. В этом окне сервер разрешает обновить timestamp записи с неизменившимися данными. Окно должно быть достаточно длинным для нескольких попыток клиента: одна неудачная регистрация из-за перезагрузки, сетевого сбоя или проблем репликации не должна превращать рабочий узел в кандидата на удаление. Именно поэтому двухчасовые интервалы из случая «Кодекс-Лаб» были непригодны.
Microsoft в статье по устранению неполадок приводит обязательную проверку: сумма Refresh и No-refresh должна быть не меньше максимальной аренды DHCP. Для Windows-машин с вручную заданными адресами нужно дополнительно учитывать стандартное периодическое обновление раз в 24 часа. Комбинация интервалов короче суток опасна для такой записи. Я оставляю многократный запас, а не подгоняю границу ровно к 24 часам.
# Выполняется на DHCP-сервере или с указанием его имени
Get-DhcpServerv4Scope -ComputerName "CDL-DHCP01" |
Select-Object ScopeId, Name, LeaseDuration
# Серверные настройки scavenging
Get-DnsServerScavenging -ComputerName "CDL-DC01"
Get-DnsServerScavenging -ComputerName "CDL-DC02"
# Настройки aging конкретной зоны
Get-DnsServerZoneAging -ComputerName "CDL-DC01" `
-Name "corp.codex-lab.test"Для максимальной аренды восемь дней в этом случае я выбрал No-refresh четыре дня, Refresh семь дней и серверный период scavenging семь дней. Сумма составляет одиннадцать дней и превышает аренду. Семидневное окно Refresh оставляет несколько возможностей для суточной перерегистрации. Это не универсальный стандарт: Microsoft отдельно предупреждает, что единого набора чисел для любой организации нет. Значения выбирают по реальным арендам, поведению клиентов и допустимому сроку хранения мусора.
В справке Set-DnsServerScavenging для параметров -NoRefreshInterval и -RefreshInterval указан максимум 8760 часов, но рядом в скобках ошибочно написано seven days. 8760 часов — это 365 суток. У зонального командлета Set-DnsServerZoneAging тот же максимум описан уже без ошибочной расшифровки. На эту подпись нельзя опираться как на семидневное ограничение; сами выбранные значения всё равно стоит держать консервативными.
- Запись устарела, когда timestamp + No-refresh + Refresh строго меньше текущего времени DNS-сервера.
- Устаревание не равно немедленному удалению: запись ждёт следующего допустимого цикла scavenging.
- При значениях 7 + 7 дней граница устаревания наступает через 14 дней.
- С периодом очистки 7 дней верхняя оценка при стабильном расписании — около 21 дня от timestamp.
- Refresh + No-refresh должны быть не меньше максимальной аренды DHCP.
- Для стандартной суточной регистрации статически адресованных Windows-машин сумма интервалов короче 24 часов небезопасна.
Три обязательных уровня и один сервер очистки
Автоматическое удаление возможно только при одновременном выполнении условий на трёх уровнях. У самой записи должен быть ненулевой timestamp. На зоне должен быть включён aging. На конкретном DNS-сервере должен быть включён автоматический scavenging. Кроме того, запись должна преодолеть возрастную границу, зона — защитное время запуска, а сервер — проверки состояния зоны и репликации.
Зональные настройки важнее глобальных значений сервера. Get-DnsServerScavenging показывает серверное состояние, период очистки и интервалы по умолчанию, но судьбу записи определяют значения зоны, которые возвращает Get-DnsServerZoneAging. Если два вывода расходятся, для расчёта возраста нужно брать No-refresh и Refresh из конкретной зоны.
Есть дополнительное ограничение ScavengeServers: список IP-адресов DNS-серверов, которым разрешено чистить зону. Если список не задан, scavenging может выполнить любой авторитетный первичный сервер, размещающий зону. Microsoft рекомендует один сервер на зону. Так проще предсказывать циклы и искать события; для AD-интегрированной зоны сделанное им удаление всё равно распространяется посредством репликации.
Я включаю aging сначала на зоне, а автоматическую очистку на серверах оставляю выключенной. При включении aging Windows рассчитывает защитное время The zone can be scavenged after: текущий час плюс один Refresh interval. Оно также пересчитывается при загрузке scavenging-enabled primary zone, изменении соответствующего флажка, включении динамических обновлений или возобновлении зоны. Защитный период даёт клиентам время обновить отметки, а AD — передать изменения.
# 1. Настраиваем aging зоны и разрешаем очистку только CDL-DC01
Set-DnsServerZoneAging -ComputerName "CDL-DC01" `
-Name "corp.codex-lab.test" `
-Aging $true `
-NoRefreshInterval 4.00:00:00 `
-RefreshInterval 7.00:00:00 `
-ScavengeServers 10.20.0.11 `
-PassThru
# 2. На фазе наблюдения автоматическая очистка выключена везде
Set-DnsServerScavenging -ComputerName "CDL-DC01" `
-ScavengingState $false -PassThru
Set-DnsServerScavenging -ComputerName "CDL-DC02" `
-ScavengingState $false -PassThru
# 3. После проверки включаем её только на выбранном сервере
Set-DnsServerScavenging -ComputerName "CDL-DC01" `
-ScavengingState $true `
-ScavengingInterval 7.00:00:00 `
-PassThruЗональная настройка AD-интегрированной зоны реплицируется вместе с зоной, а серверный флажок автоматического scavenging является локальным для каждого DNS-сервера. Поэтому недостаточно посмотреть один контроллер и предположить, что остальные настроены так же. Я опрашиваю каждый DNS-сервер отдельно и сохраняю вывод до любых изменений.
Ручной запуск через DNS Manager или Start-DnsServerScavenging не обходит защитные механизмы. Команда полезна для управляемой проверки, но не превращает свежую запись в устаревшую и не отменяет The zone can be scavenged after. Microsoft отдельно отмечает нюанс: в одном из сценариев устранения неполадок немедленное ручное удаление кандидатов ожидается только после того, как на этом сервере хотя бы раз прошёл автоматический цикл.
- Запись: ненулевой timestamp и истёкшая сумма No-refresh и Refresh.
- Зона: Aging включён и наступило The zone can be scavenged after.
- Сервер: автоматический scavenging включён, подошло время очередного цикла.
- ScavengeServers: выбранному DNS-серверу разрешено чистить эту зону.
- Для сопровождения достаточно одного сервера очистки на AD-интегрированную зону.
- Зональные интервалы имеют приоритет над глобальными серверными значениями.
Инвентаризация зоны до первого удаления
Перед включением я выгружаю A-записи и сортирую их по timestamp. Это сразу показывает критичные серверы с динамическими отметками, старые записи и узлы, которые никогда не обновлялись. Отдельно просматриваю AAAA, CNAME, PTR и SRV: инцидент может затронуть не только A-записи, хотя в первом проходе удобнее начать с адресов IPv4.
Команда ниже не изменяет DNS. Статические записи окажутся в начале списка с пустым Timestamp, а затем пойдут динамические от самых старых к новым. Format-Table годится для просмотра в консоли, но для доказательной базы я сохраняю отдельный CSV без форматирующего командлета: объекты после Format-Table уже неудобно экспортировать и обрабатывать.
$zoneName = "corp.codex-lab.test"
$dnsServer = "CDL-DC01"
$records = Get-DnsServerResourceRecord `
-ComputerName $dnsServer `
-ZoneName $zoneName `
-RRType A |
Select-Object HostName,
@{Name='IP'; Expression={$_.RecordData.IPv4Address.IPAddressToString}},
Timestamp,
TimeToLive
$records | Sort-Object Timestamp | Format-Table -AutoSize
$records | Export-Csv -Path ".\dns-a-records-before.csv" `
-NoTypeInformation -Encoding UTF8Второй проход — sanity check из процедуры Microsoft. Нужно найти динамические записи, timestamp которых старше суммы зональных интервалов. В нашем варианте порог равен одиннадцати дням. Фильтр должен исключать статические записи: пустой Timestamp не означает «очень старая», это отдельное состояние, не участвующее в aging.
$zoneName = "corp.codex-lab.test"
$dnsServer = "CDL-DC01"
$aging = Get-DnsServerZoneAging `
-ComputerName $dnsServer `
-Name $zoneName
$limit = (Get-Date).Subtract(
$aging.NoRefreshInterval + $aging.RefreshInterval
)
Get-DnsServerResourceRecord `
-ComputerName $dnsServer `
-ZoneName $zoneName `
-RRType A |
Where-Object {
$null -ne $_.Timestamp -and $_.Timestamp -lt $limit
} |
Select-Object HostName, Timestamp,
@{Name='IP'; Expression={$_.RecordData.IPv4Address.IPAddressToString}} |
Sort-Object TimestampКаждую найденную запись я раскладываю в одну из категорий. Выключенная тестовая машина — ожидаемый кандидат. Работающая машина со старым timestamp — неисправность регистрации, прав или репликации. Запись инфраструктуры, которую решили обслуживать вручную, — кандидат на нулевой timestamp и запрет саморегистрации. Неизвестное имя нельзя автоматически считать мусором: сначала проверяются CMDB, гипервизоры, DHCP, владельцы приложений и журналы.
Инвентаризацию нужно делать по каждому типу зоны, где включается aging. Прямая и обратная зоны настраиваются независимо; -CreatePtr при создании A-записи сработает только при наличии подходящей обратной зоны и разрешённых изменениях. Также не стоит забывать о нескольких AD replication scopes: зона может реплицироваться в домене, лесу или отдельном application directory partition.
До изменения настроек я дополнительно проверяю здоровье AD. Для AD-интегрированной DNS-зоны расхождение данных между контроллерами превращает очистку в лотерею. repadmin /replsummary даёт сводку, а repadmin /showrepl показывает входящие связи и ошибки конкретного контроллера. После этого я запрашиваю критичное имя напрямую у каждого авторитетного DNS-сервера, чтобы исключить влияние клиентского кэша.
repadmin /replsummary
repadmin /showrepl CDL-DC01
repadmin /showrepl CDL-DC02Resolve-DnsName "CDL-SQL01.corp.codex-lab.test" -Server 10.20.0.11
Resolve-DnsName "CDL-SQL01.corp.codex-lab.test" -Server 10.20.0.12- Выгрузить записи до изменения aging и сохранить результат в CSV.
- Отдельно найти динамические записи старше суммы No-refresh и Refresh.
- Объяснить назначение каждого старого имени до включения удаления.
- Проверить не только A, но и связанные AAAA, PTR, CNAME и SRV-записи.
- Проверить репликацию AD и ответы всех авторитетных DNS-серверов.
- Не путать клиентский кэш DNS с состоянием авторитетной зоны.
События 2501, 2502 и аудит по каждой записи
Основной журнал DNS Server отвечает на вопрос, состоялся ли цикл. Событие 2501 означает, что scavenging прошёл и удалил одну или несколько записей. Событие 2502 означает, что цикл завершился без удаления. Время последнего события плюс настроенный ScavengingInterval позволяет предсказать следующую попытку при условии, что служба DNS не перезапускалась и расписание не было изменено.
Фраза «запись удалится через No-refresh + Refresh + ScavengingInterval» годится только как верхняя оценка при стабильном графике. Для конкретного имени я сначала вычисляю момент eligibility по timestamp, затем нахожу первый плановый цикл после этой границы. Если сумма в точности равна времени цикла, строгое условие ещё не выполнено; удаление может сдвинуться на следующий цикл.
Get-WinEvent -ComputerName "CDL-DC01" `
-FilterHashtable @{LogName='DNS Server'; Id=2501,2502} `
-MaxEvents 20 |
Select-Object TimeCreated, Id, MessageДля ответа на вопрос «что именно удалилось» нужен журнал аудита Microsoft-Windows-DNSServer/Audit. В нём событие 521 относится к записи, удалённой scavenging, 552 отмечает начало цикла, 554 — его завершение, 567 содержит сведения о серверах, которым разрешено чистить зону. Эти номера прямо перечислены в официальной статье Microsoft по диагностике DNS scavenging.
Get-WinEvent -ComputerName "CDL-DC01" `
-FilterHashtable @{
LogName='Microsoft-Windows-DNSServer/Audit'
Id=521,552,554,567
} `
-MaxEvents 2000 |
Select-Object TimeCreated, Id, MessageЯ не предполагаю, что аудит уже включён и хранит нужную глубину истории. Это проверяется до внедрения, как и размер журнала, политика ротации и централизованный сбор. Если аудит активировали после инцидента, он не восстановит прошлые события. Тогда остаются событие 2501, резервные выгрузки зоны, история AD и сопоставление с конфигурацией приложений.
Отсутствие 2501 и 2502 при включённой настройке не всегда означает сломанный таймер. DNS-сервер защищается от очистки устаревшей копии AD-интегрированной зоны: раздел с зоной должен синхронизироваться хотя бы с одним партнёром после запуска службы и в пределах требуемого интервала. Если бывший контроллер домена остался в топологии и репликация смотрит на него, сначала исправляют AD, а не заставляют scavenging стартовать вручную.
nltest /dclist:corp.codex-lab.testrepadmin /replsummaryПосле первого 2501 я всегда читаю записи 521, а не ограничиваюсь числом в основном журнале. В случае «Кодекс-Лаб» именно поимённый разбор отделил примерно 900 старых тестовых объектов от рабочих серверов и спорных записей. Пятнадцать минут проверки сразу после цикла обходятся дешевле, чем восстановление имён по звонкам пользователей.
- 2501 — цикл завершился и удалил как минимум одну запись.
- 2502 — цикл завершился без удаления записей.
- 521 — конкретная запись, удалённая scavenging.
- 552 и 554 — начало и завершение цикла в журнале аудита.
- 567 — сведения о назначенных зоне scavenging servers.
- Перезапуск DNS Server сбрасывает расписание автоматической очистки.
Как зафиксировать критичную запись и не сломать права
Для существующей записи можно открыть свойства в расширенном режиме DNS Manager и снять Delete this record when it becomes stale. Timestamp станет нулевым. Другой вариант — удалить запись и создать её заново вручную без параметра -AgeRecord: этот параметр как раз указывает DNS-серверу назначить отметку времени. Перед удалением я сохраняю имя, адрес, TTL, связанные PTR и разрешения, потому что пересоздание меняет объект и его владельца.
# Пример для заранее согласованного окна изменений
Remove-DnsServerResourceRecord -ComputerName "CDL-DC01" `
-ZoneName "corp.codex-lab.test" `
-Name "CDL-AP01" `
-RRType A `
-Force
# Без -AgeRecord: создаётся запись с нулевым timestamp
Add-DnsServerResourceRecordA -ComputerName "CDL-DC01" `
-ZoneName "corp.codex-lab.test" `
-Name "CDL-AP01" `
-IPv4Address 10.20.0.21 `
-CreatePtr `
-PassThruПараметр -CreatePtr не гарантирует успех при любой конфигурации. Для него должна существовать подходящая reverse lookup zone, а сервер и учётная запись должны иметь право создать PTR. После команды я отдельно проверяю прямой и обратный ответы. Если обратной зоны нет или PTR в этой сети не нужен, параметр лучше не указывать и не создавать ложное ощущение завершённой работы.
В безопасной AD-интегрированной зоне ручное пересоздание меняет владельца объекта: им обычно становится административная учётная запись, выполнившая операцию. Компьютер может потерять право обновлять запись. Пока timestamp равен нулю и адрес действительно обслуживается вручную, это может соответствовать замыслу. Но если позднее кто-то включит для записи aging, клиент не обязательно сможет освежить её, и она снова станет кандидатом на удаление.
Есть и обратная ловушка. Снятие флажка старения не является запретом dynamic DNS. Официальная документация предупреждает, что разрешённое последующее динамическое обновление способно назначить ненулевой timestamp снова. Если A-запись должна оставаться полностью ручной, я выключаю регистрацию адреса на нужном интерфейсе и документирую это решение. Сначала получаю реальные имена интерфейсов: предполагать, что адаптер называется Ethernet0, нельзя.
Get-NetAdapter | Select-Object Name, InterfaceDescription, Status
Set-DnsClient -InterfaceAlias "Ethernet0" `
-RegisterThisConnectionsAddress $false `
-PassThruОтключение RegisterThisConnectionsAddress действует на конкретный интерфейс. На многосетевом сервере нужно проверить каждый адаптер, connection-specific suffix и роль Netlogon. Для контроллеров домена обычная настройка DNS Client не заменяет отдельного анализа регистраций Netlogon: служба регистрирует контроллерные записи по собственным правилам. Массово отключать DNS-регистрацию на DC ради защиты от scavenging нельзя.
Команда dnscmd /ageallrecords особенно опасна в существующей зоне. Она ставит текущее время на записи без timestamp и обновляет timestamp у уже динамических записей. NS, SOA и WINS при этом исключены, но остальные честные статические записи становятся размеченными для aging. Операция не имеет массовой обратной команды: возвращать нулевой timestamp придётся для выбранных записей отдельно. Поэтому я не использую её как способ «подготовить зону к очистке».
Иногда лучше отделить стабильное имя приложения от имени узла. Например, статический CNAME или отдельная статическая A-запись сервиса может использоваться в конфигурации приложения, тогда как системное имя Windows обслуживается динамически. Это снижает связь между жизненным циклом машины и пользовательским адресом, но требует чёткого владельца записи и регламента смены целевого узла.
- Снятие Delete this record when it becomes stale обнуляет timestamp, но не блокирует будущий DDNS-update.
- `Add-DnsServerResourceRecordA` без `-AgeRecord` создаёт A-запись без отметки времени.
- После пересоздания нужно проверить владельца и ACL записи в AD-интегрированной зоне.
- `-CreatePtr` требует существующей обратной зоны и отдельной проверки результата.
- Для полностью ручной A-записи отключают регистрацию на нужных интерфейсах и документируют изменение.
- `dnscmd /ageallrecords` нельзя запускать по боевой зоне без поимённого плана последствий.
Регламент внедрения: четыре-пять недель без спешки
Официальная процедура Microsoft для существующей зоны при стандартных интервалах занимает четыре-пять недель: около двух недель на sanity check и ещё две-три недели на фазу включения и наблюдения. Это не бюрократическая пауза, а время, за которое рабочие клиенты должны показать нормальный цикл обновления. Укорачивать интервалы ради ускорения проверки бессмысленно: тест перестанет воспроизводить будущую боевую конфигурацию.
На нулевой неделе я фиксирую исходные настройки всех DNS-серверов, выгружаю записи, проверяю репликацию и выбираю один scavenging server. Затем включаю aging только на нужной зоне, задаю рассчитанные интервалы, но оставляю автоматическую очистку выключенной на всех серверах. Массовое применение к зонам в этот момент не использую: прямая, обратная и служебные зоны могут требовать разных решений.
После истечения суммы No-refresh и Refresh провожу sanity check. Каждая рабочая динамическая запись должна иметь свежий timestamp. Для старых записей проверяю регистрацию, владельца, ACL, состояние машины и AD-репликацию. Инфраструктурные имена классифицирую заранее: ручная статика, управляемая динамика или стабильный сервисный псевдоним. Пока остаётся хотя бы одна необъяснимая старая запись, дальше не иду.
Затем включаю автоматический scavenging только на CDL-DC01 с семидневным периодом и создаю тестовую A-запись с -AgeRecord. Для теста беру адрес из документального диапазона TEST-NET-1, чтобы он не совпал с реальным узлом. Запись никто не должен обновлять. По её фактическому timestamp, зональным интервалам и журналу 2501/2502 вычисляю первый цикл, когда условие удаления станет истинным.
Add-DnsServerResourceRecordA -ComputerName "CDL-DC01" `
-ZoneName "corp.codex-lab.test" `
-Name "scavenging-test" `
-IPv4Address 192.0.2.123 `
-AgeRecord `
-TimeToLive 00:05:00 `
-PassThru
Get-DnsServerResourceRecord -ComputerName "CDL-DC01" `
-ZoneName "corp.codex-lab.test" `
-Name "scavenging-test" `
-RRType A |
Select-Object HostName, Timestamp, TimeToLiveTTL в пять минут влияет только на кэширование ответа и не ускоряет aging. Это важное различие: TTL и интервалы scavenging решают разные задачи. Тестовая запись с No-refresh четыре дня и Refresh семь дней не станет кандидатом раньше чем через одиннадцать дней от своего timestamp, а удаление произойдёт в первом допустимом цикле после этой границы.
В первые две-три недели после включения я просматриваю каждое событие 2501 и соответствующие записи 521. Одновременно слежу за 4013, 4515 и 4521: они могут указывать на ожидание инициализации AD DS, конфликтующую зону или ошибку загрузки AD-интегрированной зоны. Один успешный тест ещё не доказывает здоровье репликации и правильность всех владельцев.
Если времени мало, минимальный набор всё равно нельзя сокращать до одной галки. Нужно опросить каждый DNS-сервер через Get-DnsServerScavenging, получить параметры зоны, узнать максимальную аренду DHCP, найти критичные записи с ненулевым timestamp и проверить репликацию. Эти действия не удаляют данные и обычно занимают меньше времени, чем восстановление одной потерянной записи СУБД.
Идеальная чистота зоны не является целью сама по себе. Несколько тысяч старых записей увеличивают объём данных и затрудняют сопровождение, но агрессивная очистка критичного имени вызывает немедленный простой. Я предпочитаю медленное, предсказуемое удаление с аудитом. Scavenging — детерминированный механизм: если известны timestamp, два зональных интервала, защитное время и график сервера, результат можно рассчитать и проверить.
Для «Кодекс-Лаб» итоговая конфигурация осталась такой: No-refresh четыре дня, Refresh семь дней, автоматический цикл раз в семь дней на одном сервере. Критичные сервисные имена получили документированную статическую регистрацию, а временные машины сохранили динамические записи. Зона очистилась не за ночь, зато повторного исчезновения рабочих имён не было.
- Неделя 0: инвентаризация, проверка AD, выбор одного scavenging server и фиксация исходных настроек.
- Неделя 0: включение aging только на нужной зоне при выключенной автоматической очистке серверов.
- После суммы интервалов: sanity check и объяснение каждой старой динамической записи.
- После проверки: защита критичных имён и включение scavenging на одном сервере.
- Следующие две-три недели: тестовая запись, события 2501/2502, аудит 521 и контроль репликации.
- После стабилизации: регулярный просмотр удалений и повторная проверка после изменения DHCP, зон или топологии DC.
Частые вопросы
Почему DNS-запись сервера удалилась, хотя IP был задан вручную?
Способ назначения IP не определяет тип DNS-записи. Windows-машина с вручную заданным адресом по умолчанию динамически регистрирует A- и PTR-записи и обновляет регистрацию каждые 24 часа. Если у записи появился ненулевой timestamp, aging считает её динамической. При слишком короткой сумме No-refresh и Refresh она успевает устареть до следующей регистрации и удаляется в очередном цикле.
Как быстро найти записи, которым угрожает scavenging?
Получите записи через `Get-DnsServerResourceRecord` и проверьте Timestamp. Пустое значение соответствует статической записи, а дата и час — динамической. Затем сопоставьте динамические имена со списком контроллеров домена, СУБД, серверов приложений, гипервизоров, NAS и других критичных систем. Отдельно найдите timestamp старше суммы зональных No-refresh и Refresh: такие записи требуют объяснения до включения очистки.
Какие интервалы выбрать при максимальной аренде DHCP восемь дней?
Универсального набора нет, но сумма Refresh и No-refresh должна быть не меньше максимальной аренды. В разобранной сети использованы No-refresh четыре дня и Refresh семь дней: сумма равна одиннадцати дням, а семидневное окно Refresh допускает несколько суточных регистраций Windows. Период scavenging установлен в семь дней. Перед переносом этих значений нужно проверить аренды и поведение клиентов именно в вашей сети.
Можно ли включить scavenging на всех контроллерах домена?
Технически можно, но Microsoft рекомендует один сервер очистки на зону. AD реплицирует удаление остальным DNS-серверам, а один исполнитель оставляет единый график циклов и единый основной журнал. Ограничение задаётся параметром `-ScavengeServers` командлета `Set-DnsServerZoneAging` или командой `dnscmd /zoneresetscavengeservers`.
Записи уже удалены. Каков безопасный порядок восстановления?
Сначала выключите автоматический scavenging на каждом DNS-сервере, где он активен. Затем на пострадавших Windows-машинах выполните `ipconfig /registerdns` и проверьте имя напрямую на всех авторитетных серверах через `Resolve-DnsName -Server`. Не вернувшиеся записи восстановите вручную после проверки адресов, PTR и прав. Только затем исправляйте интервалы и запускайте полноценную инвентаризацию.
Достаточно ли снять Delete this record when it becomes stale?
Флажок обнулит timestamp и исключит запись из текущего scavenging, но не запретит последующее авторизованное динамическое обновление. Оно может снова назначить timestamp. Для полностью ручной записи нужно согласовать права, владельца и регистрацию каждого сетевого интерфейса; при необходимости применить `Set-DnsClient -RegisterThisConnectionsAddress $false` к правильно выбранному интерфейсу.
TTL влияет на срок удаления записи?
Нет. TTL определяет, сколько времени ответ может храниться в кэше DNS-клиента или резолвера. Возраст для scavenging рассчитывается по timestamp, No-refresh и Refresh, а фактическое удаление зависит от циклов сервера и защитного времени зоны. Маленький TTL не заставит запись устареть быстрее.
Изменился ли механизм в Windows Server 2025 по сравнению с 2019 и 2022?
Базовая модель та же: ненулевой timestamp, зональные No-refresh и Refresh, серверный период scavenging и защитные проверки. Официальная концептуальная статья Microsoft распространяется на Windows Server 2016, 2019, 2022 и 2025. При миграции риск чаще связан с повторной настройкой ролей или массовым применением параметров, а не с новой формулой Windows Server 2025.
Источники
- Microsoft Learn — DNS aging and scavenging — Официальное описание механизма для Windows Server 2016, 2019, 2022 и 2025: условия удаления, нулевой и ненулевой timestamp, стандартные интервалы 7 + 7 дней, минимальный период scavenging 1 час, формула устаревания, защитное время зоны и рекомендация использовать один сервер очистки. https://learn.microsoft.com/en-us/windows-server/networking/dns/aging-scavenging
- Microsoft Learn — Configure DNS aging and scavenging — Официальная инструкция по включению aging и scavenging, защите статических записей, использованию Set-DnsServerScavenging, Set-DnsServerZoneAging и Start-DnsServerScavenging, а также мониторингу событий 2501 и 2502. https://learn.microsoft.com/en-us/windows-server/networking/dns/configure-aging-scavenging
- Microsoft Learn — Troubleshoot DNS scavenging issues — Разделы Fundamental checks и Scenarios: три уровня настройки, статические IP с динамической регистрацией раз в 24 часа, условие Refresh + No-refresh >= maximum DHCP lease, приоритет настроек зоны, события 2501/2502 и аудит 521, 552, 554, 567, проверки репликации. https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/troubleshoot-dns-scavenging-issues
- Microsoft Learn — DNS scavenging setup — Процедура безопасного внедрения в существующей AD-интегрированной зоне: свойства записи, предупреждение о dnscmd /ageallrecords, The zone can be scavenged after, один сервер очистки, sanity check и срок четыре-пять недель при стандартных интервалах. https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/dns-scavenging-setup
- Microsoft Learn — Set-DnsServerScavenging (DnsServer, Windows Server 2025) — Официальный синтаксис параметров -ScavengingState, -RefreshInterval, -NoRefreshInterval, -ScavengingInterval, -ApplyOnAllZones, -ComputerName и -PassThru; для ScavengingInterval документированы диапазон от 0 до 365 суток и формат TimeSpan. https://learn.microsoft.com/en-us/powershell/module/dnsserver/set-dnsserverscavenging?view=windowsserver2025-ps
- Microsoft Learn — Set-DnsServerZoneAging (DnsServer, Windows Server 2025) — Официальный синтаксис зональных параметров -Aging, -NoRefreshInterval, -RefreshInterval и -ScavengeServers; указано, что без заданного списка зону может чистить любой авторитетный первичный DNS-сервер. https://learn.microsoft.com/en-us/powershell/module/dnsserver/set-dnsserverzoneaging?view=windowsserver2025-ps
- Microsoft Learn — Add-DnsServerResourceRecordA (DnsServer, Windows Server 2025) — Синтаксис создания A-записи и назначение параметров -AgeRecord, -CreatePtr, -TimeToLive, -IPv4Address, -ZoneName и -ComputerName. -AgeRecord явно включает timestamp для создаваемой записи. https://learn.microsoft.com/en-us/powershell/module/dnsserver/add-dnsserverresourcerecorda?view=windowsserver2025-ps
- Microsoft Learn — Set-DnsClient (DnsClient, Windows Server 2025) — Официальный синтаксис управления регистрацией адреса интерфейса: -InterfaceAlias и -RegisterThisConnectionsAddress. https://learn.microsoft.com/en-us/powershell/module/dnsclient/set-dnsclient?view=windowsserver2025-ps
- Microsoft Learn — How to configure DNS dynamic updates in Windows Server — Первичная документация о динамической регистрации Windows: машины с вручную заданным TCP/IP также регистрируют A и PTR, стандартное периодическое обновление выполняется каждые 24 часа, ipconfig /registerdns запускает регистрацию принудительно. https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/configure-dns-dynamic-updates-windows-server-2003
- Microsoft Learn — How to prevent domain controllers from dynamically registering DNS names — Документация Netlogon: записи контроллера регистрируются при перезапуске контроллера или службы Netlogon и затем раз в час; описан файл %windir%\system32\config\netlogon.dns и параметр UseDynamicDns. https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/prevent-domain-controllers-dns-names
- Microsoft Learn — Dnscmd — Официальная архивная справка по dnscmd: синтаксис /ageallrecords, /zoneresetscavengeservers и /startscavenging; указано, что /ageallrecords назначает текущее время записям и операция не имеет общего обратного преобразования. https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/cc772069(v=ws.11)
