Дело о загадочном Access denied

Дело о загадочном Access denied-1 Утром в службу поддержки обратился один из разработчиков корпоративного приложения. Он не мог сделать копию с базы данных MS SQL Server, и просил выяснить причину ошибки.
Первое с чего стоит начать — проверить ошибку на воспроизводимость.
Попробуем снять копию командой:

BACKUP DATABASE [SDB] TO DISK=N'\\FS1\Backup\sdb_full.bak' WITH COPY_ONLY 

Что еще за COPY_ONLY?
WITH COPY_ONLY — очень полезный ключ. Он позволит не нарушить в системе резервного копирования последовательность дифференциальных копий


Действительно, попытка снять копию заканчивалась ошибкой:
Дело о загадочном Access denied-2 Что может вызвать такую проблему?
SQL Server запускается от встроенной учетной записи «Network Service»
На всякий случай проверяем разрешение имени сервера FS1 по короткому имени и по FQDN. Оба имени разрешаются и, что важно, указывают на один и тот же сервер. Открываем сетевую папку, проверяем разрешения на NTFS и Share Permissions. Все в порядке, учетная запись сервера SQL1 имеет разрешение на запись.
Может быть проблемы с NTLM, Kerberos? Попробуем снять резервную копию, используя FQDN сервера.

BACKUP DATABASE [SDB] TO DISK=N'\\FS1.contoso.test\Backup\sdb_full.bak' WITH COPY_ONLY 


Дело о загадочном Access denied-3 Интересно. С использованием FQDN резервная копия успешно создалась. Что это значит? Разве что ситуация стала еще более запутанной.
SQL Server перезапускать в рабочее время нельзя. Оставаться в ночь не хотелось бы.
Когда ничего непонятно, лучший друг администратора — Wireshark или Microsoft Network Monitor. Если снять хороший дамп, то можно или разобраться, или уж запутаться так запутаться.
Ставить на ответственный сервер Microsoft Network Monitor теоретически безопасное мероприятие, но жизнь так часто вносит коррективы в самые безопасные начинания.
Перезагружаться нельзя, ставить монитор нежелательно. Тогда воспользуемся службой Windows Event Tracing.
Включили трассировку:

netsh trace start persistent=yes capture=yes tracefile=c:\temp\trace.etl 


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

BACKUP DATABASE [SDB] TO DISK=N'\\FS1\Backup\sdb_full.bak' WITH COPY_ONLY BACKUP DATABASE [SDB] TO DISK=N'\\FS1\Backup\sdb_full.bak' WITH COPY_ONLY BACKUP DATABASE [SDB] TO DISK=N'\\FS1\Backup\sdb_full.bak' WITH COPY_ONLY 

Остановили трассировку:

netsh trace stop 

Дело о загадочном Access denied-4 Открываем файл в Microsoft Network Monitor на рабочей станции администратора:
Дело о загадочном Access denied-5 Каждый раз при попытке снятия копии появляется событие KDC_ERR_PREAUTH_REQUIRED с загадочным пользователем DBAdmin. Это не учетная запись сотрудника, администратора, под ней не запускается SQL Server.
KDC_ERR_PREAUTH_REQUIRED означает, что учетные данные неверны.
Но резервное копирование выполняется в контексте службы «MS SQL Server», а она запущена под «Network Service». Причем здесь DBAdmin?
В Windows есть «Диспетчер учетных данных», он же «Credentials Manager», позволяющий сохранять учетные данные для различных сетевых ресурсов. Его можно вызвать командой «control userpasswords2»:
Дело о загадочном Access denied-6
Давайте проверим, нет ли в контексте учетной записи компьютера «SQL1\Network Service» сохраненных альтернативных учетных данных для сервера FS1.
Для того, чтобы запустить процесс от имени другого пользователя, воспользуемся psexec.
Если запустить psexec с ключем "-s", мы попадем в контекст «Local System». Не подойдет.
Для того, чтобы попасть в контекст «Network Service» запускаем утилиту со следующими ключами:

psExec.exe  -i  -u “nt authority\network service” cmd.exe 


Дело о загадочном Access denied-7 Дело о загадочном Access denied-8
Проверим, повторяется ли в контексте «Network Service» ошибка Access Denied при обращении к серверу FS1:
Дело о загадочном Access denied-9 Ошибка воспроизводится.
Проверим сохраненные учетные данные. Запустить «control userpasswords2» без колдовства с Explorer не получится. Да и не надо, для работы с «Credentials Manager» из командной строки есть утилита cmdkey.exe.
Для того, чтобы вывести сохраненные учетные данные выполним команду:

cmdkey /list 


Дело о загадочном Access denied-10 Никаких сохраненных учетных данных не обнаружено. Еще интереснее.
Итак, что мы знаем на текущий момент:

  1. В контексте учетной записи компьютера «SQL1\Network Service» при обращении по протоколу SMB к серверу FS1 возвращается ошибка Access Denied
  2. При обращении к серверу по FQDN FS1.contoso.test ошибка не возвращается
  3. Обращение к серверу FS1 происходит с использованием учетной записи DBAdmin, которая нигде в явном виде не используется
  4. В контексте «SQL1\Network Service» в Credentials Manager учетные данные не сохранялись


Подождите, а ведь учетные данные можно сохранить не только в Credentials Manager, но и в памяти службы «Lanman Workstation».
Если подключить диск с параметром /savecred, то учетные данные сохранятся в Credentials Manager:

net use \\FS1\Backup /persistent:yes /savecred   


Если опустить параметр /savecred, то учетные данные сохранятся в памяти службы до перезагрузки

net use \\FS1\Backup /persistent:yes /user:DBAdmin  


Проверим нет ли у нас сохраненных подключений:

net use 


Дело о загадочном Access denied-11 Есть! Теперь понятно, почему при обращении к FS1 возвращалась ошибка, а к FS1.contoso.test — нет.
Удалим сохраненные подключения:

net use * /delete 


Проверяем резервное копирование:
Дело о загадочном Access denied-12 Проблема решена.
А в чем же было дело? Причина ошибки весьма нетривиальна. Внутри корпоративного приложения от имени SQL Server был подключен сетевой диск под пользователем DBAdmin, который из-за ошибки в приложении не был в дальнейшем отключен. Спустя некоторое время у пользователя DBAdmin, вероятно сменился пароль, или сервер был перезагружен. И вот он, загадочный Access denied!
Какие для себя можно сделать выводы?

  1. Когда вы выполняете резервное копирование SQL Server, обращение к сетевым ресурсам производится от имени учетной записи службы SQL Server, а не от пользователя, запустившего команду BACKUP DATABASE. Следует помнить об этом, настраивая разрешения.
  2. Всегда снимайте дополнительные полные резервные копии с ключом WITH COPY_ONLY. SQL Server помечает страницы данных, измененные после полного резервного копирования, и в дифференциальную копию попадают только измененные страницы. Логично, что после каждого полного резервного копирования, состояние страниц очищается. Ключ позволяет не очищать отметку страниц, и последовательность не будет нарушена.
  3. В случае ошибки «Access denied» не лишним будет проверить, повторяется ли ошибка и по имени узла, по FQDN, по IP адресу.
  4. Вы можете попасть в контекст безопасности нужной учетной записи, запустив psexec с ключем -U.
  5. Для вывода учетных данных из службы хранения ключей используется утилита cmdkey.
  6. Для вывода сохраненных подключенных сетевых подключений используйте команду net use.


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

 
Автор: gotch, Источник

Добавить комментарий


Защитный код
Обновить