Apache VirtualHost con mod-proxy y SSL

28

Estoy tratando de configurar un servidor con múltiples aplicaciones web que serán atendidas a través de Apache VirtualHost (Apache que se ejecuta en el mismo servidor). Mi principal restricción es que cada aplicación web debe usar cifrado SSL. Después de buscar en Google por un tiempo y mirar otras preguntas sobre stackoverflow, escribí la siguiente configuración para VirtualHost:

<VirtualHost 1.2.3.4:443>
    ServerName host.example.org

    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    SSLProxyEngine On
    ProxyRequests Off
    ProxyPreserveHost On
    ProxyPass / https://localhost:8443/
    ProxyPassReverse / https://localhost:8443/
</VirtualHost>

Aunque https://host.example.org:8443 es accesible, https://host.example.org no lo es, lo que anula el propósito de mi configuración de host virtual. Firefox se queja de que, aunque se conectó con éxito al servidor, la conexión se interrumpió. También recibo la siguiente advertencia en el error.log de apache:

proxy: no HTTP 0.9 request (with no host line) on incoming request and preserve host set forcing hostname to be host.example.org for uri 

En la aplicación web (un servidor Tomcat) el registro de acceso muestra una extraña solicitud de acceso:

"?O^A^C / HTTP/1.1" 302

La siguiente es la solicitud de acceso correcta que obtengo cuando me conecto directamente a https://host.example.org:8443 :

"GET / HTTP/1.1" 302

Finalmente, también debo mencionar que el host virtual funciona perfectamente bien cuando no uso SSL.

¿Cómo puedo hacer que esto funcione?

JMD
fuente

Respuestas:

34

Por fin encontré una manera de hacerlo funcionar. Primero probé la sugerencia de Dave Cheney, así que instalé otro certificado para el servidor apache redirigido al puerto Tomcat no SSL (por lo que el proxy estaba redirigiendo a http: // localhost: 8080 / ). Desafortunadamente no funcionó completamente ya que en el navegador web el https se transformó en http inmediatamente después de la conexión. Así que volví a usar https: // localhost: 8443 / y el toque final para hacerlo funcionar fue agregar nuevamente SSLProxyEngine.

Aquí está la configuración de VirtualHost resultante:

<VirtualHost 1.2.3.4:443>
    ServerName host.domain.org

    <Proxy *>
        Order deny,allow
        Allow from all
    </Proxy>

    SSLEngine on
    SSLProxyEngine On
    SSLCertificateFile /etc/apache2/ssl/certificate.crt
    SSLCertificateKeyFile /etc/apache2/ssl/certificate.key

    ProxyRequests Off
    ProxyPreserveHost On
    ProxyPass / https://localhost:8443/
    ProxyPassReverse / https://localhost:8443/
</VirtualHost>
JMD
fuente
1
Evitarlo ProxyPreserveHost Ones casi siempre incorrecto, inútil y casi siempre se rompe ProxyPassReverse. Como nota al margen ProxyRequests offes el valor predeterminado, por lo tanto redundante.
kubanczyk
Cuando usamos IP externa en lugar de localhostno funciona.
Chaminda Bandara
4

Prueba esta configuración

<VirtualHost 1.2.3.4:443>
    ServerName host.domain.org

    SSLEngine On
    # include other ssl options, like cert and key here

    ProxyRequests Off
    ProxyPreserveHost On

    <Location />
        ProxyPass http://localhost:8443/
    </Location>
</VirtualHost>

Si su aplicación necesita tener acceso a la información SSL desde la conexión proxy, debería considerar usar mod_proxy_ajp y el conector tomcat ajp1.3.

Dave Cheney
fuente
Generaré el certificado con encriptemos en el servidor donde se ejecuta la aplicación para host.domain.org. ¿Entonces tengo que reutilizar el mismo certificado en el servidor proxy?
Giox
2

Pero si su objetivo es ejecutar múltiples aplicaciones web habilitadas para SSL en el mismo servidor. agregar apache al frente no los equilibrará usando su configuración anterior, aún necesitaría un equilibrador de carga o podría usar el módulo equilibrador proxy de apache con algo como lo siguiente:

ProxyRequests Off

<Proxy balancer://someapplication>
    BalancerMember http://127.0.0.1:18443 keepalive=on max=2 retry=30
    BalancerMember http://127.0.0.1:18444 keepalive=on max=2 retry=30
    BalancerMember http://127.0.0.1:18445 keepalive=on max=2 retry=30
</Proxy>


<VirtualHost 1.2.3.4:443>
    SSLEngine on
    SSLCipherSuite SSLv2:-LOW:-EXPORT:RC4+RSA
    SSLCertificateFile /path/to/cert.pem
    SSLCertificateKeyFile //path/to/key.pem
    SSLVerifyClient optional

    RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
    RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e

<Location />
    SetHandler balancer-manager
    Order allow,deny
    Allow from all
</Location>

ProxyPass / balancer://someapplication:443/
ProxyPassReverse / balancer://someapplication:443/
ProxyPreserveHost on
Brendan
fuente
Actualmente no necesito realmente utilizar el equilibrio de carga, pero eso podría ser útil en el futuro. Gracias por la perspicacia.
JMD
1

Bueno, lo que no entiendo aquí es por qué necesita tener una conexión SSL desde su apache a su aplicación que parece estar en la misma máquina ( http: // localhost: 8443 / ).

Supongo que la forma habitual de configurar cosas como esta es tener un apache que proporcione encriptación SSL al lado del "cliente", por ejemplo, Internet, y tener una conexión sin cifrar a la aplicación. Esto también le da más libertad para depurar las respuestas de su aplicación.

La otra cosa que Dave Cheney mencionó es usar el conector tomcat nativo para tener equilibrio de carga y otras características.

cero_r
fuente
Bueno, tengo dos razones para elegir esa configuración. Lo primero es que el servidor Tomcat ya está en funcionamiento en SSL y pensé que sería simple usar Apache VirtualHost con él. El segundo es que el proveedor de la aplicación (JIRA) proporciona algunas pautas para la integración de apache ( atlassian.com/software/jira/docs/v3.13/apacheintegration.html ) y basé mi configuración en él agregando soporte VirtualHost. Supongo que fue más complejo de lo que pensaba, además de hacerlo funcionar, realmente quiero entender cuál es el problema.
JMD
0

¿Realmente necesita un proxy para un servicio HTTPS? Es posible que desee proxy al servicio no SSL en localhost, por ejemplo

ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
cabeza de código
fuente
De hecho, usar SSL es obligatorio para mí. También probé el proxy sin usar SSL solo para verificar y funciona bien. El soporte SSL es el verdadero problema.
JMD
0

Primero, miraría si puede hacer una solicitud de localhost a localhost: 8443 y ver si eso es exitoso (es decir, hacer un GET o wget http: // localhost: 8443 )

No estoy muy seguro de por qué su host virtual havin ga escucha en el puerto 443 y luego lo envía a otro host SSL

¿Por qué la aplicación no puede usar 443 de forma nativa? si no puede cambiarlo, puede usar iptables para redirigir el puerto

Brendan
fuente
La razón es que necesito instalar más aplicaciones web en el mismo servidor, todas usando SSL y no todas pueden escuchar en el puerto 443. Así que estoy usando VirtualHosts basados ​​en IP para que parezca que cada aplicación web está alojada en su propio servidor. Probé el siguiente comando wget y funciona bien: wget localhost: 8443 --no-check-certificate
JMD
2
Nota: es una cuestión simple agregar direcciones IP adicionales a su servidor y, por lo tanto, tener varias aplicaciones escuchando en el puerto 443, todas en direcciones IP separadas.
Brent
0

Verifique su registro de errores SSL y asegúrese de no tener errores acerca de no poder verificar la cadena de certificados de CA.

Neobyte
fuente
Si efectivamente hay errores de verificación, ¿cuál sería la solución?
Javier Méndez