В настоящее время я рву на себе волосы на работе, пытаясь решить проблему с веб-приложением, которое использует SignalR через WebSockets, где трафик направляется через Barracuda Web Application Firewall (WAF). Каждая попытка подключиться к конечной signalr/connect
точке с помощью веб-сокетов завершается ошибкой 400 Bad Request. Затем соединение возвращается к опросу WebServer, что работает, но это не то, что нам нужно.
Сделанные запросы отправляются на наш Barracuda Web Application Firewall, а затем на наши Load Balanced IIS Web Servers. Мы используем IIS 8.5 на Windows Server 2012R2, а приложение — это .Net 4.6.2 Web Application.
Та же настройка (без использования Barracuda WAF) работает без проблем.
Пока что я имею
Включил Websockets в WAF согласно этой статьеhttps://campus.barracuda.com/product/webapplicationfirewall/doc/49054741/how-to-enable-websocket. Я все еще получаю ту же ошибку 400.
Проверил, чтобы убедиться, что на моих серверах IIS эта WebSocket
функция включена.
Включил отладку/трассировку SignalR в Web.Config согласноhttps://docs.microsoft.com/en-us/aspnet/signalr/overview/testing-and-debugging/enabling-signalr-tracing. Это приводит к появлению файлов журнала, но не указывает на ошибки.
Я не уверен, что еще проверить?
решение1
Итак, я нашел свою проблему. Я обнаружил, что мы на самом деле сначала отправляем наш трафик в наш WAF через Azure Load Balancer. Когда я вывожу заголовки в журналах доступа WAF, я вижу, что заголовок Connection
не имеет значения, и я знаю, что мой клиент отправляет его как Upgrade
.
Похоже, проблема возникает при использовании Azure Load Balancer. Поэтому я изучаю возможность использования Azure Application Gateway.
Однако на данный момент я могу заставить WAF добавлять заголовок Connection
за меня, настроив правило перезаписи заголовка для отправки этого заголовка на мои серверы IIS.
Необходимые заголовки для WebSockets
Connection: Upgrade Upgrade: websockets
- Откройте сайт управления Barracuda WAF.
- Перейти на сайт -> Переводы сайтов
В разделе «Перезапись HTTP-запроса» добавьте новое правило перезаписи…
- Укажите имя правила.
- Установите порядковый номер.
- В качестве действия выберите «Переписать заголовок».
- Введите Connection в качестве имени заголовка.
- Используйте * в качестве старого значения, которое заменит любое другое значение.
- Введите upgrade в качестве значения Rewrite, чтобы оно было отправлено вместо этого.
- Использовать
Header Upgrade eq websocket
как условие перезаписи. Теперь это правило будет применяться только тогда, когдаUpgrade
заголовок содержит значениеwebsocket
. - Нажмите «Добавить».
Теперь, когда я снова пытаюсь загрузить приложение, и — бац! — подключение к /signalr/connect с помощью транспорта webSockets успешно установлено!
Более подробную информацию можно получить на моемСообщение блога