¿Cómo usar ssl_verify_client = ON en un servidor virtual y ssl_verify_client = OFF en otro?

9

Quiero forzar la verificación del cliente SSL para uno de mis hosts virtuales. Pero aparece el error "No se envió el certificado SSL requerido", intentando obtener algo de él.

Aquí están mis configuraciones de prueba:

# defaults                                                                                                                                                                    
ssl_certificate /etc/certs/server.cer;                                                                                                                                 
ssl_certificate_key /etc/certs/privkey-server.pem;                                                                                                                     
ssl_client_certificate /etc/certs/allcas.pem;                                                                                                                                 

server {                                                                                                                                                                      
    listen 1443 ssl;                                                                                                                                                          
    server_name server1.example.com;                                                                                                                                          
    root /tmp/root/server1;                                                                                                                                                   

    ssl_verify_client off;                                                                                                                                                    
}                                                                                                                                                                             

server {                                                                                                                                                                      
    listen 1443 ssl;                                                                                                                                                          
    server_name server2.example.com;                                                                                                                                          
    root /tmp/root/server2;                                                                                                                                                   

    ssl_verify_client on;                                                                                                                                                     
} 

El primer servidor responde con 200 códigos http, pero el segundo devuelve "400 Solicitud incorrecta, no se envió ningún certificado SSL requerido, nginx / 1.0.4".

Probablemente, ¿es imposible usar ssl_verify_client en la misma IP? ¿Debo vincular estos servidores a diferentes IP? ¿Resolverá mi problema?

Alexander Artemenko
fuente

Respuestas:

4

Me encontré con un problema similar, pero busco distinguir ssl_verify_clientsentre bloques de ubicación dentro de un bloque de servidor, en lugar de entre bloques de servidor. Probablemente podría resolver su problema moviendo el material de configuración SSL predeterminado a los dos servidores (duplicándolo, seguro, o colocándolos todos en un bloque de servidor, acepte los múltiples subdominios y use ubicaciones).

Para la solución basada en la ubicación, se parece a los siguientes trabajos. Utilizar

ssl_verify_client optional;

en el bloque del servidor y use sentencias if en las distintas ubicaciones, por ejemplo:

if ($ssl_client_verify != SUCCESS) { return 403; }

Necesitaba hacer esto para dar acceso de administrador a una aplicación web, y aún así permitir webhooks desde github sin darle a github un certificado SSL de cliente.

Ethan
fuente
2

Debe actualizar al menos a nginx> = 1.0.9 si desea tener varios hosts virtuales basados ​​en nombres (usando SNI) en la misma dirección IP y puerto, pero con diferentes ssl_verify_clientconfiguraciones para estos hosts.

En versiones anteriores de nginx, la ssl_verify_clientconfiguración del host virtual predeterminado se usaba para todos los demás hosts virtuales basados ​​en nombres en la misma combinación de puerto IP +. Algunas otras opciones SSL ( ssl_verify_depth, ssl_prefer_server_ciphers) también se manejaron de la misma manera. El uso de una IP o puerto por separado podría ser una solución si no puede actualizarse.

Nota del registro de cambios de nginx para 1.0.9:

*) Bugfix: the "ssl_verify_client", "ssl_verify_depth", and
   "ssl_prefer_server_ciphers" directives might work incorrectly if SNI
   was used.

Cambios relevantes en la fuente nginx: r4034 en el tronco, r4246 en la rama 1.0.

Sergey Vlasov
fuente
0

¿Ha cargado el certificado de cliente (en formato PKCS12) firmado por la CA "/etc/certs/allcas.pem" en su navegador? En Firefox, puede verificar los certificados de sus clientes en Preferencias -> Avanzado -> Cifrado -> Ver certificados -> Sus certificados.

El valor del parámetro "ssl_verify_client" si está "desactivado" de forma predeterminada. También puede usar el valor "opcional" si el certificado de cliente SSL no es obligatorio.

usuario1025596
fuente
Estoy acostumbrado a curl --cert ... con los mismos resultados.
Alexander Artemenko
¿Hay algo interesante en el registro de errores de nginx? (probablemente /var/log/nginx/error.log)
user1025596
0

No soy un experto en nginx, pero he visto problemas similares con apache usando SSL y hosts virtuales. El problema es el orden en que el servidor maneja la negociación SSL frente a la elección del host virtual. El primer paso es establecer la conexión encriptada, y solo después de eso, el servidor ve qué nombre de host está solicitando. Y hasta que lo sepa, usará la configuración predeterminada, que en este caso es el primer host, que requiere un certificado de cliente para establecer la conexión SSL.

Entonces, respuesta corta: en este caso, sería mejor tener puertos separados o direcciones IP separadas.

Jenny D
fuente
-1

Encontré el mismo problema y encontré una solución.

Intente agregar una default_servermarca para el segundo servidor

listen 443 ssl default_server;
yfliu
fuente