null

Проксирование SQL Server Reporting Services через nginx

SQL Server Reporting Services (SSRS) - программная серверная система создания отчётов, разработанная корпорацией Microsoft. Она может быть использована для подготовки множества интерактивных и печатных отчётов. Система администрируется через веб-интерфейс.

После установки и настройки SSRS, она становится доступна по двум адресам:

  • http://hostname/Reports
  • http://hostname/ReportServer

Первый из них является графическим интерфейсом пользователя, с возможностью создавать и управлять отчётами. Второй представляет из себя сервисный API по генерации и отдаче самих отчётов и обычно подгружается как frame из /Reports/.

Авторизация в портале осуществляется с помощью учётных записей Windows, то есть NTLM. И именно отсюда начинаются все проблемы. Дело в том, что авторизация через NTLM не подразумевает проксирование из-за особенностей своей работы. NTLM авторизация происходит в рамках одного TCP-соединения с клиентом и авторизовывает по сути это самое TCP-соединение, а не HTTP-"сессию" (ибо REST и ключ авторизованной NTLM сессии каждый раз передаётся в заголовке), а со стороны клиента это обычный Keep-Alive в HTTP.

При использовании же различных проксирующих frontend серверов типа nginx, установка соединений Keep-Alive между клиентом и backend-сервером невозможна из-за особенностей работы того же nginx.

По-умолчанию, он устанавливает с backend-сервером не Keep-Alive соединение, а рвёт его после выполнения каждого запроса. В таком случае, даже в случае успешной авторизации со стороны пользователя, дальнейшие запросы к порталу будут в ответ получать 401 Unauthorized и пытаться авторизоваться снова и снова.

Если же сконфигурировать nginx таким образом, чтобы он использовал для соединения с backend'ом пул соединений и выставить каждому timeout на закрытие, авторизация будет проходить, и даже всё будет с первого взгляда работать, но ровно до появления второго клиента. В этом случае, клиенты будут делить между собой уже установленные соединения, часть из которых были авторизованы валидными пользователями (напоминаю, происходит авторизация TCP-соединений). А свеже пришедший клиент может "захватить" это авторизованное соединение и попасть в портал без авторизации.

Возможное решение для проксирование NTLM-авторизации: осуществлять её на стороне веб-сервера, а в сторону SSRS авторизовываться веб-сервером. Но у того же nginx NTLM-авторизация отсутствует в бесплатной версии, так что данное решение не всегда применимо.

Либо отказаться от авторизации NTLM в пользу других доступных. Благо SSRS поддерживает обычную HTTP Basic authentication, которая только отключена по-умолчанию.

Итак, после нескольких часов, потраченных на тюнинг параметром proxy_pass nginx'а, пришлось просто сменить способ авторизации. Для этого, нужно открыть редактором конфигурационный файл C:\Program Files\Microsoft SQL Server\MSRS16.MSSQLSERVER\Reporting Services\ReportServer\RSReportServer.config, найти там секцию, отвечающую за авторизацию:

    <AuthenticationTypes>
        <RSWindowsNTLM/>
    </AuthenticationTypes>

И изменить её на HTTP Basic authentication:

    <AuthenticationTypes>
        <RSWindowsBasic/>
    </AuthenticationTypes>

После чего перезапустить службу SSRS и настроить проксирование самым обычным образом, например:

location / {
    proxy_pass    http://hostname/;
}