Websocket работает только с ws: // но не с wss://

#ruby-on-rails #apache #ssl #websocket

#ruby-on-rails #apache #ssl #websocket

Вопрос:

У меня есть один сайт, настроенный для работы с ssl. Каждый запрос, который я получаю, я перенаправляю на https. Недавно я внедрил в него websocket, и он отлично работает при разработке, поэтому, когда я запустил production, я начал получать эту ошибку Firefox can’t establish a connection to the server at wss://

Я создал новую локаль файла только для подключения к моему websocket, который находится в рабочей среде. Когда я подключаюсь, используя ws://domain это работает, при переходе на wss://domain я получаю сообщение об ошибке.

Я использую ubuntu 18: 04, Apache / 2.4.18 и Rails action cable.

Мой виртуальный хостинг

 <VirtualHost *:80>
    ServerName domain.com
    ServerAlias www.domain.com
    ServerAdmin contato@domain.com
    DocumentRoot /var/www/domain.com/public
    ProxyRequests off
    ProxyPreserveHost On
    LogLevel error

    <Location />
        Order allow,deny
        Allow from all
        Require all granted
    </Location>

    ProxyPass / http://127.0.0.1:8080/
    ProxyPassReverse / http://127.0.0.1:8080/

    ProxyPass /cable/  ws://127.0.0.1:28080/cable/
    ProxyPassReverse /cable/ ws://127.0.0.1:28080/cable/

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

<VirtualHost *:443>
    ServerName domain.com
    ServerAlias www.domain.com
    ServerAdmin contato@domain.com
    DocumentRoot /var/www/domain.com/public
    ProxyRequests off
    ProxyPreserveHost On
    LogLevel error

    <Location />
        Order allow,deny
        Allow from all
        Require all granted
    </Location>

    ProxyPass / http://127.0.0.1:8080/
    ProxyPassReverse / http://127.0.0.1:8080/

    ProxyPass /cable/  wss://127.0.0.1:28080/cable/
    ProxyPassReverse /cable/ wss://127.0.0.1:28080/cable/

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

На локальном хостинге вне домена, если я вызываю, exampleSocket = new WebSocket("wss://domain.com/cable/"); я получаю Firefox can’t establish a connection to the server at wss:// , но если я вызываю exampleSocket = new WebSocket("ws://domain.com/cable/"); , соединение работает.

На сайте, если я вызываю exampleSocket = new WebSocket("ws://domain.com/cable/"); , это не работает из-за ssl, и я получаю SecurityError: The operation is insecure.

Кто-нибудь может помочь с этим?

Ответ №1:

 <VirtualHost *:80>
    ...
    ProxyPass / http://127.0.0.1:8080/
    ...
    ProxyPass /cable/  ws://127.0.0.1:28080/cable/
    ...
<VirtualHost *:443>
    ...
    ProxyPass / http://127.0.0.1:8080/
    ...
    ProxyPass /cable/  wss://127.0.0.1:28080/cable/
  

Маловероятно, что ваш неизвестный сервер Websocket может выполнять оба ws:// и wss:// на одном и том же порту 28080. Более вероятно, что это может сделать только ws:// , т. е. вам следует перенаправить на ws:// как для портов 80, так и для 443. Обратите внимание, что это похоже на то, что вы уже правильно делаете для обычного трафика: оба порта 80 и порт 443 перенаправляются на внутренний http:// , а не не один на http:// , а другой на https:// .

Комментарии:

1. Я изменил ProxyPass /cable/ wss://127.0.0.1:28080/cable/ на порту 443 на ProxyPass /cable/ ws://127.0.0.1:28080/cable/ , но это не сработало.

2. @AllanKlaus: https:// Работает ли это вообще? Поскольку «не удается установить соединение» может означать, что на порту 443 ничего не работает, т.е. ни https:// ни wss:// . И это может быть вызвано настройками брандмауэра, которые не имеют ничего общего с настройкой Apache.

3. https:// работает. Когда я получаю доступ к домену с помощью http:// , я перенаправляю на https:// . На брандмауэре оба порта включены « 80 РАЗРЕШИТЬ везде 443 РАЗРЕШИТЬ везде 80,443 / tcp РАЗРЕШИТЬ везде

4. Тогда, пожалуйста, покажите точное сообщение об ошибке, которое вы получаете сейчас (которое может отличаться от того, которое вы получали раньше), а также проверьте наличие любых сообщений об ошибках в файлах журнала apache.

5. Я исправил проблему, изменив порядок прохождения прокси для соответствия первому на /cable

Ответ №2:

Я исправил проблему. Все шло не так из-за порядка прохождения прокси в файле конфигурации apache. Я изменил файл на этот

 <VirtualHost *:80>
    ServerName suaradioonline.com
    ServerAlias www.suaradioonline.com
    ServerAdmin contato@suaradioonline.com.br
    DocumentRoot /var/www/suaradioonline.com/public
    ProxyRequests off
    ProxyPreserveHost On
    LogLevel error

    <Location />
        Order allow,deny
        Allow from all
        Require all granted
    </Location>

    ProxyPass /cable/  ws://127.0.0.1:28080/cable/
    ProxyPassReverse /cable/ ws://127.0.0.1:28080/cable/

    ProxyPass / http://127.0.0.1:8080/
        ProxyPassReverse / http://127.0.0.1:8080/

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

<VirtualHost *:443>
        ServerName suaradioonline.com
        ServerAlias www.suaradioonline.com
        ServerAdmin contato@suaradioonline.com.br
        DocumentRoot /var/www/suaradioonline.com/public
        ProxyRequests off
        ProxyPreserveHost On
        LogLevel error

        <Location />
            Order allow,deny
            Allow from all
            Require all granted
        </Location>

        ProxyPass /cable/  ws://127.0.0.1:28080/cable/
        ProxyPassReverse /cable/ ws://127.0.0.1:28080/cable/

        ProxyPass / http://127.0.0.1:8080/
        ProxyPassReverse / http://127.0.0.1:8080/

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

Это происходит из-за прокси-передачи / совпадения во всех входящих запросах, и запрос /cable/ так и не был достигнут.