Tengo un Apache de la ejecución que es sólo accesible a través de HTTPS. Quiero servir a websockets de un servidor adicional de la aplicación que se ejecuta en la misma máquina, pero ya no es posible para los clientes a conectar en otro puerto de 443 a nuestro servidor, los websocket las conexiones deben ser de proxy a través de Apache.

Ahora, he instalado mod_proxy y configurado de la siguiente manera:

SSLProxyEngine on
ProxyPass /ws https://127.0.0.1:9001

Esto no funciona sin embargo. Yo me puedo conectar a https://server/ws en mi navegador, pero el apache parece tragarse parte de los websockets encabezados, de modo que las conexiones websocket no funcionan.

¿Cómo puedo lograr túnel de mi websocket conexiones a través del servidor Apache?

  • Cualquier progreso con este problema?
  • Parece ser que hay nuevos módulos de Apache que podría hacer esto más fácil. Sin embargo, he recurrido a la utilización de stunnel+HAproxy, stunnel para aceptar la conexión SSL y pasar a través de la encriptar el tráfico de HAproxy, que decidirá sobre la presencia de la «Actualización: WebSocket» encabezado de si debería redirigir a la websocket servidor o a Apache a través de HTTP plano. Con la versión 1.5 de HAproxy (que está actualmente en desarrollo) el uso de stunnel puede que no sea necesario más.
InformationsquelleAutor mstud | 2012-07-13

2 Comentarios

  1. 27

    Tengo que trabajar.

    Escenario

    -------------       ----------------       ----------
    | Browser   |<----->| Apache httpd |<----->| Tomcat |
    |           |  SSL  |    2.4.9     |  SSL  | 7.0.52 |
    -------------       ----------------       ----------
    

    Navegador WebSocket a través de Apache httpd, proxy inverso a la aplicación web en Tomcat. Todos SSL de delante a atrás.

    Esta es la configuración para cada pieza:

    Navegador Cliente

    Nota al final el «/» en la url: wss://host/app/ws/. Era necesario que coincida con la correcta wss ProxyPass directiva (que se muestra más abajo en la configuración de Apache sección) y la prevención de un redireccionamiento 301 para https://host/app/ws. Es decir, era redirigir usando https esquema y no la wss esquema para el back-end.

    Página De Prueba

    <!doctype html>
    <body>
    
    <script type="text/javascript">
        var connection = new WebSocket("wss://host/app/ws/");
    
        connection.onopen = function () {
            console.log("connected");
        };
    
        connection.onclose = function () {
            console.log("onclose");
        };
    
        connection.onerror = function (error) {
            console.log(error);
        };
    </script>
    
    </body>
    </html>
    

    Apache httpd

    Estoy usando el Apache httpd 2.4.9, que fuera de la caja proporciona mod_proxy_wstunnel. Sin embargo, la mod_proxy_wstunnel.así siempre no admite SSL cuando se utiliza wss://esquema. Termina tratando de conectar con el back-end (Tomcat) en texto plano, que no consigue el handshake de SSL. Vea el error aquí. Así, usted tiene que parche mod_proxy_wstunnel.c usted mismo, siguiendo la corrección sugerida en el informe de error. Es una forma fácil 3 cambio de línea.

    Suggested correction,
    314a315
    >     int is_ssl = 0;
    320a322
    >         is_ssl = 1;
    344c346
    <     backend->is_ssl = 0;
    ---
    >     backend->is_ssl = is_ssl;
    

    Luego reconstruir el módulo y vuelva a colocarlo en su nueva mod_proxy_wstunnel.así con el antiguo.

    Edificio Apache httpd

    Aquí está el (2.4.9) comando que utilizó para construir en los módulos que yo quería. Es posible que no necesite todos ellos.

    ./configure --prefix=/usr/local/apache --with-included-apr --enable-alias=shared
    --enable-authz_host=shared --enable-authz_user=shared 
    --enable-deflate=shared --enable-negotiation=shared 
    --enable-proxy=shared --enable-ssl=shared --enable-reqtimeout=shared
    --enable-status=shared --enable-auth_basic=shared
    --enable-dir=shared --enable-authn_file=shared
    --enable-autoindex=shared --enable-env=shared --enable-php5=shared
    --enable-authz_default=shared --enable-cgi=shared
    --enable-setenvif=shared --enable-authz_groupfile=shared
    --enable-mime=shared --enable-proxy_http=shared
    --enable-proxy_wstunnel=shared
    

    Nota el último conmutador: --enable-proxy_wstunnel=shared Al principio, yo era incorrecta utilización de --enable-proxy-wstunnel=shared, que parecía a construir bien, pero en última instancia no funciona cuando he utilizado la resultante .de modo de archivo. Ver la diferencia? Usted quiere asegurarse de utilizar un carácter de subrayado en "proxy_wstunnel" en lugar de un guión.

    Apache httpd config

    httpd.conf

    ...
    LoadModule proxy_module modules/mod_proxy.so
    ...
    LoadModule proxy_wstunnel_module modules/mod_proxy_wstunnel.so
    ...
    LoadModule ssl_module modules/mod_ssl.so
    ...
    Include conf/extra/httpd-ssl.conf
    ...
    LogLevel debug
    ProxyRequests off
    
    # Note, this is the preferred ProxyPass configuration, and *should* be equivalent
    # to the same inline version below, but it does NOT WORK!
    #<Location /app/ws/>
    #        ProxyPass wss://localhost:8443/app/ws
    #        ProxyPassReverse wss://localhost:8443/app/ws
    #</Location>
    #<Location /app/>
    #        ProxyPass https://localhost:8443/app/
    #        ProxyPassReverse https://localhost:8443/app/
    #</Location>
    
    # NOTE: Pay strict attention to the slashes "/" or lack thereof!
    # WebSocket url endpoint
    ProxyPass /app/ws/wss://localhost:8443/app/ws
    ProxyPassReverse /app/ws/wss://localhost:8443/app/ws
    
    # Everything else
    ProxyPass /app/https://localhost:8443/app/
    ProxyPassReverse /app/https://localhost:8443/app/
    

    Si no ver mi nota en la anterior configuración, aquí está de nuevo: , preste mucha atención a las barras «/» o falta de ella!

    También, si usted está viendo declaraciones de registro de depuración en el log del servidor apache que dice wss conexión fue cerrada a continuación, es posible que usted tenga mod_reqtimeout habilitado como yo hice, así que asegúrese de que no se cargan:

    #LoadModule reqtimeout_module modules/mod_reqtimeout.so
    

    Tomcat

    Suponiendo que el conector HTTP de configuración es correcta, no hay mucho que configurar en tomcat. Aunque para facilitar la depuración, he encontrado que es útil para crear un $CATALINA_HOME/bin/setenv.sh que se veía así:

    setenv.sh

    CATALINA_OPTS=$CATALINA_OPTS" -Djavax.net.debug=all -Djavax.net.debug=ssl:handshake:verbose"
    

    Esto me permitió ver si el mod_proxy_wstunnel.así que he modificado estaba trabajando o no para wss://. Cuando no estaba trabajando, mi catalina.archivo de registro mostraría:

    javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?
    http-nio-8443-exec-1, SEND TLSv1 ALERT:  fatal, description = internal_error
    http-nio-8443-exec-1, WRITE: TLSv1 Alert, length = 2
    http-nio-8443-exec-1, called closeOutbound()
    http-nio-8443-exec-1, closeOutboundInternal()
    

    Final Pensamientos

    A pesar de que estoy usando el Apache httpd 2.4.9, He visto donde backports de mod_proxy_wstunnel se puede aplicar a las versiones 2.2.x. Espero que mis notas anteriores pueden aplicarse a las versiones anteriores.

    • Vale la pena señalar que mod_proxy_wstunnel también funciona para envolver SSL no websockets detrás de un servidor proxy SSL.
    • entonces supongo que si se conecta a WS a través de un no-ssl websocket no se necesita la modificación de mod_proxy_wstunnel, pero pueden usar el que «fuera de la caja.» Ninguna razón de peso para hacer Apache conectar vis wss en lugar de ws si se está ejecutando en localhost? Parece una buena solución.
    • ¿crees que es una buena solución de seguridad sabio? Yo no soy un WebSocket experto, pero creo que, redirigir la conexión segura no seguro no es una buena cosa (por Favor corríjanme si estoy equivocado) Gracias!
    • En realidad estoy tratando de terminar un no-ssl websocket detrás de un servidor proxy SSL, pero parece que no puede conseguir que funcione.. alguna sugerencia?
    • NOTA: El apache error mencionado ha sido fijada desde 2.4.10.
  2. 1

    Si usted no desea que Apache para terminar la conexión SSL (y hacia adelante sin cifrar WebSocket de tráfico), pero tiene el SSL terminado en el objetivo final WebSocket servidor y exlusively desea utilizar WSS en el WebSocket el tráfico que viene en el Apache, luego mod_proxy_connect puede ser capaz de conectarse a través de la raw de tráfico. No estoy seguro. Yo estaría también interesado si que funciona.

    Si encima no se sostiene, aquí hay más información:

    En cualquier caso, el uso de Apache severamente limitar la escalabilidad en cuanto a número de concurrentemente sirve WebSocket conexiones, ya que cada WS conexión consumirá 1 proceso/subproceso en el Apache.

    • Gracias por su respuesta. Sin embargo, no creo que mod_proxy_connect va a ayudar aquí, ya que sólo se encarga de las solicitudes de conexión que viene desde el navegador. Lo que necesito es transparente proxy inverso. Por cierto, funciona todo bien mientras yo no utiliza SSL.
    • Tengo que redirigir el único WebSocket solicitudes y manejar solicitud https por apache host virtual donde estoy cambiando este WebSockets. Para esto, necesito ProxyPass y ProxyPassReverse para https así?

Dejar respuesta

Please enter your comment!
Please enter your name here