How do I install a CA bundle on Laravel Forge? - nginx

I've got an application that's getting SSL warnings on Chrome for Android and it turns out I need to add my CA Bundle from RapidSSL. I don't see a way to do this using Laravel Forge. How can I accomplish this?
My nginx config was auto-generated by Laravel Forge and looks like this:
# FORGE SSL (DO NOT REMOVE!)
ssl on;
ssl_certificate /etc/nginx/ssl/mydomain.com/1646/server.crt;
ssl_certificate_key /etc/nginx/ssl/mydomain.com/1646/server.key;

Status before: untrusted page
I had the same issue with a comodo certificate from https://cheapsslsecurity.com/. At first I installed only the domain specific certificate via the laravel forge webinterface (www_timtimer_at.crt) which resulted in an untrusted page.
Stumbling upon the answer of #Citizen and the post Nginx not serving intermediate certificate helped me to fix it. See this post also for debugging instructions.
How to fix the problem
SSL-Status
Use openssl s_client -connect www.timtimer.at:443 to check the certificate chain. (As am I am using Windows I just used the git bash to use this command). It should be a real chain like the following (s=subject, i=issuer). So you always have a subject with an issuer. This issuer should be the next subject which is issued by another authority and so on. The last subject is itselfs issuer.
At first my certificate chain looked like the following:
Certificate chain
0 s:/OU=Domain Control Validated/OU=PositiveSSL/CN=www.timtimer.at
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
The Verify return code was: 21 (unable to verify the first certificate).
Solution
Check your server configuration file (I am using Laravel forge with nginx, so my file would be /etc/nginx/sites-available/default to get the location of the certificate you are using. Look out for the following section
# FORGE SSL (DO NOT REMOVE!)
ssl_certificate /etc/nginx/ssl/default/2658/server.crt;
ssl_certificate_key /etc/nginx/ssl/default/2658/server.key;
So in my case the certificate is stored in /etc/nginx/ssl/default/2658/server.crt. Now edit this file and make sure you put all the needed certificates in there. I added the content of the certificates from the zip-file in the following order:
www_timtimer_at.crt
COMODORSAAddTrustCA.crt
COMODORSADomainValidationSecureServerCA.crt
AddTrustExternalCARoot.crt
The file should look like like the following
-----BEGIN CERTIFICATE-----
... (www_timtimer_at.crt)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... (COMODORSAAddTrustCA.crt)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... (COMODORSADomainValidationSecureServerCA.crt)
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
... (AddTrustExternalCARoot.crt)
-----END CERTIFICATE-----
After a /etc/init.d/nginx restart everything looked good.
I received the following certificate chain after executing openssl s_client -connect www.timtimer.at:443:
Certificate chain
0 s:/OU=Domain Control Validated/OU=PositiveSSL/CN=www.timtimer.at
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
3 s:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
The Verify return code was: 19 (self signed certificate in certificate chain).

Ok, so I solved this problem by doing the following:
Download the RapidSSL CA bundle:
https://knowledge.rapidssl.com/support/ssl-certificate-support/index?page=content&id=AR1549
Paste it below my certificate in a text file.
https://www.digicert.com/ssl-support/pem-ssl-creation.htm
Pasted the three certs in one into Laravel forge when it asks for my certificate.
And it worked!

Related

Mutal SSL authentication with Qt

I am new to ssl / networking and want to utilize mutal ssl ( client verifies server and server verifies peer) I found a white paper (http://www.infidigm.net/articles/qsslsocket_for_ssl_beginners/) online that gave me some guidance for setting up my certs and keys. Now this paper utilizes a local host ip address as the clients cert file. I want to switch this to a register domain name (scp.radiant.io). This FQDN is local to my ubuntu os for testing purposes
updated my localhost to have a domianname (scp.radiant.io). by modifying this file sudo nano /etc/hosts/ to say 127.0.0.1 scp.radiant.io localhost
Next I create certificate and private keys for both client and server
a. Steps for gen certs example for server below. same commands are run for client to create client certs
openssl req -out server_ca.pem -new -x509 -nodes -subj "/C=$COUNTRY/ST=$STATE/L=$LOCALITY/O=$ORG/OU=$ORG_UNIT/CN=server/emailAddress=radiant.$EMAIL"
mv privkey.pem server_privatekey.pem
touch server_index.txt
echo "00" >> server_index.txt
openssl genrsa -out server_local.key 1024
openssl req -key ${NAME}_local.key -new -out server_local.req -subj "/C=$COUNTRY/ST=$STATE/L=$LOCALITY/O=$ORG/OU=$ORG_UNIT/CN=scp.radiant.io/emailAddress=$EMAIL"
openssl x509 -req -in ${NAME}_local.req -CA ${NAME}_ca.pem -CAkey server_privatekey.pem -CAserial server_index.txt -out server_local.pem
b. this generates a CaCerts (server_ca.pem and client_ca.pem)
c. this generates a Local Cert files (server_local.pem and client_local.pem).. THIS IS WHERE I SET FQDN to scp.radiant.io
d. this generate a LocalKey (server_local.key and client_local.key)
I use the generated cert files for setting up the ssl configuration on the QSslSocket for both sides like so
//client socket setup
config.setPrivateKey("server_local.key");
config.setLocalCertificate("server_local.pem");
config.addCaCertificate("client_ca.pem");
config.setPeerVerifyMode("QSslSocket::VerifyPeer");
sslSocket->setSslConfiguration(config);
sslSocket->connectToHostEncrypted("scp.radiant.io",1200);
// server socket setup
config.setPrivateKey("client_local.key");
config.setLocalCertificate("client_local.pem");
config.addCaCertificate("server_ca.pem");
config.setPeerVerifyMode("QSslSocket::VerifyPeer");
sslSocket->setSslConfiguration(config);
sslSocket->startServerEncryption()
When running this code i get the following error in my ssl errors. "The host name did not match any of the valid hosts for this certificate
Now if I change the client socket to use this when connecting sslSocket->connectToHostEncrypted("scp.radiant.io",1200,"scp.radiant.io"); it will work.
I dont understand why I have to set the peerVerifyHost argument when connecting encrypted. I would like use the same certificates for my WebSockets implementation for this as well but the QWebSocket class does not allow you to set the peerverifyHost when connecting. So I must be doing something wrong at the cert level or the os level for my FQDN. any networking and ssl help would be helpful
I think you can ignore this error using "ignoreSslErrors" and let the handshake continue

Convert root certificate ,server certificate and intermediate certificate to .cert and .key file

I have three certificate files rootcertificate.txt, intermediateCertificate.txt, and serverCertificate.txt.
I want to install an SSL certificate on the Nginx server in the ubuntu platform and for this required two files yourdomain.cert and yourdomain.key
So my question is how to convert three files into .cert and .key format
No you can't, as I understand all you have are certificates
rootcertificate.txt is root CA certificate
intermediateCertificate.txt is Intermediate CA certificate, created by root CA
serverCertificate.txt is your server certificate, created by Intermediate CA certificate
for yourdomain.cert, you just need to rename serverCertificate.txt into yourdomain.cert
for yourdomain.key, it's not possible, you need to request the person who give you certificates for the private key
You need to build a certificate bundle (certificate chain). To do so, you just have to concatenate your three certificates. Make sure to have the Root CA on top of your chain, instead it won't work.
cat rootcertificate.txt intermediateCertificate.txt \
serverCertificate.txt > fullchain.txt
If your certificate are in DER format and you want to convert them in PEM before building your chain. You can use the ssl command below to convert your certificate in PEM.
openssl x509 -in serverCertificate.txt -out serverCertificate.pem \
-inform DER -outform PEM
You can use the same conversion to convert your private key in PEM also. Make sure to change in the "inform" in your certificate format they are not DER. Default value is PEM format.

Redirect www to non www godaddy with nginx

I have a website with non www url , i tried to redirect it using following steps -
For DNS i have used go daddy where
Type name value ttl
A # xx.xx.xx.xx 600 seconds
CNAME www # 1 Hour
In my Nginx configuraion i made following changes -
server {
listen 443;
server_name XAXA.com www.XAXA.com;
if ($host = XAXA.com) {
return 301 https://$host$request_uri;
}
return 404;
}
I am able to login my site with XAXA.com but whenever i try with www.XAXA.com i get - Your connection is not private
I am using let's encrypt for SSl.
The "connection is not private" warning is related to the certificate you present. Your browser is unable to verify that the certificate presented by the server is valid for www.xaxa.com
Without knowing the exact contents of your certificate I guess that your certificate doesn't have the proper Subject Alternative Name set up.
I'll be using openssl as an example of how to view contents of a certificate but you can use whatever you want.
I assume your certificate's Subject looks something like this
$ openssl s_client -connect xaxa.com:443 -showcerts | openssl x509 -subject -noout
CN = xaxa.com
This is fine and doesn't need to be changed. Depending on your browser it may not even be part of the validation process when verifying the certificate against the host.
I also assume your certificate's Subject Alternative Name looks something like this
$ openssl s_client -connect xaxa.com:443 -showcerts 2>/dev/null | openssl x509 -text -noout 2>/dev/null | grep -A 1 'Subject Alternative Name'
X509v3 Subject Alternative Name:
DNS:xaxa.com
What you want to achieve is a list in that Subject Alternative Name field:
$ openssl s_client -connect xaxa.com:443 -showcerts 2>/dev/null | openssl x509 -text -noout 2>/dev/null | grep -A 1 'Subject Alternative Name'
X509v3 Subject Alternative Name:
DNS:xaxa.com, DNS:www.xaxa.com
If you have several subdomains you could supply a wildcard value instead of www, ie. DNS:*.xaxa.com
How you actually achieve that with regards to Let's Encrypt depends on which ACME client implementation you're using.

Private certificate issue with chef server (knife ssl check - unable to get local issuer certificate)

I'm using open source chef12 server and I have created a private certificate for chef-server rather using self signed certificate. As i got error while using private certificate as below for "knife ssl check":
WARNING: There are invalid certificates in your trusted_certs_dir.
OpenSSL will not use the following certificates when verifying SSL connections:
c:/Users/test/.chef/trusted_certs/server.test.com.crt: unable to get local issuer certificate
I followed steps given in "https://docs.chef.io/server_security.html" for private certificate adding server.crt and root.crt and configured the nginx server. But when i tried "knife ssl fetch" it downloaded server.crt and root.crt seperately in trusted_certs folder and getting the same error for "knife ssl check" again.
Please help me how to configure chef-server with private cert without error.

SSL verification causes RCurl and httr to break - on a website that should be legit

i'm trying to automate the login of the UK's data archive service. that website is obviously trustworthy. unfortunately, both RCurl and httr break at SSL verification. my web browser doesn't give any sort of warning. i can work around the issue by using ssl.verifypeer = FALSE in RCurl but i'd like to understand what's going on?
# breaks
library(httr)
GET( "https://www.esds.ac.uk/secure/UKDSRegister_start.asp" )
# breaks
library(RCurl)
cert <- system.file("CurlSSL/cacert.pem", package = "RCurl")
getURL("https://www.esds.ac.uk/secure/UKDSRegister_start.asp",cainfo = cert)
# works
library(RCurl)
getURL(
"https://www.esds.ac.uk/secure/UKDSRegister_start.asp" ,
.opts = list(ssl.verifypeer = FALSE)
) # note: use list(ssl.verifypeer = FALSE,followlocation=TRUE) to see content
TL;DR
Get the TERENA SSL CA PEM file from TERENA's repository of trusted certificates and use this file as your cainfo parameter.
EDIT: You might need to add two lines to the beginning of that file. The code works for me using the following TERENA.pem file:
TERENA
======
-----BEGIN CERTIFICATE-----
MIIEmDCCA4CgAwIBAgIQS8gUAy8H+mqk8Nop32F5ujANBgkqhkiG9w0BAQUFADCB
lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt
SGFyZHdhcmUwHhcNMDkwNTE4MDAwMDAwWhcNMjAwNTMwMTA0ODM4WjA2MQswCQYD
VQQGEwJOTDEPMA0GA1UEChMGVEVSRU5BMRYwFAYDVQQDEw1URVJFTkEgU1NMIENB
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw+NIxC9cwcupmf0booNd
ij2tOtDipEMfTQ7+NSUwpWkbxOjlwY9UfuFqoppcXN49/ALOlrhfj4NbzGBAkPjk
tjolnF8UUeyx56+eUKExVccCvaxSin81joL6hK0V/qJ/gxA6VVOULAEWdJRUYyij
8lspPZSIgCDiFFkhGbSkmOFg5vLrooCDQ+CtaPN5GYtoQ1E/iptBhQw1jF218bbl
p8ODtWsjb9Sl61DllPFKX+4nSxQSFSRMDc9ijbcAIa06Mg9YC18em9HfnY6pGTVQ
L0GprTvG4EWyUzl/Ib8iGodcNK5Sbwd9ogtOnyt5pn0T3fV/g3wvWl13eHiRoBS/
fQIDAQABo4IBPjCCATowHwYDVR0jBBgwFoAUoXJfJhsomEOVXQc31YWWnUvSw0Uw
HQYDVR0OBBYEFAy9k2gM896ro0lrKzdXR+qQ47ntMA4GA1UdDwEB/wQEAwIBBjAS
BgNVHRMBAf8ECDAGAQH/AgEAMBgGA1UdIAQRMA8wDQYLKwYBBAGyMQECAh0wRAYD
VR0fBD0wOzA5oDegNYYzaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VS
Rmlyc3QtSGFyZHdhcmUuY3JsMHQGCCsGAQUFBwEBBGgwZjA9BggrBgEFBQcwAoYx
aHR0cDovL2NydC51c2VydHJ1c3QuY29tL1VUTkFkZFRydXN0U2VydmVyX0NBLmNy
dDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG
9w0BAQUFAAOCAQEATiPuSJz2hYtxxApuc5NywDqOgIrZs8qy1AGcKM/yXA4hRJML
thoh45gBlA5nSYEevj0NTmDa76AxTpXv8916WoIgQ7ahY0OzUGlDYktWYrA0irkT
Q1mT7BR5iPNIk+idyfqHcgxrVqDDFY1opYcfcS3mWm08aXFABFXcoEOUIEU4eNe9
itg5xt8Jt1qaqQO4KBB4zb8BG1oRPjj02Bs0ec8z0gH9rJjNbUcRkEy7uVvYcOfV
r7bMxIbmdcCeKbYrDyqlaQIN4+mitF3A884saoU4dmHGSYKrUbOCprlBmCiY+2v+
ihb/MX5UR6g83EMmqZsFt57ANEORMNQywxFa4Q==
-----END CERTIFICATE-----
Why?
The GET method of httr uses RCurl::curlPerform internally, as does RCurl::getURL, so the observed behavior is not surprising. The curl command-line tools with the "verbose" switch -v gives the following additional hints:
$ curl -v "https://www.esds.ac.uk/secure/UKDSRegister_start.asp"
* About to connect() to www.esds.ac.uk port 443 (#0)
* Trying 155.245.69.4...
* Connected to www.esds.ac.uk (155.245.69.4) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS alert, Server hello (2):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
The link in the above error message contains, at enumeration item 3, instruction on obtaining the server's certificate:
$ openssl s_client -connect "www.esds.ac.uk:443"
CONNECTED(00000003)
depth=0 C = GB, ST = Essex, L = Colchester, O = University of Essex, OU = UK Data Archive, CN = www.esds.ac.uk
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = GB, ST = Essex, L = Colchester, O = University of Essex, OU = UK Data Archive, CN = www.esds.ac.uk
verify error:num=27:certificate not trusted
verify return:1
depth=0 C = GB, ST = Essex, L = Colchester, O = University of Essex, OU = UK Data Archive, CN = www.esds.ac.uk
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
0 s:/C=GB/ST=Essex/L=Colchester/O=University of Essex/OU=UK Data Archive/CN=www.esds.ac.uk
i:/C=NL/O=TERENA/CN=TERENA SSL CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIEIzCCAwugAwIBAgIQO9FPWbAYKDAuFHq61U3gDDANBgkqhkiG9w0BAQUFADA2
MQswCQYDVQQGEwJOTDEPMA0GA1UEChMGVEVSRU5BMRYwFAYDVQQDEw1URVJFTkEg
U1NMIENBMB4XDTEwMTIwNjAwMDAwMFoXDTEzMTIwNTIzNTk1OVowgYMxCzAJBgNV
......
To me, this reads as if the certificate is not trusted. A quick search for "terena ssl root certificate" found this website of the University of Helsinki which reads:
Unfortunately root certificates of these authorities are not always present in devices in use, instead, we need to install those root certificates ourselves.
This site also contains a link to the certificate repository.

Resources