Обратный прокси-сервер

В реальных развертываниях часто хочется исключить доступ пользователей к внутренним сетевым ресурсам. Как правило, это решается использованием обратного прокси-сервера (Reverse Proxy), который установлен в демилитаризованной зоне (DMZ), доступен из внешней сети и имеет доступ к внутренней сети. Пользователи имеют доступ только ко внешнему интерфейсу прокси-сервера и не могут напрямую обращаться к ресурсам во внутренней сети, в которой развернут сервер.

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

В данном разделе описаны общие принципы поддержки Reverse Proxy, зная которые можно настроить любой готовый прокси-сервер или написать свой. Также приводятся варианты конфигурации прокси на примере популярного прокси-сервера nginx.

Механизм формирования URL в ответах сервера при работе за reverse proxy

Использование proxy-серверов осложняет задачу формирования URL в ответах сервера (это могут быть URL в представлении ресурсов или URL в заголовках): сервер «1С:Шины» получает запрос от proxy-сервера и не может восстановить исходный URL используя одни лишь данные из строки запроса и заголовка HOST. Другими словами сервер не в состоянии сформировать URL к ресурсу каким он видится клиенту.

Для передачи данных, необходимых для восстановления URL используются заголовки X-Forwarded-*. Они устанавливаются ближайшим к клиенту proxy-сервером и несут всю необходимую для формирования URL информацию:

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

Ниже описаны заголовки, которые может использовать proxy-сервер и которые поддерживаются компактным сервером.

X-Forwarded-Proto
Схема, которая использовалась клиентом при отправке запроса на ближайший к нему proxy-сервер.
Если этот заголовок присутствует, то компактный сервер использует значение в качестве схемы во всех генерируемых URL.
Возможные значения: http, https.
X-Forwarded-Host
Хост, к которому обратился клиент (имя или адрес).
Если этот заголовок присутствует, то компактный сервер использует значение в качестве имени хоста во всех генерируемых URL.
X-Forwarded-Port
Номер порта на который клиент отправил запрос.
Если этот заголовок присутствует, то номер порта запроса меняется на значение заголовка.
Если заголовок X-Forwarded-Port не задан, но задан X-Forwarded-Host, то номер используется номер порта по-умолчанию в зависимости от схемы каталога: 80 (http), 443 (https).
X-Forwarded-Prefix
Префикс пути исходного запроса – используется для передачи на целевой сервер информации о том какой префикс сегмента path используется на ближайшем к клиенту proxy для всех URL.
Если этот заголовок присутствует, то он добавляется в начало сегмента path всех URL, которые генерирует сервер. Указанный заголовок proxy-сервер должен устанавливать, если на прокси-сервере используется непустой префикс пути для upstream сервера.
X-Forwarded-Endpoint
Нестандартный заголовок. Используется для замены сегмента path /applications/<имя приложения> на более короткий сегмент.
X-Forwarded-For
Список промежуточных IP-адресов. Первым должен идти IP-адрес клиента, отправившего запрос, за ним – адреса всех промежуточных proxy-серверов. В настоящий момент не используется, в будущем может быть использован для логов и аналитики.

Отображение заголовков на URL

Пусть сервер «1С:Шины» доступен по адресу 192.168.0.1 (порт 9090), клиент взаимодействует с ним через proxy, доступный по адресу 10.0.0.1 (порт 443). Пусть в сервере «1С:Шины» функционирует приложение app1. Proxy взаимодействует с сервером «1С:Шины» не используя защищенное соединение, тогда некоторый ресурс приложения доступен proxy-серверу по URL:

http://192.168.0.1:9090/applications/app1/api/resource

Клиент не имеет возможности работать непосредственно с адресом 192.168.0.1, вместо этого он взаимодействует с proxy, доступном на адресе 10.0.0.1 по защищенному соединению.

Proxy, помимо запросов к серверу «1С:Шины», принимает запросы, адресованные другим серверам — таким образом конфигурация proxy должна обеспечить возможность различать запросы для разных серверов.

Также proxy использует возможность, предоставляемую сервером «1С:Шины», по укорачиваю URL за счет замещения сегментов applications/app1. В этих условиях тот же ресурс адресуется клиентом (работающим с proxy) следующим образом (на схеме отображены значения заголовков, которые proxy отправит серверу «1С:Шины» для обеспечения возможности восстановления URL, использованного клиентом):

X-Forwarded-Proto
  |
  |           X-Forwarded-Prefix
  |               |  
/---\            /-\
https://10.0.0.1/cs/app1/api/resource
        \------/\   \--/
           |     \    |
X-Forwarded-Host |   X-Forwarded-Endpoint
                 |
     X-Forwarded-Port
Примечание: Заголовок X-Forwarded-Endpoint в отличии от остальных заголовков X-Forwarded-* настраивается в конфигурационных файлах для каждого приложения отдельно.

Примеры трансляции клиентских запросов proxy-серверами

Пусть ближайший к серверу «1С:Шины» reverse-proxy принимает запросы на адресе 10.0.0.2, непосредственно сервер «1С:Шины» — на адресе 192.168.0.1, а на адресе 10.0.0.1 функционирует другой reverse proxy, который ближе к клиенту, клиент отправляет запросы с сокета 10.0.0.10:45675. Входящие запросы поступают по защищенному соединению, транслируются запросы в режиме clear text.

Прием запроса компактным сервером, который прошел через reverse-proxy.

Запрос отправленный ближайшему к клиенту reverse-proxy:

GET /app1/resource/1 HTTP/1.1
Host: 10.0.0.1

Запрос, транслированный следующему reverse-proxy в цепочке. Этот proxy настроен на переписывание сегмента path с помощью X-Forwarded-Prefix/Endpoint, он, как ближайший к клиенту, устанавливает все X-Forwarded-* заголовки:

GET /applications/app1/resource/1 HTTP/1.1
Host: 10.0.0.2
X-Forwarded-Proto: https
X-Forwarded-Host: 10.0.0.1
X-Forwarded-Port: 443
X-Forwarded-Endpoint: /app1
X-Forwarded-For: 10.0.0.10:45675

Запрос, транслированный серверу «1С:Шины». Этот proxy транслирует path запроса в неизмененном виде и лишь модифицирует заголовок X-Forwarded-For:

GET /applications/app1/resource/1 HTTP/1.1
Host: 192.168.0.1
X-Forwarded-Proto: https
X-Forwarded-Host: 10.0.0.1
X-Forwarded-Port: 443
X-Forwarded-Endpoint: /app1
X-Forwarded-For: 10.0.0.10:45675,10.0.0.1:443

В результате сервер «1С:Шины» сможет сгенерировать url, восстановив начальную часть по заголовкам: https://10.0.0.2:443/app1/, и сгенерировать URL других ресурсов, относящихся к приложению.

Ограничения использования заголовка X-Forwarded-Endpoint

Заголовок X-Forwarded-Endpoint не может использоваться для менеджеров приложений и аутентификации (при поступлении запроса к ресурсам менеджеров с указанным заголовком клиент получит ответ с кодом 400). Причина в невозможности узнать значения X-Forwarded-Endpoint при переадресации из других приложений.

Примеры конфигурации nginx