2017-09-29 2 views
0

Je veux sécuriser une collection d'API web que j'écris. L'accès à ces API doit être accordé aux abonnés jusqu'à l'expiration de l'abonnement; les API sont consommées par les services Web distants. Donc, je pensais que Mutual SSL est le meilleur moyen de le faire. J'essaie de configurer ma propre autorité de certification pour délivrer des certificats x509 aux clients.Nginx Mutual Auth pour la consommation Rest API

C'est la première fois que je fais cela; donc, naturellement, rien ne fonctionne.

Voici ce que je veux obtenir en tant que résultat final: je déploie mes API en utilisant Nginx comme proxy inverse; si le client envoie un certificat valide à Nginx, le proxy inverse accepte la connexion et transmet les demandes; la connexion est fermée sinon. Chaque fois qu'un nouveau client signe un abonnement, je génère un nouveau certificat et l'envoie à lui/elle.

Je suivis this guide, qui me semblait être plus complet que d'autres que je lis, et je mis un auto-signé ca.crt à /etc/ssl/ca/cert pour la signature des CSR s reçus des clients et je mis en place nginx comme

server { 
    listen *:443 ssl; 
    server_name  api.example.com; 
    ssl_dhparam /etc/ssl/certs/dhparam.pem; 
    ssl_certificate /etc/ssl/certs/server.pem; #certificate from an actual CA 
    ssl_certificate_key /etc/ssl/private/server.key; #PK of server.pem 
    ssl_client_certificate /etc/ssl/ca/certs/ca.crt; 
    ssl_crl /etc/ssl/ca/crl/ca.crl; 
    ssl_verify_client on; 
    ssl_protocols TLSv1.1 TLSv1.2; 
    ssl_prefer_server_ciphers on; 
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; 
    ssl_ecdh_curve secp384r1; 
    ssl_session_cache shared:SSL:10m; 
    ssl_session_tickets off; 
    ssl_stapling on; #ensure your cert is capable 
    ssl_stapling_verify on; #ensure your cert is capable 
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; 
    add_header X-Frame-Options DENY; 
    add_header X-Content-Type-Options nosniff; 
    #Redirects all traffic 
    location/{ 
     proxy_pass http://mysecuredserver/api$request_uri; 
     limit_req  zone=one burst=10; 
    } 
} 

Mais quand je consomme une Test api (il répond toujours avec un 200 OK) en utilisant

curl -k -v --key key.pem --cert cert.pem https://api.example.com/Test 

je reçois toujours l'erreur suivante:

< HTTP/1.1 400 Bad Request 
* Server nginx is not blacklisted 
< Server: nginx 
< Date: Fri, 29 Sep 2017 18:00:16 GMT 
< Content-Type: text/html 
< Content-Length: 224 
< Connection: close 
< 
<html> 
<head><title>400 The SSL certificate error</title></head> 
<body bgcolor="white"> 
<center><h1>400 Bad Request</h1></center> 
<center>The SSL certificate error</center> 
<hr><center>nginx</center> 
</body> 
</html> 
* Closing connection 0 
* SSLv3, TLS alert, Client hello (1): 

Quelqu'un pourrait-il m'expliquer ce qui ne va pas?

Deuxième question: dans ssl_certificate Je mets le CERT que j'ai acheté d'une CA valide: est-ce exact ou devrais-je mettre un CERT généré en utilisant le ca.crt à la place?

+0

Prenez les étapes suivantes. Vous voulez prendre une étape à la fois. 'Étape 1. Votre certificat SSL fonctionne'. Supprimez donc ssl_verify_client; ssl_client_certificate /etc/ssl/ca/certs/ca.crt; '.Voyez si vous vous connectez bien en utilisant 'curl -v https: // api.example.com/Test'. Étape 2 - Ajouter un certificat client et rendre la vérification facultative. Ajoutez 'ssl_verify_client facultatif, ssl_client_certificate /etc/ssl/ca/certs/ca.crt;'. Dans 'location /' ajouter 'return 200" Client cert status - $ ssl_client_verify ". Cela vous indiquera si le serveur a pu vérifier le certificat ou non –

+0

Étape 1: fonctionne correctement. Étape 2 avec 'ssl_verify_client facultatif': 400 Demande incorrecte, même message – GoGoLander

+0

Change' ssl_verify_client off', puis essaie et aussi ce que dit le journal nginx? –

Répondre

1

Comme discuté lorsque vous ne recevez pas beaucoup de journaux à Nginx, vous devez ajouter

debug_connection <IP>; 

Il va générer plus de journaux. Qui a montré

2017/09/29 20:27:55 [info] 28783#0: *72 client SSL certificate verify error: (3:unable to get certificate CRL) while reading client request headers 

Cette erreur se produit lorsque vous ne fournissez pas CRL pour chaque certificat de la chaîne ssl_client_certificate.

Voici fil similaire montrant la même question

https://serverfault.com/questions/501912/nginx-proxy-ssl-clr-400-bad-request-error

Nginx unable to get certificate CRL

Vous devez spécifier la directive ssl_crl et lui donner le fichier CRL

ssl_crl /etc/ssl/certs/crl/ca.crl; 

De plus, vous devriez vérifier que ssl_certificate fait référence au certificat créé par votre autorité de certification pour votre serveur:

ssl_certificate /etc/ssl/ca/certs/server.pem;  #signed by your CA 

ssl_certificate_key /etc/ssl/ca/private/server.key; #PK used to generate 
                #server.pem 

ssl_client_certificate /etc/ssl/ca/certs/ca.crt; 

ssl_crl /etc/ssl/ca/crl/ca.crl;      #CRL of the 
                #ssl_client_certificate and 
                #its chain