apache - letsencrypt - haproxy ssl passthrough
Convencer a Apache del protocolo original del cliente (2)
El directorio slash redirige: lo que quiere es
mod_rewrite
.RewriteEngine On RewriteCond %{HTTP:X-Forwarded-Proto} =https RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^(.+[^/])$ https://www.example.com/$1/ [R=301,L,QSA]
Si el encabezado está establecido en
https
y el nombre de archivo solicitado es un directorio (-d
), entonces vuelva a escribir eso (reemplaceexample.com
con su propio dominio).En cuanto a hacer que PHP trate la conexión como una conexión HTTPS normal, establezca la variable de entorno
HTTPS
on
:SetEnvIf X-Forwarded-Proto https HTTPS=on
Así que tengo una pila de servidores relativamente sencilla que utiliza una descarga de SSL y un equilibrador de carga HTTP. La configuración se ve así:
(client) -> (SSL offload - stud) -> (balancer - haproxy) -> (http server - apache)
Mi pregunta no es sobre tapar todo esto. Funciona de maravilla, y sinceramente estoy impresionado de lo sencillo que ha sido configurar esto. También agregaré que los clientes HTTP se conectan directamente a haproxy, omitiendo así el SSL descargado. Y para el registro, hay socios redundantes para cada una de las piezas anteriores.
El problema es algo abstracto. Comenzaré con una demostración. El cliente realiza una solicitud a través de la configuración a https://myserver.tld/scp
(algunos encabezados se eliminaron para mantener las cosas claras)
GET /scp HTTP/1.1
Host: myserver.tld
(headers added by haproxy)
X-Forwarded-For: [original::client:ip]
X-Forwarded-Proto: https
Y el servidor responde con
HTTP/1.1 301 Moved Permanently
Date: Wed, 03 Jul 2013 03:16:25 GMT
Server: Apache/2.2.15 (CentOS)
Location: http://myserver.tld/scp/
Content-Length: 344
Content-Type: text/html; charset=iso-8859-1
Entonces Apache mod_dir
está enviando un redireccionamiento a la misma URL con una barra inclinada. Es apropiado hacerlo. Ese no es el problema. El problema es que el protocolo HTTPS se perdió. Una vez más, creo que Apache está en lo correcto al redirigir a una URL HTTP, después de todo, la conexión que recibió de la pila mencionada anteriormente es una conexión HTTP regular.
Entonces, desde la perspectiva de Apache, el cliente solicitó una conexión HTTP regular. El indicador HTTPS está desactivado, junto con toda la demás información SSL, porque la parte SSL de la sesión la gestiona Stud.
Aunque (dentro de Apache) tengo un encabezado X-Forwarded-Proto
válido, no puedo encontrar una manera de decirle a Apache que la conexión del cliente original fue HTTPS y que el directorio slash redirigir por mod_dir
debe usar el protocolo https://
. ¿Qué me estoy perdiendo?
Lo único que se me ocurre es volver a escribir el encabezado Location
dentro de haproxy para HTTPS reenviar las conexiones para reemplazar http://
con https://
, pero realmente no creo que ese enfoque sea muy elegante. Preferiría Apache (y ( no me lastime ) PHP más abajo en la cadena) estar informado y tratar la conexión como una conexión HTTPS normal.
¡Por favor ayuda!
PD - He escuchado decirlo antes si tienes que preguntar, entonces lo estás haciendo mal. Tal vez esa es la raíz del problema aquí, pero parece un dilema tan simple y me siento como el único que ha llegado aquí.
Puede hacer esto al incluir el protocolo en la directiva ServerName:
ServerName https://my-server-name
De acuerdo con los documentos de Apache:
En ocasiones, el servidor se ejecuta detrás de un dispositivo que procesa SSL, como un proxy inverso, un equilibrador de carga o un dispositivo de descarga de SSL. Cuando este sea el caso, especifique el esquema https: // y el número de puerto al que se conectan los clientes en la directiva ServerName para asegurarse de que el servidor genera las URL autorreferenciales correctas.