4

问题

我正在尝试使用 apache 服务器后面的 laravel websockets 库设置一个实时环境。Websocket 服务器正在端口上运行6001(无法从外部访问)。Apache VHost 配置为ws.example.com

我无法让 Apachewss://正确代理请求。请求wss://ws.example.com/request/path?protocol=7&client=js&version=5.1.1&flash=false失败。( Error during WebSocket handshake: Invalid status line)

我认为我的虚拟主机配置有问题。我错过了什么吗?任何建议表示赞赏。

虚拟主机配置

<VirtualHost *:443>
    ServerName ws.example.com
    ServerAlias www.ws.example.com.com
    DocumentRoot /srv/vhost/example.com/domains/ws.example.com/public_html

    ErrorLog /var/log/virtualmin/ws.example.com_error_log
    CustomLog /var/log/virtualmin/ws.example.com_access_log combined
    ScriptAlias /cgi-bin/ /srv/vhost/example.com/domains/ws.example.com/cgi-bin/

    DirectoryIndex index.php index.html

    RewriteEngine on
    ProxyRequests off
    ProxyVia on
    RewriteCond %{HTTP:Connection} Upgrade [NC]
    RewriteCond %{HTTP:Upgrade} websocket [NC]
    RewriteRule /(.*) ws://localhost:6001/$1 [P,L]
    ProxyPass               /request/path http://localhost:6001/request/path
    ProxyPassReverse        /request/path http://localhost:6001/request/path

    SSLCertificateFile /etc/letsencrypt/path/ws.example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/path/ws.example.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
4

2 回答 2

2

为 websockets 创建一个子域。然后编辑您的虚拟主机配置(Apache 2.4),如下所示:

<VirtualHost *:443>
    ServerAdmin admin@example.com
    ServerName socket.website.com

    <Proxy *>
        Require all granted
        Allow from all
    </Proxy>

    SSLEngine on
    SSLProxyEngine on
    SSLProxyVerify none
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerName off
    SSLProxyCheckPeerExpire off

    RewriteEngine on
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule .* wss://127.0.0.1:6001%{REQUEST_URI} [P]
    ProxyPass / ws://127.0.0.1:6001
    ProxyPassReverse / ws://127.0.0.1:6001

    SSLCertificateFile /etc/letsencrypt/live/socket.website.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/socket.website.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>

broadcasting.php

    'pusher' => [
        'driver' => 'pusher',
        'key' => env('PUSHER_APP_KEY'),
        'secret' => env('PUSHER_APP_SECRET'),
        'app_id' => env('PUSHER_APP_ID'),
        'options' => [
            'cluster' => env('PUSHER_APP_CLUSTER'),
            'host' => '127.0.0.1',
            'encrypted' => true,
            'port' => 6001,
            'scheme' => 'https',
            'curl_options' => [
                CURLOPT_SSL_VERIFYHOST => 0,
                CURLOPT_SSL_VERIFYPEER => 0,
            ]
        ],
    ],

websockets.php

'dashboard' => [
    'port' => env('LARAVEL_WEBSOCKETS_PORT', 443) // <- we changed this to 443
],
'apps' => [
    [
        'id' => env('PUSHER_APP_ID'),
        'name' => env('APP_NAME'),
        'key' => env('PUSHER_APP_KEY'),
        'secret' => env('PUSHER_APP_SECRET'),
        'enable_client_messages' => true,
        'enable_statistics' => true,
        'encrypted' => true,
        'host' => env('WEBSOCKETS_URL') // for dashboard
    ],
],
'allowed_origins' => [
    parse_url(env('APP_URL'))['host']
],
'statistics' => [
    ...
    'perform_dns_lookup' => true, // For statistics to work
    ...
],
'ssl' => [
    'local_cert' => env('LARAVEL_WEBSOCKETS_SSL_LOCAL_CERT', null),
    'local_pk' => env('LARAVEL_WEBSOCKETS_SSL_LOCAL_PK', null),
    'passphrase' => null,
    'verify_peer' => false
],

.env

WEBSOCKETS_URL=socket.website.com
LARAVEL_WEBSOCKETS_SSL_LOCAL_CERT=/etc/letsencrypt/live/socket.website.com/fullchain.pem
LARAVEL_WEBSOCKETS_SSL_LOCAL_PK=/etc/letsencrypt/live/socket.website.com/privkey.pem

/etc/supervisord.d/websockets.conf

[program:websockets]
command=php /var/www/html/website.com/artisan websockets:serve --host=127.0.0.1 --port=6001
process_name=websockets
numprocs=1
autostart=true
autorestart=true

Echo

window.Echo = new Echo({
    broadcaster: 'pusher',
    key: window["MIX_PUSHER_APP_KEY"], // <- from .env
    wsHost: window["WEBSOCKETS_URL"], // <- from .env
    wsPort: 80,
    wssPort: 443,
    disableStats: true, 
    enabledTransports: ['ws', 'wss']
});
于 2020-10-15T11:46:37.947 回答
-1

@max:您的重写规则是关键,当代理仅转发未加密的流量并且 apache 正在将 ssl 处理到外部时也适用,替换wsswsthen - 经过一天的摆弄,它终于可以正常工作了!

编辑:评论没有足够的声誉,对不起

于 2020-10-22T21:36:12.273 回答