Apache proxy todas as conexões ws para porta diferente

1

No meu vache do Apache 2.4, estou tentando obter todo o tráfego https:// para a porta 443, mas todo o tráfego ws:// para encaminhar para ws://*:6969 .

Por exemplo:

https://example.com/index iria para https://example.com/index:443 normalmente.

ws://example.com/anypathhere/ seria encaminhado para ws://example.com/anypathhere:6969

Até agora eu tentei os valores comentados no vhost.

<VirtualHost *:443>
    SSLEngine on
    SSLCertificateFile /etc/pki/tls/certs/ca.crt
    SSLCertificateKeyFile /etc/pki/tls/private/ca.key
    DocumentRoot /var/www/html/

    RewriteOptions Inherit
    AccessFileName .htaccess
    AllowEncodedSlashes NoDecode

    DirectoryIndex disabled

    <Directory /var/www/html>
            Options +FollowSymlinks
            RewriteEngine On
            AllowOverride All
            Require all granted
            RewriteCond %{REQUEST_FILENAME} -d
            RewriteRule .* %{REQUEST_URI}index.php [L]
    </Directory>

    ServerName localhost.localdomain


  #ProxyPreserveHost On
  #ProxyRequests Off
  #ProxyPassMatch / ws://192.16.4.177:6969/ retry=0
  #ProxyPassReverse ws:// ws://192.16.4.177:6969/
  #ProxyPass ws:// ws://192.16.4.177:6969/
  #RewriteEngine On
  #RewriteRule ws:// ws://%{HTTP_HOST}/$1:6969 [NC,R=301,L]

Tudo isso resulta em

Firefox can't establish a connection to the server at ws://192.16.4.177:443

ou um erro 400.

    
por KapowKi 21.10.2015 / 11:30

3 respostas

1

Você realmente precisa adicionar um vhost para o tráfego ws, que está ouvindo *:80

Há um ponto, que falha com RewriteCond ou com ProxyPass no Arquivo VHost errado. Seu tráfego é criptografado pelo certificado que você está usando. Portanto, a conexão não será estabelecida corretamente. Seu host remoto não pode lê-lo.

Com base na documentação em wikipedia :

The communications are done over TCP port number 80 [..]

Seu arquivo VHost adicional deve ficar assim:

<VirtualHost *:80>
  ServerName localhost.localdomain
  ProxyPreserveHost On
  ProxyRequests Off
  ProxyPassReverse / ws://192.16.4.177:6969/
  ProxyPass / ws://192.16.4.177:6969/
</VirtualHost>

Como explicação. Todo o seu pedido passando por http: 80 é redirecionado para ws: 6969.

    
por 26.10.2015 / 11:25
1

Infelizmente, não acho que haja uma maneira fácil de fazer isso. A resposta de Peter não funciona porque Websockets pega carona em HTTP (S) como uma solicitação GET com cabeçalhos especiais . Qualquer que seja a lógica que o mod_rewrite use para detectar o esquema de URL não é inteligente o suficiente para detectar isso, então o esquema sempre aparece como http ou https .

Em teoria, você pode procurar os cabeçalhos com algo como a seguinte sintaxe:

RewriteCond %{HTTP:Upgrade} ^websocket$ [nocase]
RewriteRule ^(.*)$ ws://192.16.4.177:6969/$1 [proxy]

No entanto, embora essa regra corresponda ao handshake de abertura do cliente (confirmado em meus logs), isso não me dá um redirecionamento de Websocket funcionando. Eu suspeito que mod_rewrite não entende realmente como fazer proxy nas conexões do Websocket, mesmo que você consiga que o handshake vá para o lugar certo.

Isso nos deixa com a resposta da JinnFox. Se você conseguir mover o ponto de extremidade do Websockets para algum lugar diferente de / , isso pode ser uma solução aceitável.

P.S. Nesse meio tempo, descobri que o NGINX lida com este caso quase perfeitamente (role para baixo até o passo 6 para encontrar um trecho de código que funciona tanto para o HTTP quanto para o WS).

    
por 26.11.2015 / 02:49
0

A melhor maneira de fazer isso seria dizer ao cliente para usar a porta certa ... mas se você quiser fazer proxy ou redirecionar quando usar a porta errada:

Eu não sei nada sobre ws: //, mas eu acredito que você precisaria usar um RewriteCond para isso, já que RewriteRule e similar não contém o esquema para combinar. Veja a referência da diretriz . Isso provavelmente só funcionará se ws: // requests forem parecidos com HTTP requets, ou se você tiver um módulo que lide especialmente com ws: // requests. (Para usar RewriteCond , você pode listá-lo quantas vezes quiser, e isso se aplica somente ao próximo RewriteRule [ou similar?])

por exemplo. para proxying:

RewriteEngine On
ProxyRequests Off
ProxyPreserveHost On

RewriteCond %{REQUEST_SCHEME} "^ws$"
RewriteRule "^(/?.*)$" ws://otherhost:6969/$1 [P]
    
por 21.10.2015 / 20:56