Skip to content

Instantly share code, notes, and snippets.

@jessedearing
Forked from twoism-dev/gist:1183437
Created April 10, 2012 14:44
Show Gist options
  • Save jessedearing/2351836 to your computer and use it in GitHub Desktop.
Save jessedearing/2351836 to your computer and use it in GitHub Desktop.
Create self-signed SSL certificate for Nginx
#!/bin/bash
echo "Generating an SSL private key to sign your certificate..."
openssl genrsa -des3 -out myssl.key 1024
echo "Generating a Certificate Signing Request..."
openssl req -new -key myssl.key -out myssl.csr
echo "Removing passphrase from key (for nginx)..."
cp myssl.key myssl.key.org
openssl rsa -in myssl.key.org -out myssl.key
rm myssl.key.org
echo "Generating certificate..."
openssl x509 -req -days 365 -in myssl.csr -signkey myssl.key -out myssl.crt
echo "Copying certificate (myssl.crt) to /etc/ssl/certs/"
mkdir -p /etc/ssl/certs
cp myssl.crt /etc/ssl/certs/
echo "Copying key (myssl.key) to /etc/ssl/private/"
mkdir -p /etc/ssl/private
cp myssl.key /etc/ssl/private/
@slava-vishnyakov
Copy link

slava-vishnyakov commented Apr 17, 2013

Thanks! That's very useful!
Just for future reference: here's how to attach it to nginx

server {
    listen               443 ssl;
    ssl                  on;
    ssl_certificate      /etc/ssl/certs/myssl.crt;
    ssl_certificate_key  /etc/ssl/private/myssl.key;
    server_name SERVER_NAME.com;
    location / {
    }
}

EDIT: (updated, taking into consideration discussion below)

@schmurfy
Copy link

thanks you both for this, generating/using certificates is really a pain :/

@tvlooy
Copy link

tvlooy commented Feb 28, 2014

The command below seems to work just fine for me and is just a one liner. Any comments?

openssl req -x509 -nodes -days 365 -newkey rsa:1024 \
    -keyout /etc/ssl/private/myssl.key \
    -out /etc/ssl/certs/myssl.crt

You can automate the questions in a script:

openssl req -x509 -nodes -days 365 -newkey rsa:1024 \
    -keyout /etc/ssl/private/myssl.key \
    -out /etc/ssl/certs/myssl.crt <<EOF
BE
Brussels

My project
Development
the.domain.tld

EOF

@stealthpaladin
Copy link

@tvlooy - works for me, though on centos it seems the private directory is not there by default. presumably some distros may not have either so i put a small tweak of..

mkdir -p /etc/ssl/private && mkdir -p /etc/ssl/certs && openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/ssl/private/site_name.key -out /etc/ssl/certs/site_name.crt

OR

mkdir -p /etc/ssl/private &&
mkdir -p /etc/ssl/certs &&

openssl req -x509 -nodes -days 365 -newkey rsa:4096
-keyout /etc/ssl/private/site_name.key
-out /etc/ssl/certs/site_name.crt <<EOF
US
TX
Private

SiteName Admin Portal
Development
portal.sitename.com

EOF

@adrianorsouza
Copy link

On Ubuntu there is no permissions into /etc/ssl/private, However I make it works in /etc/nginx/ssl.
Also based on your script a made my own witch output the nginx configuration at the end. https://gist.github.com/adrianorsouza/2bbfe5e197ce1c0b97c8

@abkrim
Copy link

abkrim commented Aug 15, 2017

One step (if use Ubunut 16.04 /etc/ssl exists. If not use you feel free to add create dir)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt

@natanraj
Copy link

natanraj commented Nov 1, 2017

hi.. It is a very good gist... I am using nginx on AWS and followed these instructions. But unable to access https://<>. Any suggestions pls.

Note: i have enabled my AWS security group to listen to 443 as well.

@tqwhite
Copy link

tqwhite commented Apr 3, 2018

I love this article. The self-signing process worked perfectly immediately.

@slava-vishnyakov provided a wonderfully useful snippet for the nginx configuration file. BUT...

I don't know if things have changed in the years since he or she wrote it but, it has one tiny imperfection that resulted in an error (ssl_error_rx_record_too_long) in the browser.

Use this instead..

server {
listen 443 ssl;
ssl on;
ssl_certificate /etc/ssl/certs/myssl.crt;
ssl_certificate_key /etc/ssl/private/myssl.key;
server_name SERVER_NAME.com;
location / {
}
}

Just add the "ssl" to the listen parameters.

With that, this article becomes one of the most instantly useful I've ever seen.

Thanks to all of you.

@davidfirst
Copy link

As to the Nginx configuration, I got a warning
nginx: [warn] the "ssl" directive is deprecated, use the "listen ... ssl" directive instead in /usr/local/etc/nginx/sites-enabled/local.mysite.com:8

I just removed the ssl on; part and the warning is gone.

In other words, it should be something like this:

server {
    listen               443 ssl;
    ssl_certificate      /etc/ssl/certs/myssl.crt;
    ssl_certificate_key  /etc/ssl/private/myssl.key;
    server_name SERVER_NAME.com;
    location / {
    }
}

@cesarjv
Copy link

cesarjv commented Jun 21, 2020

Good morning, is it necessary to have a domain to apply this method of generating ssl self-signed certificate?

Because in my company it is handled is url type https://10.164.7.203:37006/PruebaHTTPS

@popovserhii
Copy link

popovserhii commented Aug 26, 2020

If someone got the next error:

# nginx -t

nginx: [emerg] SSL_CTX_use_certificate("/etc/ssl/certs/myssl.crt") failed (SSL: error:140AB18F:SSL routines:SSL_CTX_use_certificate:ee key too small)
nginx: configuration file /etc/nginx/nginx.conf test failed

You have to change the length of your certificate from rsa:1024 to rsa:2048

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment