skip to Main Content

I’m running a Spotify server on my Raspberry Pi at my school’s robotics shop. It’s on the school wifi network and it’s accessed through a webpage http://localhost:6680. I wanted to add basic HTTP authentication (username/password) because people were being malicious, so I’m using an Apache VirtualHost as a proxy with basic authentication.

In addition, the webserver requires WebSockets to function through the same port. I successfully set up a VirtualHost file and it’s working fine… except it’s not working on Safari or iOS. After looking in the console, all WebSocket requests in Safari are returning a 401 error:

WebSocket connection to 'ws://XX.XXX.XX.XXX/iris/ws/' failed: Unexpected response code: 401

After looking into this more, apparently it’s a known bug with Safari. Here’s the VirtualHost file:

<VirtualHost *:80>
  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined

  <Proxy *>
    Allow from all
  </Proxy>

  ProxyRequests On

  ProxyPass /mopidy/ws/ ws://localhost:6680/mopidy/ws/
  ProxyPassReverse /mopidy/ws/ ws://localhost:6680/mopidy/ws/

  ProxyPass /iris/ws/ ws://localhost:6680/iris/ws/
  ProxyPassReverse /iris/ws/ ws://localhost:6680/iris/ws/

  <Location />
    ProxyPass http://localhost:6680/
    ProxyPassReverse http://localhost:6680/

    AuthType Basic
    AuthName "Restricted Content"
    AuthUserFile /etc/apache2/.htpasswd
    Require valid-user
  </Location>
</VirtualHost>

Is there any way we can simply remove authentication for just the websockets but not for the webpage? Considering how this is structured, that should be the case, but it isn’t. Thanks!

3

Answers


  1. I don’t know much about WebSockets, but I do know that you should always declare the VirtualHost port you are listening to if you want to separate traffic.

    Try to do so by adding two different VirtualHost in the same configuration:

    <VirtualHost *:80>
      ErrorLog ${APACHE_LOG_DIR}/error.log
      CustomLog ${APACHE_LOG_DIR}/access.log combined
    
      <Directory "/">
        AllowOverride All
        AuthType Basic
        AuthName "Restricted Content"
        AuthUserFile /etc/apache2/.htpasswd
        Require valid-user
      </Directory>
    </VirtualHost>
    

    From now on I can’t help further:

    <VirtualHost *:6680>
     somethingsomethingsomething
    </VirtualHost>
    

    Update

    Traffic different from :80 is blocked in your school, I guess.
    I can suggest a more radical approach which is banning all traffic from Safari (both desktop and mobile).
    You can modify the config by adding a redirect to a courtesy page like “your browser is not supported”.

     <Location *>
     SetEnvIfNoCase User-Agent .*Safari* bad_browser
     Deny from env=bad_browser
     </Location>
    
    Login or Signup to reply.
  2. Make sure you are proxying over your websockets if needed. They might look something like this:

    ProxyPass        /socket.io http://localhost:6680/socket.io
    ProxyPassReverse /socket.io http://localhost:6680/socket.io
    
    Login or Signup to reply.
  3. Try do next, like described here:

    #In your case it will be like this:
    <LocationMatch /(iris|mopidy)/ws>
      Allow from all
    </LocationMatch>
    

    Update: Please be aware this rule to wide as you see.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search