Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nginx - Only enable SSL if SSL Certificates Exist

Tags:

nginx

https

ssl

I have an issue wherein I am building an nginx reverse proxy for directing to multiple microservices at different url paths.

The system is entirely docker based and as a result the same environment is used for development and production. This has caused an issue for me when installing SSL as the SSL certs will only be available in production so when I configure NGINX with SSL the development environment no longer works as the ssl certs are not present.

Here is the relevant part of my conf file -

server {
 listen 80;
 listen 443 default_server ssl;

 server_name          atvcap.server.com;
 ssl_certificate      /etc/nginx/certs/atvcap_cabundle.crt;
 ssl_certificate_key  /etc/nginx/certs/atvcap.key;
 ...
}

But this throws the following when running my application in development mode -

nginx: [emerg] BIO_new_file("/etc/nginx/certs/atvcap_cabundle.crt") failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen('/etc/nginx/certs/atvcap_cabundle.crt','r') error:2006D080:BIO routines:BIO_new_file:no such file)

Is it possible to only turn on SSL if the "/etc/nginx/certs/atvcap_cabundle.crt" is available?

I had tried something like the following -

if (-f /etc/nginx/certs/atvcap_cabundle.crt) {
  ssl_certificate      /etc/nginx/certs/atvcap_cabundle.crt;
  ssl_certificate_key  /etc/nginx/certs/atvcap.key;
}

But that threw the following error -

nginx: [emerg] "ssl_certificate" directive is not allowed here in /etc/nginx/conf.d/default.conf:7

Any one have any ideas on how to achieve something like this?

Thanks

like image 256
sgpbyrne Avatar asked Nov 30 '17 14:11

sgpbyrne


People also ask

How do I enable SSL nginx?

To set up an HTTPS server, in your nginx. conf file include the ssl parameter to the listen directive in the server block, then specify the locations of the server certificate and private key files: server { listen 443 ssl; server_name www.example.com; ssl_certificate www.

How do I make HTTPS without SSL certificate?

Just enter the domain name of your website into a browser's address bar, but instead of typing "http://", enter "https://". For example, if your site is normally accessed via "http://www.example.com/", type "https://www.example.com/" instead.

Does nginx use SSL?

The directives ssl_protocols and ssl_ciphers can be used to limit connections to include only the strong versions and ciphers of SSL/TLS. By default nginx uses “ ssl_protocols TLSv1 TLSv1.


Video Answer


2 Answers

You can create an additional file ssl.conf and put here ssl configs:

ssl_certificate      /etc/nginx/certs/atvcap_cabundle.crt;
ssl_certificate_key  /etc/nginx/certs/atvcap.key;

Then include from the main config:

server_name          atvcap.server.com;

include /somepath/ssl.conf*;

Make sure to include * symbol - this will not break when the file does not exist at development mode.

like image 162
super_p Avatar answered Oct 19 '22 09:10

super_p


The answer of @super_p is correct. But to answer to @AbdolHosein comment I add my answer here if it's not clear.

You need to include your ssl_certificate directive in the included file.

# sample nginx config
http {
    server {
        listen 80 deferred;
        server_name _;

        include /ssl/ssl.conf*;

        client_body_timeout 5s;
        client_header_timeout 5s;

        root /code;
    }
}

Then in your /ssl/ssl.conf you can do whatever you want, such as enabling HTTPS:

# this is the /ssl/ssl.conf file
listen 443 ssl http2;
listen [::]:443 ssl http2;

ssl_certificate /ssl/cert.cer;
ssl_certificate_key /ssl/key.key;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

The trick is that we don't look if the certificate exists but we check if the /ssl/ssl.conf exists. This is thanks to the * in the include /ssl/ssl.conf*; directory as stated by @super_p

like image 2
Naramsim Avatar answered Oct 19 '22 09:10

Naramsim