Iis – Enabling WebSockets (SignalR) with a Barracuda WAF

barracudaiisweb-application-firewallwebsocket

I am currently tearing my hair out at work trying to resolve an issue with a web application that uses SignalR over WebSockets where traffic is directed through a Barracuda Web Application Firewall (WAF). Every attempt to connect to the signalr/connect endpoint using websockets would fail with a 400 Bad Request. The connection is then reverted back to WebServer polling which works, but isn't what we want.

Requests made are sent to our Barracuda Web Application Firewall and are then sent on to our Load Balanced IIS Web Servers. We are using IIS 8.5 on Windows Server 2012R2 and the application is a .Net 4.6.2 Web Application.

The same setup (Not using a Barracuda WAF), works without an issue.

So Far I have

Enabled Websockets in the WAF as per this article https://campus.barracuda.com/product/webapplicationfirewall/doc/49054741/how-to-enable-websocket. I still get the same 400 error.

Checked to make sure that my IIS Servers have the WebSocket Feature enabled.

Turned on SignalR debugging/tracing in the Web.Config as per https://docs.microsoft.com/en-us/aspnet/signalr/overview/testing-and-debugging/enabling-signalr-tracing. This results in log files, but no indicates errors.

I am not sure what else to check?

Best Answer

So I have found out my problem. I have found out that we are actually sending our traffic to our WAF through an Azure Load Balancer first. When I log out the Headers in the WAF Access Logs I can see that the Connection header has no value, which I know my client is sending as Upgrade.

It would appear to be an issue using an Azure Load Balancer. So I ma investigating using an Azure Application Gateway instead.

For the moment, however I can get this to work by having the WAF add the Connection Header for me, by configuring a rewrite header rule to send this header onto my IIS Servers.

Required Headers for WebSockets

Connection: Upgrade Upgrade: websockets

  1. Open up the Barracuda WAF Management Site.
  2. Go to Website -> Website Translations
  3. Under HTTP Request Rewrite, Add a new Rewrite Ruleā€¦

    1. Specify a Rule Name.
    2. Set a Sequence Number.
    3. Select Rewrite Header as the Action.
    4. Enter Connection as the Header Name.
    5. Use * as the Old Value, which will replace any value.
    6. Enter upgrade as the Rewrite value, so that this is sent instead.
    7. Use Header Upgrade eq websocket as the Rewrite condition. This will now only apply the rule when the Upgrade header contains the value websocket.
    8. Click Add.

Now when I try and load the application again and boom, connection successful to /signalr/connect with webSockets transport!

More information is available at my blog post

Related Topic