Turned on WAF in Sophos UTM Firewall, video on web is black screen

Rather than use port forwarding, I have setup WAF on our Sophos UTM. This is working fine for the iOS app - it gets all the camera streams fine.

If however I access SecuritySpy via the web I can log in OK, but all the camera feeds are just black.

Have tried Safari and Firefox, Mac and iPad.

Nothing in the Sophos WAF logs that I can see. I’ve turned all the options off but still no video.

Any suggestions?

Thanks, James.

Comments

  • This is from the WAF log:

    httpd[16236]: [proxy:error] [pid 16236:tid 16269] (104)Connection reset by peer: [client 159.196.244.250:55290] AH03307: ap_proxy_transfer_between_connections: error on sock - ap_pass_brigade


    httpd: id="0299" srcip="159.196.244.250" localip="180.150.16.235" size="0" user="-" host="159.196.244.250" method="GET" statuscode="200" reason="-" extra="-" exceptions="-" time="185117" url="/video" server="cameras.bordo.com.au:9001" port="9001" query="?cameraNum=31&vcodec=jpeg&acodec=&fps=&apause=1&sizeFraction=1&auth=" referer="-" cookie="liveChecks0=31; ss-session-id=KeSoSk6SELG22nDFYOPtpnR; cookie-test=1; selectedSection=live; HASH_ss-session-id=67CD78D3420A8B812F67F3A813B202B6A3F76A13; cf_clearance=alCyvmkOytC1OSbBS5nkVcj_2HChyFlx9UDRArSg04o-1754433639-1.2.1.1-C6I9vWKGe9v_4mcNUy13VrgMje5BVuq9khUzbKVV3wQYBFZMF5BojwqEjrSh4YVP9x9FGd3xEnYE7tV9ntIKxHoNPUY78_jVQKi9tCKcxrzFwOTwxZXJ7Tfxflzyb.uQqrT0nALOkBduhTNvHPwKK8UcVnLPdQPRyZ47EejukGGOdDD9lczioNQ3XH5IwKOlHpC2jdRXXRg1bHKpSRSJtdPK15vUUZ9sm4R1WXVNX2c; b-pkuid=ZQOAZAZAMwMgYwMANQMgYQNQOANAYQNAOQMAYwZgOANANwYgZAMAOQNwNAMwYwMg; b-mobile=1; b-cfkstrhl=6aA1720e1ab18f71f2db3bdfa7ead746" set-cookie="-" websocket_scheme="wss" websocket_protocol="-" websocket_key="gCv70GQQcxw7h

    2025:08:09-17:16:25 astaro1-1 httpd: S3heZJyHA==" websocket_version="13" uid="aJb1yXbAAy8vd_cqCZ9-uQAAABy"

  • Hi James, SecuritySpy's web interfaces uses WebSockets for the live video streams, so you'll need to enable this functionality in the proxy. I'm not too familiar with Sophos but a quick google indicates there should be an option to 'Enable WebSocket passthrough' in the 'Advanced' section of the WAF rule.

  • Thanks Ben. 'Enable WebSocket passthrough' was turned on, so it should work.

  • Hi Ben. Sophos tech support have done a deep dive on this. This is what they had to say:

    Our development team analyzed the collected logs and captures.

    They have shared their analysis as follows:

    From the client's perspective, the issue is that the WebSocket connection through the WAF fails.

    We see several errors in the WAF logs. 

    Example:

    2025:08:15-08:46:48 astaro1-2 httpd[41020]: [proxy:error] [pid 41020:tid 41033] (70007)The timeout specified has expired: [client 159.196.244.250:61390] AH03307: ap_proxy_transfer_between_connections: error on sock - ap_pass_brigade
    
    2025:08:15-08:46:51 astaro1-2 httpd[41020]: [proxy:error] [pid 41020:tid 41035] (32)Broken pipe: [client 159.196.244.250:61517] AH03307: ap_proxy_transfer_between_connections: error on sock - ap_pass_brigade
    
    2025:08:15-09:18:38 astaro1-2 httpd[41020]: [proxy:error] [pid 41020:tid 41039] (104)Connection reset by peer: [client 159.196.244.250:61782] AH03307: ap_proxy_transfer_between_connections: error on sock - ap_pass_brigade
    

    Based on the available information, it appears that the backend is dropping the connection for some reason. Since there is no proper response being received from the backend, it is difficult to determine the exact cause from the WAF side alone.

    We also noticed several cookies in the request that seem to contain session data or access tokens. The backend may be configured to reject connections from proxies and perform validation of incoming requests.

    If the source IP differs from the client IP, the backend may drop the video feed. However, this is only a hypothesis, and reviewing the backend application logs would be necessary to confirm the underlying issue.

    Regarding the current configuration, based on the screenshots provided, it seems that WebSocket passthrough has been enabled for the root path /.

    This is not recommended.

    WebSocket passthrough should only be allowed on paths that actually handle WebSocket streams—in this case, it looks like it should be /video.

    When WebSocket passthrough is enabled, the WAF cannot enforce security features on that path, effectively bypassing its protections. If the application requires WebSocket connections on /, it would be better to use DNAT, as the WAF cannot provide any meaningful protection in that scenario.

    Additionally, it appears that the application has two backend ports configured—9001 and 9000—but only port 9001 is exposed to clients through the WAF. While this may not be directly related to the issue, as clients are trying to establish the WebSocket stream on port 9001 along with standard HTTP requests, we cannot fully rule out the possibility that the application expects port 9000 to be accessible as well. It may be used for fallback or other purposes.

    Any thoughts?


    Thanks, James.

  • My comments on this are as follows:

    • SecuritySpy uses cookies for authenticated HTTP sessions - after login, a unique cookie is supplied by the server, which the client must include in all subsequent requests within the session to authenticate itself.
    • The way WebSockets works is that the client first makes an HTTP request, with a special header to upgrade to a WebSocket connection. This HTTP request needs to contain the session cookie to be authenticated.
    • Without this session cookie, SecuritySpy would return an appropriate HTTP response like 403 (forbidden), so if this were the case, the WAP should be seeing this error.
    • After the connection has been upgraded to WebSockets, it becomes more tricky for the server to send back error messages if things go wrong. We have a custom error message format that our web frontend understands, because the built-in WebSocket mechanism for this is very basic. This could account for the WAF not being able to determine what went wrong, after the connection has been upgraded.
    • They are correct that /video is the path that should have the WebSocket passthrough enabled for it, not / - could this perhaps be the issue?
    • Only one port is needed - by default this is port 8000 for unencrypted (HTTP / WS) connections, or 8001 for secure (HTTPS / WSS) connections. It looks like you may have custom ports in use (9000 / 9001) but the situation is still the same - only one of these is needed for full access, not both.
  • Thanks Ben.

    From Sophos support:

    I have further feedback from our development.

    It looks like there is currently only a single /video site path route configured. That may not be correct. Ideally, the application should have two routes:

    • / to handle the regular HTTP requests for the UI
    • /video with websocket passthrough enabled for video traffic

    This would be the recommended basic rule layout.

    That said, having this setup alone doesn’t necessarily guarantee everything will work as expected, since we still don’t know the exact reason why the backend connection is being dropped. It could be something as simple as needing the passthrough option applied to the correct route, but it may also involve other factors.

    Please note that once traffic is in passthrough mode, it becomes invisible to us — we cannot see what happens inside the tunnel.

    If I just have /video as the site path route I can't even get to the login screen. I setup two site path routes, one for '/' and one for '/video' and are now back to where we started - everything works except no video.

    They continue:

    If the issue continues even with the two site path routes in place, another step to try would be disabling backend connection pooling. This would force the WAF to create a new connection to the backend for each incoming request. While this approach has a noticeable performance impact, it can help in cases where the issue is related to the WAF attempting to reuse persistent connections to the backend. At this point, it’s only a hypothesis, since the root cause of the connection drops is not yet clear.

    Is there anyway to do with in Security Spy?

    Thanks, James.

  • Actually, the backend connection pooling is a Sophos UTM setting. I've turned it on. No change.

  • So it sounds like you need a regular proxy for / and a WebSocket passthrough proxy for /video

    I've added some extra logging to the latest beta version of SecuritySpy that may reveal what is going wrong. Install it by going to Settings > Registration > Choose Version > Latest Beta > Install. Then:

    • Open the Console app
    • Select your Mac at the top-left side
    • Enter SecuritySpy into the search box
    • Click the Start streaming option
    • Try accessing the video stream
    • Copy-paste the resulting log entries here

    Here's what I mean:


  • jlbrown
    edited September 23

    Thanks Ben. Beta installed. Here is the log:


  • The log doesn't contain the extra logging I added. This indicates that the WebSocket connection isn't even being opened - it's not that SecuritySpy is closing the connection, it's not even receiving it in the first place.

    One thing I notice in your logs is that the protocol that the proxy is trying to use here is WSS, i.e. a secure WebSocket. In your arrangement, where the proxy is the one providing SSL services to the client, the connection between the proxy and SecuritySpy should be unencrypted (i.e. HTTP/WS, not HTTPS/WSS).

    So the arrangement should be client <-- HTTPS/WSS/9001 --> proxy <-- HTTP/WS/9000 --> SecuritySpy

    I'm assuming here that your ports in SecuritySpy are 9000/9001 rather than the default of 8000/8001 for HTTP/HTTPS?

  • Yes re ports.

    Sophos suggested the same thing - use plain HTTP from proxy to SecuritySpy. I did this.


    No luck.

    They also suggested turning off 'Backend connection pooling' so did that to no avail.

    Sophos Support said:

    The DEV team reviewed the site path configuration and that looks good. They suggested if backend connection pooling doesn't make a difference, then best to leave it enabled for better performance.

    Unfortunately, there isn't any data to use to troubleshoot this further. We don't have any visibility inside the tunnel, so the only thing we see is the backend dropping the connection. We suggest that you should get your server-side logs analyzed by SecuritySpy's support and tell us what the reason for the connection drop is.

    Maybe it's worth a try to see if setting this up in TLS offload mode would make a difference in behavior. Basically what you would need to do is change your HTTPS rule to use the HTTP backend, so that WAF terminates all TLS connections and forwards the content over HTTP. Looking at the documentation of SecuritySpy, that's how they recommend setting up their app with a Cloudflare reverse proxy, so maybe it would help in our case as well.

    Here is the new Security Spy log output:

    Thanks, James.

  • Hi Ben, any comments on the above?

  • Hi James, sorry but I'm out of ideas here. Again in the new logs you provided, there is no indication that a WS connection is even being attempted. I'd be happy to provide any further information you need about how SecuritySpy handles these connections, but the Sophos proxy is not something that we have tested nor officially support. If you don't want to expose your SecuritySpy server directly to the Internet, then perhaps the best option for you here is to use a private network solution like ZeroTier or Tailscale, as described here: Remote Access Without Port Forwarding. This provides an extra layer of security (even better than a proxy, since only devices that have been accepted into the virtual network can even attempt connections), and is free and easy to set up.