Client authentication using self signed ssl certificate for nginx - authentication

I am hosting a nginx webserver in my LAN and I want to authenticate client who are accessing my server with ssl client certificate.I generated a self signed SSL certificate and one client certificate following some documents on google. But I am unable to authenticate client who has certificate. I am getting the following errors
When requested from Firefox:
2017/08/10 18:30:13 [info] 8994#0: *4 client sent no required SSL certificate while reading client request headers, client: 192.168.16.27, server: 192.168.26.43, request: "GET /hls1/master.m3u8 HTTP/1.1", host: "192.168.26.43"
When request using curl:
curl -v -s -k --key client.key --cert client.crt --cacert ca.crt https://192.168.26.43/hls2/master.m3u8
2017/08/10 18:30:33 [info] 8994#0: *5 client SSL certificate verify error: (18:self signed certificate) while reading client request headers, client: 192.168.16.27, server: 192.168.26.43, request: "GET /hls2/master.m3u8 HTTP/1.1", host: "192.168.26.43"
So,my question is can I use self-signed certificate to authenticate client?If so, can anyone provide the steps to achieve this?

I just stumbled over this and discovered a small pitfall which caused the same error you encountered:
error 18 at 0 depth lookup: self signed certificate
There are plenty of guides how to create a self signed client certificate, I used the following (adapted from here):
# Create the CA Key and Certificate for signing Client Certs
openssl genrsa -des3 -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
# Create the Client Key and CSR
openssl genrsa -des3 -out client.key 4096
openssl req -new -key client.key -out client.csr
# Sign the client certificate with our CA cert
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
# Convert to .p12 so import in OSX works
openssl pkcs12 -export -clcerts -inkey client.key -in client.crt -out client.p12 -name "MyKey"
However, if you use the same Organization Name (eg, company) for both your ca and your client certificate, you will see above error! (edited: important)
If openssl verify -verbose -CAfile ca.crt client.crt does not complain about a self-signed certificate, you're good to go.

The server has to trust the client certificate. In the case of a self-signed certificate, that means the certificate has to be exported from the client's keystore and imported into the server's truststore.
When the server asks for the client certificate, it also sends a list of trusted signers, and the client is only allowed to send a certificate which is ultimately signed by one of those signers. As the server didn't know about the self-signed client certificate, it didn't include that as a trusted signer, so the client was unable to send its certificate. Hence client sent no required SSL certificate while reading client request headers.

Related

how to remove or revoke openssl self signed certificates

Recently i have created self signed ssl certificates with the following commands
STEP 1: Create the server private key
openssl genrsa -out main.key 2048
STEP 2: Create the certificate signing request (CSR)
openssl req -new -key main.key -out main.csr
STEP 3: Sign the certificate using the private key and CSR
openssl x509 -req -days 365 -in tls.csr -signkey main.key -out main.crt
i haven't added ssl certificate info, in to my apache default file in : site-enabled config folder
but after an apache restart it took effect and i am able get https connection, but with a warning.
now i want to remove those self signed certificate. is that possible ?
i tried to revoke those certificates with this command - openssl ca -config /root/tls/openssl.cnf -revoke /certs/server-1.crt
but the above command didnt work .
i am currently very new to ssl certificate generation. any help is appreciated.

Why does NOT my certificate chain contain the CA root certificate?

I simulate a CA on a centos7 host(azcn-gs1-nginx2), and use the CA to sign a certificate for a server(azcn-gs1-nginx1).
Below are what I do:
On CA azcn-gs1-nginx1, generate key
cd /etc/pki/CA/private/
openssl genrsa -aes128 -out testCA.key 2048
Generate CA certificate
openssl req -new -x509 -days 1825 -key /etc/pki/CA/private/testCA.key -out /etc/pki/CA/certs/testCA.crt
On the server azcn-gs1-nginx2, generate private key and certificate sign request.
openssl genrsa -out /etc/pki/tls/private/newServer.key 1024
openssl req -new -key /etc/pki/tls/private/newServer.key -out /etc/pki/tls/newServer.csr
Copy newServer.csr to CA host for signing.
scp /etc/pki/tls/newServer.csr root#azcn-gs1-nginx2:~/newServer.csr
On CA host, sign the newServer.csr, and copy back the newServer.crt
to server azcn-gs1-nginx2.
openssl x509 -req -in ./newServer.csr -CA /etc/pki/CA/certs/testCA.crt -CAkey /etc/pki/CA/private/testCA.key -CAcreateserial -out newServer.crt -days 1461
scp newServer.crt root#azcn-gs1-nginx2:/etc/pki/tls/certs/newServer.crt
Server azcn-gs1-nginx2 is a reverse proxy for a webservice. I configure the newServer.key and newServer.crt in Nginx for https.
ssl_certificate /etc/pki/tls/certs/newServer_1.crt;
ssl_certificate_key /etc/pki/tls/private/newServer.key;
I am on another Ubuntu host. I import the CA's certificate testCA.crt into Ubuntu truststore, as below:
cp testCA.crt /usr/local/share/ca-certificates/
update-ca-certificates
The Ubuntu's built-in browser is firefox. I also import testCA.crt
into firefox's truststore. Please see attached pic.
I open firefox browser and visit web server by https. Expected result is it can directly open webpage without security warning.
Unfortunately, it gives warning of "Your connection is not secure.....".
and, looks like the certificate only contains the certificate itself. It doesn't not contain CA's certificate.
Why this happen? How can I get a signed certificate with the CA's certificate in Chain?
Thanks & regards,
Jie
Thanks for your comments.
That's right.
Actually, it is very simple. The 2 .crt files of CA and server can be concatenated into one .crt. Then the certificate chain is a whole.
Right, the pictures of 2 and 3 are other problems.
Thanks,
Jie

RSA 2048 self signed certificate not being accepeted by NLB TCP listener

i am trying to create a self signed certificate using openssl following the docs https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https-ssl.html
i tried to add the generated private and public pem files to my NLB TCP listener as a self signed certificate and it is failing with the below exception.
Error creating listener The imported certificate's configuration is not compatible and will not appear in the list of available certificates for your listeners. Select or upload a different certificate and try again.
I saw that NLB allows RSA 2048 certs. Not sure why the console is showing the error display.
You need to generate a RSA 1024 or 2028 certificate. check the valid certificates that ACM supports. i used the below commands to generate the self signed certificate
openssl genrsa -out private-key.pem 1024
openssl rsa -in private-key.pem -pubout -out public-key.pem
openssl req -new -x509 -key private-key.pem -out cert.pem -days 3600
mention the country, state and domain name. I initially missed the domain name because of which NLB listener wasn't accepting the certificate.

Must server and client certificate be signed by same CA in SSL

I am trying to understand the relationship between the client and server in the context of an SSL connection. Am I correct in understanding that the fact that the same certificate authority (me - in example below) sign both server and client certificate makes that they can communicate. Thus, that the server only accepts communication when client authenticates with client certificate signed by the same CA as the server certificate, and this is essential to the idea of an SSL connection?
(script underneath comes directly from http://blog.nategood.com/client-side-certificate-authentication-in-ngi)
# Create the CA Key and Certificate for signing Client Certs
openssl genrsa -des3 -out ca.key 4096
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
# Create the Server Key, CSR, and Certificate
openssl genrsa -des3 -out server.key 1024
openssl req -new -key server.key -out server.csr
# We're self signing our own server cert here. This is a no-no in production.
openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
# Create the Client Key and CSR
openssl genrsa -des3 -out client.key 1024
openssl req -new -key client.key -out client.csr
# Sign the client certificate with our CA cert. Unlike signing our own server cert, this is what we want to do.
openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
server {
listen 443;
ssl on;
server_name example.com;
ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;
ssl_client_certificate /etc/nginx/certs/ca.crt;
ssl_verify_client on;
The short answer is No. These are two separate aspects.
Here:
ssl_certificate /etc/nginx/certs/server.crt;
ssl_certificate_key /etc/nginx/certs/server.key;
You are configuring the server certificates which need to be trusted by the client.
And here:
ssl_client_certificate /etc/nginx/certs/ca.crt;
You configure the certification authority to verify your clients' certificates against.
"Must server and client certificate be signed by same CA in SSL"
Short answer is, it can be but not necessary.
To see why, let's break down the steps but without too much technical.
From your point of view when setting up the nginx server.
You want to achieve 2 goals.
Prove the identity of your server.
For this you get a CA to sign your server certificate and
present it to a client that connects to your server
Verify the identity of the client connecting to the server
For this, you set define the list of CA that you trust that signs the client's certificate.
When a client connects to your server, you check if the client certificate presented is signed by your list of CA
That's not the end. Let's look at the client's end.
The client also wants to achieve 2 goals.
Prove the client's identity when connecting to your server
For this, the client get a CA to sign its client certificate and
present it to your server when connecting.
Here is the catch, the CA that signs the client certificate must be in your server's list of CA.
Verify the identity of your server
For this, the client has to trust the CA that signs your server's certificate.
How is this done?
Typically this list is predefine on the system or browser so it happens transparently.
But if you are writing a client, then you may have to define this list of trusted CA or just let the client know the CA that signs your server certificate.
So, it can happen that the CA signing the server and the client is the same but it is not necessary. It all depends on the list of CA defined on both the server and the client.
Server certs and Client certs are used in completely different ways.
The only similarities are:
They both contain the word certificate
They both use public & private keys for encryption

How to get a certificate from a CA?

I need to get a certificate from a certificate authority with .crt extension.
I used openssl commands but it generates a self-signed certificate which is not suitable for my use.
$ openssl genrsa -out client.key 4096
$ openssl req -new -x509 -text -key client.key -out client.cert
How can I obtain a certificate form a CA in Ubuntu 16.04? I need .key and .crt files.
These are the steps you would need to do to get a certificate signed by a CA.
Generate a Asymmetric Key Pair.
openssl genrsa -out localhost.key 2048
Generate a PKCS#10 (Certificate Signing Request) from the Key Pair.
openssl req -new -sha256 -key localhost.key -out localhost.csr
Send the above generated request to the CA (different CA's have different ways of receiving your request).
CA replies with a PKCS#7 (Certificate Chain) or just the signed certificate (you will usually get the entire certificate chain, but if you just got only the peer certificate, you can check with them where you can get the CA certificate chain to construct the chain yourself).
You can convert the above received PKCS#7 to PEM format
openssl pkcs7 -in localhost.p7r -inform DER -out localhost.pem
-print_certs
Associate the above PEM certificate chain to the private key you generated in the step 1.
openssl pkcs12 -export -inkey localhost.key -in localhost.pem -name
sslCertificate -out localhost.pfx
You now have a PKCS#12 keystore that you can use to secure your server.
So to answer you question, this is how you could proceed with step 3.
There are many well known Certificate Authorities out there (GeoTrust, Entrust, Verisign, GoDaddy, Comodo, etc, ...). Each CA could be different on their pricing depending on what kind of certificate you are requesting. You can visit their official web page(s) to know more about what they have to offer. Once you have decided which CA to go with, you use their service to request a certificate to be signed (usually online on their site).