Tengo un montón de preguntas con respecto a SSL, sesiones locales y equilibrio de carga que parecen estar interconectadas, por lo que me disculpo de antemano por la extensión de esta pregunta.
Tengo un sitio web que utiliza sesiones basadas en archivos. La naturaleza del sitio es que la mayor parte es http, pero algunas secciones son ssl. Actualmente, debido a las sesiones basadas en archivos, es necesario que cualquier solicitud de SSL llegue al mismo servidor que cualquier solicitud http anterior.
Debido a limitaciones de tiempo, quiero hacer lo más fácil posible para equilibrar la carga y aumentar el tráfico http y ssl.
Parece que hay 2 opciones para algoritmos de equilibrio de carga fijos:
- basado en ip
- basado en cookies
La solución basada en IP probablemente funcionará, pero el algoritmo de hash cambiará potencialmente el servidor al que va un usuario cuando un servidor deja de funcionar o se agrega, lo que no es deseable con la configuración actual de la sesión basada en archivos. También supongo que es técnicamente posible que un usuario cambie legítimamente ips mientras navega por un sitio web.
El algoritmo basado en cookies parece mejor, pero la incapacidad de inspeccionar la cookie cuando está encriptada por SSL aparentemente presenta sus propios problemas.
He buscado en Google ejemplos sobre cómo cargar el equilibrio de carga SSL, y parece que no puedo encontrar ejemplos explícitos de configuraciones que puedan hacer un equilibrio de carga basado en cookies Y que puedan lidiar con un aumento de la carga SSL agregando otro decodificador SSL.
La mayoría de los ejemplos explícitos que he visto tienen el decodificador ssl (generalmente hardware, apache_mod_ssl o nginx) ubicado entre el cliente del navegador y el equilibrador de carga. Los ejemplos generalmente parecen tener algo como esto (modificado de http://haproxy.1wt.eu/download/1.3/doc/architecture.txt ):
192.168.1.1 192.168.1.11-192.168.1.14 ------- + ----------- + ----- + ----- + ----- + El | El | El | El | El | + - + - + + - + - + + - + - + + - + - + + - + - + El | LB1 | El | A | El | B | El | C | El | D | + ----- + + --- + + --- + + --- + + --- + Apache 4 servidores web baratos mod_ssl haproxy
La parte de decodificación de SSL en el ejemplo anterior parece ser un posible cuello de botella que no es escalable horizontalmente.
He examinado haproxy, y parece tener una opción 'mode tcp' que permitiría algo como esto, que le permitiría tener múltiples decodificadores ssl:
haproxy El | ------------- El | El | ssl-decoder-1 ssl-decoder2 El | El | ------------------- El | El | El | web1 web2 web3
Sin embargo, en tal configuración, parece que perdería la IP del cliente porque haproxy no está decodificando el ssl: https://cloud-support.engineyard.com/discussions/problems/335-haproxy-not-passing-x-forward -para
También he examinado nginx, y tampoco veo ningún ejemplo explícito de decodificadores ssl escalables horizontalmente. Parece que hay muchos ejemplos de personas que tienen nginx como un posible cuello de botella. Y al menos este enlace parece sugerir que nginx ni siquiera tiene la opción de una configuración similar a un haproxy en la que se pierde la ip al decir que nginx "no admite el paso transparente de conexiones TCP a un servidor" Cómo pasar Apache Tráfico SSL a través del proxy nginx? .
Preguntas:
- ¿Por qué no parece haber más ejemplos de configuraciones que agreguen más decodificadores SSL para lidiar con el aumento del tráfico?
- ¿Es porque el paso de decodificación ssl es solo un cuello de botella teórico, y prácticamente hablando, un decodificador será esencialmente suficiente, excepto para sitios con tráfico ridículo?
- Otra posible solución que viene a la mente es que cualquiera con necesidades de SSL tan elevadas también tiene un almacén de sesiones centralizado, por lo que no importa a qué servidor web acceda el cliente en solicitudes secuenciales. Entonces podría habilitar mod_ssl o equivalente en cada servidor web.
- La solución de haproxy citada anteriormente parece funcionar (además del problema de IP del cliente), pero alguien ha encontrado una solución equilibradora de carga de software basada en cookies que funcionaría al aumentar el número de decodificadores mientras se mantiene la IP del cliente, o es que técnicamente no posible (porque tiene que decodificar la solicitud para obtener la IP del cliente, en cuyo caso, tenemos un cuello de botella de decodificador).
Suponiendo que todo lo que he dicho es cierto, estas parecen ser mis opciones:
- use el hash de ip (malo para los usuarios que potencialmente cambian legítimamente ips, y para escenarios de agregar y quitar servidores)
- use nginx o mod_ssl como el primer programa que toca la solicitud de SSL, esto será un posible cuello de botella de decodificación de SSL
- use haproxy como el primer programa que toca la solicitud de SSL, ganando escalabilidad horizontal de SSL, pero vive sin ips registrados en el nivel del servidor web para solicitudes de SSL (probablemente temporalmente aceptable)
- a largo plazo, avance hacia una tienda de sesiones móvil o centralizada, haciendo innecesarias las sesiones adhesivas
fuente
Respuestas:
La "cosa más simple", con toda seriedad, es pasar a una tienda de sesión centralizada. Debe configurar toda esta plomería con equilibradores de carga, haproxy, SSL y el resto, cuando cada código de manejo de sesión que he visto hace que sea casi trivial conectar diferentes motores de almacenamiento, por lo que Un poco de código y muy, muy poca complejidad adicional resuelve todos sus problemas.
fuente
womble tiene razón sobre la tienda de sesiones compartidas que hace las cosas mucho más fáciles en general. Además de su respuesta, puedo ampliar un poco las partes de la pregunta sobre el equilibrio de carga:
Las PC modernas de varios núcleos pueden realizar varios miles de transacciones SSL por segundo. Y si eso se convierte en un cuello de botella, un dispositivo dedicado de F5 , Citrix, Cisco o similar puede ser aún más rápido. Por lo tanto, la mayoría de los sitios nunca superan una buena solución de equilibrio de carga y SSL de un solo dispositivo.
Hay opciones para escalar el descifrado SSL horizontalmente, si es que necesita esto.
El enfoque común es utilizar DNS Round Robin para pares de aceleradores SSL altamente disponibles, es decir, publicar múltiples direcciones IP para el dominio, cada dirección IP apunta a un par de aceleradores SSL.
En este caso, podría preocuparse de que el tiempo de espera de TTL de DNS se agote en el medio de una sesión de usuario, lo que lleva al usuario a otro servidor de aplicaciones. Eso no debería ser una ocurrencia común, pero podría suceder. Un almacén de sesión compartido es la solución común, pero se puede manejar de otras maneras.
Como ejemplo, podría separar el descifrado SSL del equilibrio del servidor de aplicaciones. El manejo de SSL requiere más CPU que el equilibrio de carga básico, por lo tanto, un solo equilibrador de carga debería poder saturar un par de aceleradores SSL. Me gusta esto:
Internet --> DNS round robin to multiple SSL accelerators --> plain HTTP to a single HTTP load balancer --> plain HTTP to multiple application servers
Como se mencionó al principio, un almacén de sesión compartida simplifica muchas cosas y es casi seguro una mejor solución a largo plazo que poner mucha complejidad en su capa de equilibrio de carga / SSL.
fuente
Es divertido responder a preguntas de 2 años como esta cuando los productos han evolucionado. En este momento, haproxy admite el protocolo PROXY, que le permite pasar la IP del cliente al siguiente salto incluso en modo TCP puro. También es compatible con SSL nativo, así como con la adherencia SSL si desea usarlo como una primera capa frente a una granja de servidores SSL (posiblemente hecha de servidores haproxy). Parece que su solicitud se adelantó un poco y que las implementaciones se han puesto al día :-)
fuente
Estoy de acuerdo con womble y Jesper aquí. La ruta más fácil / mejor es arreglar el código. Por supuesto, como administradores de sistemas a menudo no tenemos esa opción, pero incluso en ese caso hay suficientes trucos que puede hacer para obtener hardware moderno relativamente barato para escalar lo suficientemente lejos, aunque no sea realmente horizontal.
Solo quería publicar para comentar dónde le preocupa perder la IP del cliente. En cualquiera de las principales soluciones L7 / proxy, puede insertar un encabezado X-Fordered-For (o lo que desee) en la solicitud. Luego, en el servidor web de fondo que recibe la solicitud, puede cambiar el formato del archivo de registro para registrar ese valor en el mismo espacio en el archivo que usó para registrar la IP del cliente layer3. De esa manera, ningún software de análisis de registros ve la diferencia (ni usted tampoco cuando hace la cola).
Hay compensaciones para todo y no hemos escuchado lo suficiente sobre su configuración para saberlo, pero con el trío de no-puede-equivocarse de ha-proxy, nginx y barniz, es probablemente una buena idea mover su equilibrio de carga a una herramienta de capa proxy. Eso resolverá su problema de SSL y le brindará una gran cantidad de nuevas opciones como almacenamiento en caché, cambio de contenido y manipulación de encabezados.
fuente
Algunos pensamientos al azar;)
Primero, dispare a la persona que decidió usar datos de sesión basados en archivos. No hay forma de que leer / escribir datos de un sistema de archivos sea más rápido que simplemente regresar a la fuente para obtener los datos que necesita. Esta es la PEOR manera de hacerlo.
Personalmente, nunca he visto una situación en la que almacenar datos en una sesión fuera mejor que simplemente extraerlos directamente de la base de datos según sea necesario. Dicho esto, he visto dónde usar memcache o estrategias de almacenamiento en caché similares puede ayudar a un sitio a escalar a millones de usuarios, pero eso ni siquiera está en el mismo estadio que usar sesiones.
En segundo lugar, acaba de encontrar la razón número uno para no usar sesiones: el equilibrio de carga. FYI - Pegajoso no significa atascado. Incluso con las sesiones Sticky activadas, usted corre la posibilidad muy real de que el usuario sea trasladado a otro servidor en medio del uso de su aplicación. Esto sucederá en los momentos más inoportunos. Pegajoso solo significa que el equilibrador de carga intentará empujar al usuario de vuelta al servidor en el que comenzó, pero de ninguna manera es una garantía.
Este punto generalmente lleva a las personas a almacenar la sesión nuevamente en la base de datos ... Lo que creo que es un completo fracaso . Para que la sesión funcione, debe cargarse y escribirse en cada solicitud de página. Cuando se almacena en una base de datos (necesaria para servidores con equilibrio de carga), esto requiere dos consultas del servidor: la primera para obtener los datos, la segunda para escribir las actualizaciones.
La parte de falla es que las personas usualmente usan sesiones para no tener que volver a la base de datos para extraer cosas como el nombre de los usuarios ... Pero si la página tiene que consultar la base de datos para cargar una sesión, entonces ... bueno, deberías poder ver el problema lógico aquí.
Solo que es peor con las sesiones ... porque el procesador de páginas tiene que volver a escribir los datos de la sesión en la base de datos al final del ciclo de vida de la página ... en caso de que algo cambie. Lo que significa que en lugar de la única consulta para extraer el nombre de ese usuario, terminas con dos. Por cada carga de página. Además, significa serializar y deserializar los datos que tienen su propio impacto en el rendimiento.
Mi punto es: la sesión es malvada y generalmente estás mejor sin ella. Los sitios de bajo tráfico que solo se ejecutan en un servidor web no necesitan el aumento de rendimiento que puede ocurrir; y los sitios de alto tráfico que se ejecutan en una granja de servidores web tienen escalas limitadas debido a ello.
fuente
En lugar de usar Haproxy en el frente, puede usar DNS round robin para hacer un equilibrio aproximado entre múltiples decodificadores SSL y luego pasarlo a haproxy para el equilibrio de carga adecuado.
fuente