I have a .crt, .key and CA.pem files that were generated like this.
These certs are kind of project-wide, and they work when firing up a webpack-dev-server server on HTTPS like:
devServer: {
https: {
key: fs.readFileSync('/path/to/example.com.key'),
cert: fs.readFileSync('/path/to/examle.com.crt'),
ca: fs.readFileSync('/path/to/CA.pem'),
}
}
Now I need to setup an Nginx server using these 3 files, but I've been trying with no luck. Here's my config:
server {
listen 3000;
ssl_certificate certs/example.com.crt;
ssl_certificate_key certs/example.com.key;
# where does the CA.pem file go??
}
The result of this is Chrome giving me a
This site can’t provide a secure connection
example.com sent an invalid response.
ERR_SSL_PROTOCOL_ERROR
Nginx logs show random hex characters:
172.18.0.1 - - [14/Dec/2018:18:01:55 +0000] "\x16\x03\x01\x00\xDD\x01\x00\x00\xD9\x03\x03\xAB\xE1\xB3\x1F\xCE\x02\x02\xC5}q\xDFgd\xF1`\xC1m\x8E\x99\xCE' \x98\xDF\xDEEg\x8Fm\xED\x9F\xB1\x00\x00\x1C" 400 166 "-" "-" "-" 0.001 -
Any ideas what could I be doing wrong?
You need to concatenate your certificate with CA for nginx:
cp example.com.crt example.com.fullchain.pem
cat CA.pem >> example.com.fullchain.pem
and use this file in nginx config:
ssl_certificate certs/example.com.fullchain.pem;
Related
I'm trying to reverse-proxy an http server via nginx. The service is listening on port 8123 and I want to proxy it on 443.
I created a self-signed certificate like this:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
Here is the complete nginx configuration:
events {
worker_connections 768;
}
http {
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /home/mcmsadm/cert.pem;
ssl_certificate_key /home/mcmsadm/key.pem;
location / {
proxy_pass http://localhost:8123;
}
}
}
When I try to connect to the server using Firefox, it says PR_END_OF_FILE_ERROR.
What am I doing wrong?
Thanks!
EDIT:
I found the nginx error message in the logs (Didn't think about it):
SSL_CTX_use_PrivateKey_file("/home/mcmsadm/key.pem") failed
(SSL: error:2807106B:UI routines:UI_process:processing error:while reading strings
error:0906406D:PEM routines:PEM_def_callback:problems getting password
error:0907B068:PEM routines:PEM_read_bio_PrivateKey:bad password read
error:140B0009:SSL routines:SSL_CTX_use_PrivateKey_file:PEM lib)
I did create the certificate with a password, but nginx is asking for it when I restart it via nginx -s reload. To temporarily solve this I wrote the password in a file and added this line to my nginx.conf:
ssl_password_file /etc/nginx/pass;
Is there any way that I can avoid writing the password in a file?
For anyone else with this issue.. it can also happen if you have forgotten to add ssl to the listen directives. Chrome shows ERR_SSL_PROTOCOL_ERROR whilst Firefox shows PR_END_OF_FILE_ERROR.
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
...
}
The error is often not related to the browser. In our case it was also not a configuration thing of nginx, but a wrong setting of the firewall. So logically, when I say that often has nothing to do with the browser, server-side and not client-side. Accordingly, it was not a proxy or VPN.
Note for myself :-d
The default_server configuration (with ssl or/and without ssl) is missing from one of the virtual host definitions, like this:
server {
listen 80 default_server;
listen 443 default_server;
...
Have recently moved to CloudFlare as I wanted a DNS service that provided DNS credentials for certbot to generate a wildcard SSL certificate.
However, I am struggling to get a basic SSL Nginx setup running.
Background:
DNS resolution works fine. (When I just have an Nginx HTTP server block, the website loads insecurely over HTTP)
Can connect to website via direct IP with HTTPS address (not via CloudFlare IP). It gives an invalid cert warning but still connects.
openssl s_client -connect property-connect.co.uk:443 -servername property-connect.co.uk seems to indicate the SSL certificate is fine
Steps:
Ran certbot --nginx specified include both domains (www.property-connect.co.uk property-connect.co.uk)
sudo nginx -t was successful
sudo nginx -s reload
nginx.conf
events {
}
http {
server {
server_name www.property-connect.co.uk property-connect.co.uk;
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
location / {
proxy_pass http://localhost:700;
}
ssl_certificate /etc/letsencrypt/live/property-connect.co.uk-0001/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/property-connect.co.uk-0001/privkey.pem; # managed by Certbot
}
}
Any thoughts as to what I am missing with this basic config?
Your current certificate for this domain issued and managed by Cloudflare itself, not by your CertBot/Nginx:
$ openssl s_client -connect property-connect.co.uk:443 -servername property-connect.co.uk </dev/null 2>&1 | grep ^issuer
issuer=C = US, ST = CA, L = San Francisco, O = "CloudFlare, Inc.", CN = CloudFlare Inc ECC CA-2
I guess this is because you have proxied traffic via Cloudflare to your host
You should switch your domain to DNS only and then you will able to connect directly to your Nginx without Cloudflare reverse-proxying.
Turns out I just needed to change the Cloudflare SSL setting from 'Flexible' (Browser -> HTTPS -> Cloudflare -> HTTP -> Web server) to 'Full' (Browser -> HTTPS -> Cloudflare -> HTTPS -> Web server).
Heroku gives simple instructions for updating your certificates for SSL:
$ heroku certs:update server.crt server.key
However, there is no indication that any verification is done before deploying. As this is production, I want to be sure that the two files I'm giving them will not cause any security snafus.
I have my foo_com.crt (which was signed by DigiCert), server.key, and DigitCertCA.crt.
I've found that I can use security verify-cert -c certificate.pem to verify my certificate (on OS X). My certificate doesn't verify though:
$ security verify-cert -c foo_com.crt
Cert Verify Result: CSSMERR_TP_NOT_TRUSTED
Which leads me to believe that my intermediary may not be trusted but:
$ security verify-cert -c DigiCertCA.crt
...certificate verification successful.
Specifying a purpose of SSL succeeds too
$ security verify-cert -p ssl -c foo_com.crt
...certificate verification successful.
I tried on a Linux box as well with similar mixed results.
$ openssl verify foo_com.crt
C = __, ST = ___, L = ___, O = "Foo Inc", CN = foo.com
error 20 at 0 depth lookup: unable to get local issuer certificate
error foo_com.crt: verification failed
$ openssl verify -CAfile DigiCertCA.crt foo_com.crt
foo_com.crt: OK
$ openssl verify -purpose sslserver -CApath /etc/ssl/certs foo_com.crt
C = __, ST = ___, L = ___, O = "Foo Inc", CN = foo.com
error 20 at 0 depth lookup: unable to get local issuer certificate
error foo_com.crt: verification failed
How can I be sure that when I update my certificates in Heroku, that everything will work smoothly?
Related: Renewing SSL certificate on Heroku
A suggestion from a colleague to run nginx led me to a confident way to know that everything would deploy smoothly.
I configured nginx with
server {
listen 443 http2 ssl;
listen [::]:443 http2 ssl;
server_name server_IP_address;
ssl_certificate /Users/traff/cert/gd.crt;
ssl_certificate_key /Users/traff/cert/server.key;
server_name localhost;
...
}
Once I had my nginx server set up I ran openssl s_client -connect localhost:443 -CApath /etc/ssl/certs. Then, after setting up foo.com in my hosts to point to my nginx server. I used curl https://foo.com.
Using the concatenation of foo_com.crt and DigiCertCA.crt (in that order) and server.key, upload was successful.
Furthermore, though Heroku's documentation does not state it, the update step does verify that SSL will serve properly
$ heroku certs:update foo_com_DigiCertCA_cat.crt server.key -a my-app
Resolving trust chain... done
_ Potentially Destructive Action
_ This command will change the certificate of endpoint ____
_ (_______.herokussl.com) from _ my-app.
_ To proceed, type my-app or re-run this command with
_ --confirm my-app
> my-app
Updating SSL certificate _____ (____.herokussl.com) for _ my-app... done
Updated certificate details:
Common Name(s): foo.com
Expires At: DateTime
Issuer: /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
Starts At: DigiCert
Subject: blah blah blah
SSL certificate is verified by a root authority.
Question:
Is there anything special about the way nginx wants its .pem/.crt and .key files formated? I can't get nginx running... it always craps out complaining about the cert/key file.
Ask:
Anyone want to share with me a (sanitized) copy of their .pem/crt and .key file on a (non-production) system that is working fine? Or otherwise tell me what I am doing wrong (see below)
Errors:
After configuring nginx.conf to point to ssltest.cuddletech.com.crt and depositing the .crt (and key) file in /nginx/servers... and then run nginx to start the server, I get the following error:
nginx: [emerg] unexpected end of file, expecting ";" or "}" in /usr/local/etc/nginx/servers/ssltest.cuddletech.com.crt:63
Troubleshooting:
`
If I go in and put a ;at the end of the file (right after the second
-----END CERTIFICATE-----; (it's a bundle containing both the leaf and the intermediate ca). Now,it no longer complains about the unexpected end, but rather complains:
nginx: [emerg] unknown directive "-----BEGIN" in /usr/local/etc/nginx/servers/ssltest.cuddletech.com.crt:62
If I then go in and delete the -----BEGIN part, it continues to complain about the unknown directive... this time starting with the first few characters of the encoded cert.
Interestingly, If I change the file type to .pem (keeping the ; at the end, and update nginx.conf to look for the .pem). Now, it does not complain at all about the certificate file, but rather starts complaining the same way about the KEY file:
$ nginx: [emerg] unexpected end of file, expecting ";" or "}" in /usr/local/etc/nginx/servers/ssltest.cuddletech.com.key:28
Putting the ; or } at the end of the .key file makes nginx complain:
nginx: [emerg] unknown directive "-----BEGIN" in /usr/local/etc/nginx/servers/ssltest.cuddletech.com.key:27
Also interesting is that both time it complains about the -----BEGIN it indicates a line number at the end of the file, not at the beginning.
How I Generated The Cert and Key files:
I generated the cert using Hashicorp's Vault PKI backend (per this howto )
I cut and pasted the leaf and intermediate cert into one file and the private key into another file.
They look like this:
Certificate bundle:
-----BEGIN CERTIFICATE-----
MIIE/DCCAuSgAwIBAgIUIKX6kkLIidtRvnx0nafFH9SunaIwDQYJKoZIhvc
NAQELBQAwKTEnMCGA1UEAxMeQ3VkZGxldGVjaCBPcHMgSW50ZXJtZWRpYXRlIENBMB4X
DTE3MDkwOTAwMTgxNVoXDTE3MTAwOTAwMTg0NVowITEfMB0GA1UEAxMWc3NsdGVz
....
NW9I2ThBDp0uo7LcIO7hmHhNun6apGSlgf6Gj1L63dp
Fe+hoQpCNOGfoc2P+4uJZenqiax5dFqskiBVkQ7uyVFxf5ydF5pjzwF/QFFcKKok
SkRjCJmrVxD/7V6H8u+hSRJuXGXNIIuhhUmYhWoNZpnZEUyDPOuMWHjxq7ZfPHlO
A039BhLFI0msEBfk+DunhYA+xyBIhK0Lq3pqcc7zH9A=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFpTCCA42gAwIBAgIUbXR6po8/oWmxgTVYuhxHDAM1prUwDQYJKoZIhvcNAQEL
BQAwHTEbMBkGA1UEAxMSQ3VkZGxldGVjaCBSb290IENBMB4XDTE3MDkwODIyNTI0
OFoXDTE4MDkwODIyNTMxOFowKTEnMCUGA1UEAxMeQ3VkZGxldGVjaCBPcHMgSW50
.....
ZXJtZWRpYXRlIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwuTe
h9gpV4RcibYNOptsDJHomUZaEkRs3ppGt1asnM5os7L17ExFS8PLSY0SbhB75Vo1
TLlgH2MkDGHbw5bcgY0fYXvKqk1y6JjLFBnmiGHe8mHt9XaWkbnwP/E7CttGr2GC
SaT7RxDN2pHXceTnmLOiz0Dk1ZpssldMVD1MQeSQspuBp9s2sWfXtkrLluPLOZH0
C1WXl+H/7giQggXPmMVLhnxPaaAwU0DNX0IZjzE1fqazBbrx36n7baVdUgRczkD2
Xiht8pnAdbUFdp8byeupDkPJ2vLyMLocvSO6z1m4+drXlgFPBLSgKXGvnw5A8b+S
dqKRe55MBNxpws0E4OjMVwVXlMctcLCogmx6jFYjWSJUQgKLHCi2JVWW6ajlKOfV
Gn/opA11kWKb
-----END CERTIFICATE-----
The Private Key file:
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAyWnbF5T5vIlrcVHG82S+u/GESnlhAiX6maUYmpQMVOGsmjWr
XOKFGQbFW796FgENrt1PzXlYT8/aKyT215KomxkC4bWV0daobC5p+fzusVyV51Si
.....
smzFwxewOYa4FU3KGgRlscBooaRumwpXid3IPwfsBzOCdNQ8zXyaqSZeStewxUBq
ZtMEDpD3q7noZQU85cQs4SlbOOscXEUMUaeKQDhC2FWW9qlM5NKU
-----END RSA PRIVATE KEY-----
The HTTPS server section of nginx.conf
# HTTPS server
#
server {
listen 443 ssl;
server_name ssltest.cuddletech.com;
ssl_certificate /usr/local/etc/nginx/servers/ssltest.cuddletech.com.pem;
ssl_certificate_key /usr/local/etc/nginx/servers/ssltest.cuddletech.com.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
location / {
root /user/share/nginx/html;
index index.html index.htm;
}
}
include servers/*;
}
My Set-up:
Mac OS X 10.12.6
nginx version: nginx/1.12.1
built by clang 8.1.0 (clang-802.0.42)
built with OpenSSL 1.1.0f 25 May 2017
TLS SNI support enabled
TIA for any advice!!!
Your problem us the include servers/*; statement. You are including everything in the servers directory as config. So the certificates also are being loaded as config
Either change it to
include servers/*.conf;
Or remove it if there are no configs you are including
I've gotten SSL to work on Apache servers and on a client's Nginx server. However, I am having issues with my EV SSL certificate installation. This is also on a server with a special character in the URL: weöm.com.
weöm.com is displayed as xn--wem-tna.com in browsers, which is fine. When I inspected my .ca-bundle that was emailed to me from COMODO, I saw my domain name rendered as we\xC3\xB6m.com, which made me think I have to generate my .csr and .key the same way.
Here's how I've been doing it (ran this command in Terminal):
openssl req -new -newkey rsa:2048 -nodes -out weom.csr -keyout weom.key -subj "/serialNumber=000000000/businessCategory=Private Organization/C=US/postalCode=00000/ST=California/L=Cupertino/street=1 Loop Way/O=Apple Inc/OU=COMODO EV SSL/CN=we\xC3\xB6m.com"
(I've replaced the serial number and other things with fake data in my example)
The code spits out a .csr and .key with the exact same data that my compiled .crt has and I cannot understand why I'm still getting this SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch error.
I've been wrangling with this for about a week, does anyone have any idea what I'm doing wrong?
EDIT: Proving more information...
Here is how I'm creating my master .crt:
cat xn--wem-tna.com.crt AddTrustExternalCARoot.crt COMODORSAAddTrustCA.crt COMODORSAExtendedValidationSecureServerCA.crt >> cert_chain.crt
This is the default file in my sites-available folder:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name xn--wem-tna.com;
return 301 https://$host$request_uri;
}
server {
# SSL configuration
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_certificate cert_chain.crt;
ssl_certificate_key weom.key;
ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name xn--wem-tna.com;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}
The reason for the error is that your KEY and CRT are different.
You can verify this by checking MD5 hashes on them:
openssl x509 -noout -modulus -in certificate.crt | openssl md5
openssl rsa -noout -modulus -in privateKey.key | openssl md5
Additionally I would change the order in the bundle CRT (cert_chain.crt),at the moment you have it this way:
xn--wem-tna.com.crt AddTrustExternalCARoot.crt COMODORSAAddTrustCA.crt COMODORSAExtendedValidationSecureServerCA.crt
It should be:
cat xn--wem-tna.com.crt COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > cert_chain.crt
This is Official Comodos Certificate Installation: NGINX
What gets me worried is your comment at the beginning:
If you have changed the key once your certificate had been issued you will need to invalidate it and apply for a new CRT with your new KEY and new CSR.
weöm.com is displayed as xn--wem-tna.com in browsers, which is fine. When I inspected my .ca-bundle that was emailed to me from COMODO, I saw my domain name rendered as we\xC3\xB6m.com, which made me think I have to generate my .csr and .key the same way.
Oh yeah, forgot to update.
I got a refund and went with CertSimple. Emailed them questions Friday night, went through the entire process of obtaining an EV cert Saturday morning/afternoon, and had it on my server by 6pm (and that's only because I was out running errands).