From 71cff90ba42b49ea81d8c92adbbf8bd0f1343499 Mon Sep 17 00:00:00 2001 From: Andrew Cady Date: Thu, 21 Jan 2016 13:33:57 -0500 Subject: update documentation to reflect new code --- README.md | 173 ++++++++++++++------------------------------------------------ 1 file changed, 37 insertions(+), 136 deletions(-) diff --git a/README.md b/README.md index c101c43..e55607f 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,21 @@ # Let's Encrypt ACME protocol +``` +Usage: acme-encrypt-exe --key FILE --domain DOMAIN --dir DIR [--email ADDRESS] + [--terms URL] [--staging] + This is a work in progress. + +Available options: + -h,--help Show this help text + --key FILE filename of your private RSA key + --domain DOMAIN the domain name to certify + --dir DIR output directory for ACME challenges + --email ADDRESS an email address with which to register an account + --terms URL the terms param of the registration request + --staging use staging servers instead of live servers + (certificates will not be real!) +``` + This is a simple Haskell script to obtain a certificate from [Let's Encrypt](https://letsencrypt.org/) using their ACME protocol. @@ -9,165 +25,50 @@ Encrypt](https://letsencrypt.org/) using their ACME protocol. - The ACME spec: https://letsencrypt.github.io/acme-spec/ -Most values are still hard-coded for my initial attempt (i.e. my email address -and a domain of mine). - - -## Discover the URL for letsencrypt ACME endpoints - -API endpoints are listed at https://acme-v01.api.letsencrypt.org/directory and -are currently hard-coded in the script. - -``` -> curl -s https://acme-v01.api.letsencrypt.org/directory | json_pp -{ - "new-cert" : "https://acme-v01.api.letsencrypt.org/acme/new-cert", - "new-authz" : "https://acme-v01.api.letsencrypt.org/acme/new-authz", - "revoke-cert" : "https://acme-v01.api.letsencrypt.org/acme/revoke-cert", - "new-reg" : "https://acme-v01.api.letsencrypt.org/acme/new-reg" -} -``` - - ## Generate user account keys -You need an account with Let's Encrypt to ask and receive certificates for your -domains. The account is controlled by a public/private key pair: - -``` -openssl genrsa 4096 > user.key -openssl rsa -in user.key -pubout > user.pub -``` - - -## Generate nonces +The needed keys will be automatically generated with HsOpenSSL. You can also +pre-generate them manually, in which case they won't be overwritten: -Each request to the API have a nonce to prevent replays. The nonce is currently -hard-coded in the script. New nonces can be obtained from letsencrypt with - -``` -> generate-nonce.sh ``` - - -## Create user account - -Generate `registration.body` by using the `acme.hs` script then POST it to -letsencrypt (note it assumes you agree to their subscriber agreement): - -``` -> curl -s -X POST --data-binary "@registration.body" \ - https://acme-v01.api.letsencrypt.org/acme/new-reg | json_pp -{ - "agreement" : "https://letsencrypt.org/documents/LE-SA-v1.0.1-July-27-2015.pdf", - "contact" : [ - "mailto:noteed@gmail.com" - ], - "key" : { - "e" : "...", - "kty" : "RSA", - "n" : "..." - }, - "id" : 36009, - "createdAt" : "2015-12-04T14:22:08.321951547Z", - "initialIp" : "80.236.245.73" -} -``` - - -## Request a challenge - - -Let's Encrypt needs a proof that you control the claimed domain. You can -request a challenge with `challenge-request.body`. - -``` -> curl -s -X POST --data-binary "@challenge-request.body" \ - https://acme-v01.api.letsencrypt.org/acme/new-authz | json_pp -{ - "expires" : "2015-12-21T18:44:52.331487674Z", - "challenges" : [ - { - "status" : "pending", - "uri" : "https://acme-v01.api.letsencrypt.org/acme/challenge/vXZ1UnZ-y1q7sntnf6NdOfbPAwetJFBqOtvp7FHCjaU/1844047", - "type" : "tls-sni-01", - "token" : "oielAbB7MdyCl29mqjzlqGdrCQSB8SyJaxHbAgQBA7Q" - }, - { - "uri" : "https://acme-v01.api.letsencrypt.org/acme/challenge/vXZ1UnZ-y1q7sntnf6NdOfbPAwetJFBqOtvp7FHCjaU/1844048", - "status" : "pending", - "type" : "http-01", - "token" : "DjyJpI3HVWAmsAwMT5ZFpW8dj19cel6ml6qaBUeGpCg" - } - ], - "identifier" : { - "type" : "dns", - "value" : "aaa.reesd.com" - }, - "combinations" : [ - [ - 0 - ], - [ - 1 - ] - ], - "status" : "pending" -} +openssl genrsa 4096 > user.key +mkdir -p ${DOMAIN_NAME} +openssl genrsa 4096 > ${DOMAIN_NAME}/rsa.key ``` -The script assumes you'll answer the challenge by hosting a file at a location -chosen by Let's Encrypt. Extract the token for the `http-01` challenge and run -the script again. Now you have to host the file at the location reported by the -script. +## Send CSR -Once this is done, you can ask Let's Encrypt to check the file. +The CSR will be automatically created. You can also create it yourself with: ``` -> curl -s -X POST --data-binary "@challenge-response.body" \ - https://acme-v01.api.letsencrypt.org/acme/challenge/vXZ1UnZ-y1q7sntnf6NdOfbPAwetJFBqOtvp7FHCjaU/1844048 | json_pp -{ - "token" : "DjyJpI3HVWAmsAwMT5ZFpW8dj19cel6ml6qaBUeGpCg", - "keyAuthorization" : "DjyJpI3HVWAmsAwMT5ZFpW8dj19cel6ml6qaBUeGpCg.EJe0KReqzCUq6leNOerMC9naZSHxP9TJzGxCcsGkNrw", - "type" : "http-01", - "uri" : "https://acme-v01.api.letsencrypt.org/acme/challenge/vXZ1UnZ-y1q7sntnf6NdOfbPAwetJFBqOtvp7FHCjaU/1844048", - "status" : "pending" -} +> openssl req -new -sha256 -key ${DOMAIN}/rsa.key \ + -subj "/CN=aaa.reesd.com" -outform DER > ${DOMAIN}/csr.der ``` -The same URL can then be polled until the status becomes valid. +## Receive certificate +The signed certificate will be saved by this program in +``./${DOMAIN}/cert.der``. You can copy that file to the place your TLS server is +configured to read it. -## Send CSR / Receive certificate - -The CSR is created with: +You can also view the certificate like so: ``` -> openssl genrsa 4096 > domain.key -> openssl req -new -sha256 -key domain.key -subj "/CN=aaa.reesd.com" > aaa.reesd.com.csr -> openssl req -in aaa.reesd.com.csr -outform DER > aaa.reesd.com.csr.der +> openssl x509 -inform der -in ${DOMAIN}/cert.der -noout -text | less ``` -And the signed certificate can be obtained from Let's Encrypt: - -``` -> curl -s -X POST --data-binary "@csr-request.body" \ - https://acme-v01.api.letsencrypt.org/acme/new-cert > aaa.reesd.com.cert.der -``` - - ## Create a certificate for HAProxy Including explicit DH key exchange parameters to prevent Logjam attack (https://weakdh.org/). ``` -> openssl x509 -inform der -in aaa.reesd.com.cert.der \ - -out aaa.reesd.com.cert.pem -> openssl dhparam -out aaa.reesd.com-dhparams.pem 2048 -> cat aaa.reesd.com.cert.pem \ +> openssl x509 -inform der -in ${DOMAIN}/cert.der \ + -out ${DOMAIN}/cert.pem +> openssl dhparam -out ${DOMAIN}/dhparams.pem 2048 +> cat ${DOMAIN}/cert.pem \ lets-encrypt-x1-cross-signed.pem \ - aaa.reesd.com.key \ - aaa.reesd.com-dhparams.pem > aaa.reesd.com-combined.pem + ${DOMAIN}/rsa.key \ + ${DOMAIN}/dhparams.pem > aaa.reesd.com-combined.pem ``` -- cgit v1.2.3