Назад | Перейти на главную страницу

Websocket и HTTP-прокси с сервером между двумя брандмауэрами

У меня есть сервер («A»), работающий за брандмауэром, который обслуживает HTTP и веб-сокеты. У меня нет контроля над брандмауэром, но у меня есть внешний сервер («B»), к которому может подключиться внутренний сервер (обратите внимание, что обратное соединение от B к A невозможно из-за брандмауэра). Как я могу настроить какой-то прокси на B, чтобы интернет-клиент («C») мог получить доступ к ресурсам на A?

Я бы предпочел что-нибудь легкое - даже программу Python или SSH-туннель (что я пробовал безуспешно) - чем что-то более тяжелое, но надежное.

У вас две проблемы. Во-первых, вам нужно обойти брандмауэр. Во-вторых, вам нужно отменить прокси-серверы.

Первая проблема проще. Я бы начал с установки openvpn-server на B и подключил к нему A. Вы можете выбрать любой порт, разрешенный брандмауэром. Я обнаружил, что он отлично поддерживает удаленное соединение, и вы получаете шифрование для загрузки.

Вторая проблема - это обратное проксирование http и веб-сокетов. Веб-сокеты - это сложно, но после установки openvpn вы можете использовать любой из обычных методов, не беспокоясь о брандмауэре. Я бы попытался использовать функции прокси-сервера websocket более поздних версий nginx: http://nginx.org/en/docs/http/websocket.html

Я решил это с помощью веб-прокси nginx с туннелем ssh. Предполагая, что моя служба на A работает на порту 3000, я сделал:

ssh -R 3000:localhost:3000 me@B

для установки обратного соединения от порта 3000 на B к порту 3000 на A.

Затем я настроил прокси-сервер nginx для пересылки как веб-сокета, так и обычного трафика на порт ssh со следующей конфигурацией:

events {
  worker_connections 100;  #I'm not expecting many connections
}

http {
  server {
      listen 3001;

      # host name to respond to
      #server_name ws.example.com;

      location / {
          # switch off logging
          access_log off;

          # redirect all HTTP traffic to localhost:3000
          proxy_pass http://localhost:3000;
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header Host $host;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

          # WebSocket support (nginx 1.4)
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
      }
  }
}

Теперь я могу подключиться к C, чтобы http://B:3001 и все прозрачно пересылается http://A:3000.

Единственная оставшаяся проблема заключается в том, что первоначальное соединение немного медленное, но это может быть связано с подключением ssh. Я собираюсь поэкспериментировать с добавлением сжатия gzip к прокси-серверу nginx.