Конфигурирование SQL Server для сетевого доступа. Часть 2.
В предыдущей серии мы остановились на списке прослушиваемых SQL Server портов, которые можно получить при помощи netstat и ее разновидностей, в частности, замечательной Руссиновичской тулы TCPView, которую рекомендовал Artem в комментариях к посту. К сожалению, в Интернет-рекомендациях зачастую смешиваются понятия прослушиваемый и открытый порт. Netstat говорит только о том, что есть такой-то процесс, который слушает по такому-то порту. Например, на компе 192.168.0.2 имеются SQL Server, который слушает по порту 1433, Analysis Services, которые слушают по порту 2383 и т.д.:
Рис.1
но если эти порты закрыты на файрволе, то то эти товарищи могут вслушиваться сколько угодно, все равно ничего снаружи они не услышат. В качестве примера попробуем создать прилинкованный сервер на 192.168.0.2 с машины 192.168.0.1:
if exists(select 1 from sys.servers where name = 'Denalium') exec sp_dropserver @server = 'Denalium', @droplogins = 'droplogins'
exec sp_addlinkedserver @server = N'Denalium', @srvproduct = N'', @provider = N'SQLNCLI', @datasrc = N'192.168.0.2'
exec sp_addlinkedsrvlogin @rmtsrvname = 'Denalium', @locallogin = null, @rmtuser = 'sa', @rmtpassword = 'passw0rd'
exec sp_tables_ex @table_server = 'Denalium', @table_catalog = 'Adventure Works 2008R2'
Скрипт 1
Последний оператор завершается с ошибкой:
Msg 7399, Level 16, State 1, Procedure sp_tables_ex, Line 41
The OLE DB provider "SQLNCLI10" for linked server "Denalium" reported an error. The provider did not give any information about the error.
Msg 7303, Level 16, State 1, Procedure sp_tables_ex, Line 41
Cannot initialize the data source object of OLE DB provider "SQLNCLI10" for linked server "Denalium".
Прежде, чем грешить на провайдера, строку соединения, аутентификацию, эккаунт, под которым трудится SQL Serverный сервис, недостаток прав, инопланетян, необходимо убедиться, что SQL Server 192.168.0.1 может банально достучаться на SQL Server 192.168.0.2. Действительно, если со 192.168.0.1 пропинговать порт 1433 на 192.168.0.2:
Рис.2
мы видим, что он закрыт. В данном случае использовалась древняя Microsoftовская тула PortQry, которую можно скачать с Microsoft Downloads, также упоминавшаяся в предыдущей серии. PortQry может использоваться в качестве простейшего бесплатного портового сканера. Например, в нее можно передать список портов, используемых SQL Server и его компонентами (см. в прошлой серии) и посмотреть, кто из них открыт, кто нет:
c:\temp\portqryv2\portqry.exe -n 192.168.0.2 -p TCP -o 1433,1434,80,443,4022,21,137,138,139,135,2383,2382
c:\temp\portqryv2\portqry.exe -n 192.168.0.2 -p UDP -o 1434,500,4500
Рис.3
Можно передать диапазон портов: c:\temp\portqryv2\portqry.exe -n 192.168.0.2 -p TCP -r 137:139 и т.д.
Возникает вопрос - как узнать, какой в данном случае порт требуется открыть SQL Server (чтобы создать прилинкованный сервер, настроить зеркалирование, пообщаться с сервис-брокером, ...). Для начала стоит посмотреть на Рис.1, чтобы понять, чего хочет SQL Server, т.е. по каким портам он слушает = ожидает получить коммуникацию. Но, во-первых, хотелок может быть много, во-вторых, не все они имеют явное отношение к SQL Server, как, например, порты 135, 80 и т.д. Более надежный способ - это включить журналирование на файрволе, выполнить действие и посмотреть, в какие порты шло (пыталось пройти) взаимодействие. Для начала стоит убедиться, что причина действительно кроется в закрытых портах. На файрволе 192.168.0.2 иду в Control Panel -> Administrative Tools -> Windows Firewall with Advanced Security (или wf.msc из командной строки); встаю в левой панели на корень и из контекстного меню или из правой панели выбираем Properties. В открывшемся диалоговом окне свойств я выбираю закладку Private Profile, потому что соединение со 192.168.0.1 в моем случае относится к этому профилю, и отключаю для него Windows Firewall:
Рис.4
Теперь sp_tables_ex на прилинкованный сервер работает:
Рис.5
Значит, проблема действительно в том, что на файрволе 192.168.0.2 перекрыты какие-то необходимые порты. Осталось понять, какие. Для этого на Рис.4 включаю обратно файрвол на 192.168.0.2 в профиле Private, нажимаю кнопку Customize в секции Logging и включаю журналирование отвергнутых сетевых пакетов
Рис.6
Снова выполняю процедуру sp_tables_ex и выключаю логгирование, чтобы не захламлять картину. Открываю в текстовом редакторе файл, который на Рис.6 указан в качестве журнала:
Рис.7
Названия колонок приводятся в верхней строчке: дата, время, действие (DROP означает, что пакет был отвергнут), протокол (TCP, UDP, ICMP, …), с какого IP шел пакет, на какой, с какого порта, на какой, размер пакета и т.д. В колонке Path указывается направление. RECEIVE в данном случае означает, что по отношению к 192.168.0.2 это была входящая коммуникация. Попытка интенсивного общения по порту 500 в начале - это IPSec. Остается 1433 в трех последних строчках, где SSMS со 192.168.0.1 безуспешно бьется о файрвол на 192.168.0.2, пытаясь достучаться до тамошнего SQL Server. Стоит включить 1433 на 192.168.0.2:
netsh advfirewall firewall add rule "SQL Srv" dir=in action=allow enable=yes profile=private protocol=tcp remoteip=192.168.0.1 localport=1433
Рис.8
как наступает счастье (Рис.5).
Алексей Шуленин