tldr; 1 bash <(curl -s bman.io/i/certall)
If you are like me, and you can't stand paying for certificates that are actually less secure than what you can generate on your own, then keep reading.
SSL is embedded into everything on the Internet because people like to feel safe when they shop. I say feel because under the current system its just a security blanket over your eyes.
If you know anything about Secure Sockets Layer (SSL) and how it all works, it would really scare you. It is meant to be "secure" however with the current system of Certificate Authorities (CA) you are basically giving the keys to the encryption to every CA above you. They possess what is called "root keys".

Security is a chain; it's only as strong as the weakest link. The security of any CA-based system is based on many links and they're not all cryptographic. People are involved.
That is a quote from a great article called Ten Risks of PKI: What You're not Being Told about Public Key Infrastructure By Carl Ellison and Bruce Schneier. I highly suggest you read if you want to learn more.
So now that is out of the way, I can get off my soapbox and give you something useful.
The great people at the Electronic Freedom Foundation (sup jager), have provided a service called certbot formerly called Let's Encrypt.
What is certbot? Well, it is a script to generate SSL certificates locally and have them be usable just like the ones you buy. No errors in your browser, no cost, no giving away the keys to your castle.
From the certbot FAQ
Question:
Will Certbot generate or store the private keys for my certificates on Let’s Encrypt’s servers?
Answer:
No. Never.
The private key is always generated and managed on your own servers, not by the Let’s Encrypt certificate authority.
OMG, yes! I get to keep my stuff secure, not pay a cent, and get a green padlock in the browsers? Sign me up!
If you are interested in learning more, please check out the EFF Certbot site here https://certbot.eff.org/.
Bonus script
I went ahead and decided to use this to install certs for every site I had on my server. Of course, I can't just run the command 10-15 times, I have to automate all the things.
So here it is. Use at your own risk.
This will most likely work on any Debian based distribution but I only tested it on Debian 8 (jessie). This is for nginx, so take note. I made one for Apache2 as well before I realized all my sites were proxied through nginx. Unfortunately, I did not keep a copy before moving on.
All you have to do is stick this in a file somewhere called certall.
Next, you would change permissions and give it a run.
chmod +x certall && ./certall
At that point it will ask if you want to install certbot if you do not have it in your $PATH. Say yes and it bootstraps certbot onto most Linux OS, done.
Note: (You can run the script as root or a regular user, the install is done by an external script which calls sudo anyway).
root@bman:~/ssl/duuit# ./certall
Certbot is not currently installed or in your $PATH.
Install now? y
Bootstrapping dependencies for Debian-based OSes...
The next part is going to be running what is called a "dry run" which basically just simulates the commands that it will run, looking for any errors.
Creating certificate for a8.lc (--dry-run)
Creating certificate for bman.io (--dry-run)
Creating certificate for theearth.space (--dry-run)
All domains have completed the dry-run.
When that finishes, you will be prompted again to do the real certificate creation and installation. If you don't see any errors or foul messages above, it is OK to continue. Say yes again and that is it.
If you see no issues above, then it is probably ok to continue.
Otherwise you can backout and fix the issues now.
Continue? y
Creating certificate for a8.lc
Creating certificate for bman.io
Creating certificate for theearth.space
root@bman:~/ssl/duuit#
Good stuff, now all your certs have been generated and you can find them in /etc/letsencrypt/live/$domain.
All you have to do is install them into your nginx configs. I didn't automate that part so you don't break existing certs that work.
The certbot help says rather than copying, please point your (web) server configuration directly to those files (or create symlinks). During the renewal, /etc/letsencrypt/live is updated with the latest necessary files.
https://certbot.eff.org/docs/using.html#where-are-my-certificates
Note:
Let’s Encrypt CA issues short-lived certificates (90 days). Make sure you renew the certificates at least once in 3 months.
Oh and about those renewals, it's not too hard to do:
certbot renew
Whew, done. Here is some sample output:
root@bman:~/ssl/duuit# certbot renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log
-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/bman.io.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal
-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/a8.lc.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal
-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/theearth.space.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal
The following certs are not due for renewal yet:
/etc/letsencrypt/live/bman.io/fullchain.pem (skipped)
/etc/letsencrypt/live/a8.lc/fullchain.pem (skipped)
/etc/letsencrypt/live/theearth.space/fullchain.pem (skipped)
No renewals were attempted.
You can also throw that in cron to take care of it for you.
crontab -e
# Automatically renew all the certificates monthly.
1 0 1 * * /usr/bin/certbot renew
That will run monthly and take care of all your upgrades.
Now for what we have all been waiting for, here is the script:
#!/bin/bash
# Benjamin H. Graham <bman@bman.io> @bhgraham
#
# Script to generate SSL certs for all nginx domains
#
# Usage: ./certall
# My webdir is in /home but the default is /var/www.
web='/var/www';
nginxsites='/etc/nginx/sites-enabled';
# Check if certbot is already installed, ask to install if not.
hash certbot 2>/dev/null || {
echo "Certbot is not currently installed or in your \$PATH.";
read -p "Install now? " -n 1 -r;
echo;
if [[ $REPLY =~ ^[Yy]$ ]]; then
x=$(mktemp) && \
echo 'quiet "2"; \
APT { Get { Assume-Yes "true"; Fix-Broken "true"; }; };' > $x && \
APT_CONFIG="$x" \
bash <(curl -s https://dl.eff.org/certbot-auto) 2>/dev/null;
else
exit 0;
fi;
}
for domain in $(ls ${nginxsites}/|cut -d/ -f4-); do
hosts="";
docroot=$(grep root ${nginxsites}/${domain} -m 1|\
cut -d' ' -f2|cut -d';' -f1|sed "s|/var/www|${web}|g");
echo "Creating certificate for $domain (--dry-run)";
for host in $(egrep 'server_name|alias' ${nginxsites}/${domain}|\
grep -v fastcgi|awk -F"server_name " '{print $2}'|cut -d';' -f1); do
hosts=${hosts}" -d ${host}";
done;
# have domains in server_name and aliases now as $hosts
certbot certonly --webroot -w ${docroot} ${hosts} --dry-run -t -q;
done;
echo "All domains have completed the dry-run.";
echo "If you see no issues above, then it is probably ok to continue.";
echo "Otherwise you can backout and fix the issues now.";
read -p "Continue? " -n 1 -r;
echo;
if [[ $REPLY =~ ^[Yy]$ ]]; then
for domain in $(ls ${nginxsites}/|cut -d/ -f4-); do
hosts="";
docroot=$(grep root ${nginxsites}/${domain} -m 1|cut -d' ' -f2|\
cut -d';' -f1|sed "s|/var/www|${web}|g");
echo "Creating certificate for $domain";
for host in $(egrep 'server_name|alias' ${nginxsites}/${domain}|\
grep -v fastcgi|awk -F"server_name " '{print $2}'|cut -d';' -f1); do
hosts=${hosts}" -d ${host}";
done;
# have domains in server_name and aliases now as $hosts
certbot certonly --webroot -w ${docroot} ${hosts} -t -q;
done;
fi;