Browse Source

Added readme

Daniel Roesler 9 years ago
parent
commit
7e8f773143
1 changed files with 178 additions and 1 deletions
  1. 178 1
      README.md

+ 178 - 1
README.md

@@ -1,2 +1,179 @@
 # acme-tiny
-A tiny script to issue and renew TLS certs from Let's Encrypt
+
+This is a tiny, auditable script that you can throw on your server to issue
+and renew [Let's Encrypt](https://letsencrypt.org/) certificates. Since it has
+to be run on your server and have access to your private Let's Encrypt account
+key, I tried to make it as tiny as possilbe (currently less than 200 lines).
+The only prerequisites are python and openssl.
+
+**PLEASE READ THE SOURCE CODE! YOU MUST TRUST IT WITH YOUR PRIVATE KEYS!**
+
+##Donate
+
+If this script is useful to you, please donate to the EFF. I don't work there,
+but they do fantastic work.
+
+[https://eff.org/donate/](https://eff.org/donate/)
+
+## How to use this script
+
+If you already have a Let's Encrypt issued certificate and just want to renew,
+you should only have to do Steps 3 and 6.
+
+### Step 1: Create a Let's Encrypt account private key (if you haven't already)
+
+You must have a public key registered with Let's Encrypt and sign your requests
+with the corresponding private key. If you don't understand what I just said,
+this script likely isn't for you! Please use the official Let's Encrypt client.
+
+```
+openssl genrsa 4096 > account.key
+```
+
+### Step 2: Create a certificate signing request (CSR) for your domains.
+
+The ACME protocol (what Let's Encrypt uses) requires a CSR file to be submitted
+to it, even for renewals. You can use the same CSR for multiple renewals. NOTE:
+you can't use your account private key as your domain private key!
+
+```
+#generate a domain private key (if you haven't already)
+openssl genrsa 4096 > domain.key
+```
+
+```
+#for a single domain
+openssl req -new -sha256 -key domain.key -subj "/CN=yoursite.com" > domain.csr
+
+#for multiple domains (use this one if you want both www.yoursite.com and yoursite.com)
+openssl req -new -sha256 -key domain.key -subj "/" -reqexts SAN -config <(cat /etc/ssl/openssl.cnf <(printf "[SAN]\nsubjectAltName=DNS:yoursite.com,DNS:www.yoursite.com")) > domain.csr
+```
+
+### Step 3: Make your website host challenge files
+
+You must prove you own the domains you want a certificate for, so Let's Encrypt
+requires you host some files on them. This script will generate and write those
+files the folder you specify, so all you need to do is make sure that folder
+is served under the ".well-known/acme-challenge/" url path. NOTE: This must be
+on port 80 (not port 443).
+
+```
+#make some challenge folder (modify to suit your needs)
+mkdir -p /var/www/challenges/
+
+#example for nginx
+server {
+    listen 80;
+    server_name yoursite.com, www.yoursite.com;
+
+    location /.well-known/acme-challenge/ {
+        alias /var/www/challenges/;
+        try_files $uri =404;
+    }
+
+    ...the rest of your config
+}
+```
+
+### Step 4: Get a signed certificate!
+
+Now that you have setup your server and generated all the needed files, run this
+script on your server with the permissions needed to write to the above folder
+and read your private account key and CSR.
+
+```
+#run the script on your server
+python acme_tiny.py --account-key ./account.key --csr ./domain.csr --acme-dir /var/www/challenges/ > ./signed.crt
+```
+
+### Step 5: Install the certificate
+
+The signed https certificate that is output by this script can be used along
+with your private key to run an https server. You need to include them in the
+https settings in your web server's configuration. Here's an example on how to
+configure an nginx server:
+
+```
+#NOTE: For nginx, you need to append the Let's Encrypt intermediate cert to your cert
+wget https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem
+cat signed.crt lets-encrypt-x1-cross-signed.pem > chained.pem
+```
+
+```nginx
+server {
+    listen 443;
+    server_name yoursite.com, www.yoursite.com;
+
+    ssl on;
+    ssl_certificate /path/to/chained.pem;
+    ssl_certificate_key /path/to/domain.key;
+    ssl_session_timeout 5m;
+    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
+    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA;
+    ssl_session_cache shared:SSL:50m;
+    ssl_dhparam /path/to/server.dhparam;
+    ssl_prefer_server_ciphers on;
+
+    ...the rest of your config
+}
+
+server {
+    listen 80;
+    server_name yoursite.com, www.yoursite.com;
+
+    location /.well-known/acme-challenge/ {
+        alias /var/www/challenges/;
+        try_files $uri =404;
+    }
+
+    ...the rest of your config
+}
+```
+
+### Step 6: Setup an auto-renew cronjob
+
+Congrats! Your website is now using https! Unfortunately, Let's Encrypt
+certificates only last for 90 days, so you need to renew them often. No worries!
+It's automated! Just make a bash script and add it to your crontab (see below
+for example script).
+
+Example of a `renew_cert.sh`:
+```sh
+#!/usr/bin/sh
+python /path/to/acme_tiny.py --account-key /path/to/account.key --csr /path/to/domain.csr --acme-dir /var/www/challenges/ > /path/to/signed.crt
+wget https://letsencrypt.org/certs/lets-encrypt-x1-cross-signed.pem
+cat /path/to/signed.crt lets-encrypt-x1-cross-signed.pem > /path/to/chained.pem
+service nginx reload
+```
+
+```
+#example line in your crontab (runs once per month)
+0 0 1 * * /path/to/renew_cert.sh 2>> /var/log/acme_tiny.log
+```
+
+## Permissions
+
+The biggest problem you'll likely come across while setting up and running this
+script is permissions. You want to limit access to your account private key and
+challenge web folder as much as possible. I'd recommend creating a user
+specifically for handling this script, the account private key, and the
+challenge folder. Then add the ability for that user to write to your installed
+certificate file (e.g. `/path/to/chained.pem`) and reload your webserver. That
+way, the cron script will do it's thing, overwrite your old certifiate, and
+reload your webserver without having permission to do anything else.
+
+**BE SURE TO:**
+* Backup your account private key (e.g. `account.key`)
+* Don't allow this script to be able to read your domain private key!
+* Don't allow this script to be run as root!
+
+## Feedback/Contributing
+
+This project has a very, very limited scope and codebase. I'm happy to receive
+bug reports and pull requests, but please don't add any new features. This
+script must stay under 200 lines of code to ensure it can be easily audited by
+anyone who wants to run it.
+
+If you want to add features for your own setup to make things easier for you,
+please do! It's open source, so feel free to fork it and modify as necessary.
+