From e1c9067b8ae21a6348ed6df9a1a4d56bebbb2024 Mon Sep 17 00:00:00 2001 From: Quentin Dufour Date: Fri, 10 Sep 2021 15:35:26 +0200 Subject: [PATCH] Fix some typo --- _posts/2021-09-10-dev-with-tls.md | 38 +++++++++++++++++-------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/_posts/2021-09-10-dev-with-tls.md b/_posts/2021-09-10-dev-with-tls.md index b5888ec..6939b19 100644 --- a/_posts/2021-09-10-dev-with-tls.md +++ b/_posts/2021-09-10-dev-with-tls.md @@ -12,19 +12,22 @@ tags: In this article we focus on openssl as it is generally available and, hopefully, it is versatile enough to adapt all our uses cases. -Note that most straightforward tools exist, such as mkcert, that simplify many steps presented here. +Note that more straightforward tools exist such as `mkcert`. +They simplify many steps presented here. This article is not exhaustive to keep it readable but do not hesitate to complete it with -the corresponding openssl manpage, and you can start with `man openssl` but keep in mind that openssl +the corresponding openssl manpage. +You can already start with `man openssl` but keep in mind that openssl works with subcommands that have dedicated manpages (eg. the manpage for `openssl x509` is `man x509` on my Fedora). In this guide, our target is to create a simple CA for **local development purposes only**. Do not reproduce this practises in production or you will put yourself, your organization and your users at risk. -In our commands, we do not specify an output format while multiple formats exist such as PEM or DER often denoted by various extensions. -By default, openssl always use PEM encoding, which stands for Privacy-Enhanced Mail and is defined in [RFC 7468](https://datatracker.ietf.org/doc/html/rfc7468). In my experience, this format is supported in many places and produce base64 encoded text files. Often we use the `.pem` extension to denote a PEM encoded file but in practise, like in this article, we also create files with the `.crt` or `.key` extension while storing PEM encoded content inside the file. +In our commands, we do not specify an output format even if multiple formats exist. +To name only two, we have PEM or DER. +By default, openssl always use PEM encoding (which stands for Privacy-Enhanced Mail) and is defined in [RFC 7468](https://datatracker.ietf.org/doc/html/rfc7468). It is basically a way to store base64 encoded data in files. In my experience, this format is supported in many places. Often we use the `.pem` extension to denote a PEM encoded file but in practise, like in this article, we also create files with the `.crt` or `.key` extension that are also storing PEM encoded data. -After this preamble, let's start generating our certificates by choosing a working folder: +I am done with the preamble, let's start generating our certificates by choosing a working folder (I will assume that your `$D` environment variable is set for all following commands): ```bash export D=$HOME/.certs/localhost/ @@ -33,7 +36,7 @@ mkdir -p $D ## The Certificate Authority -It is mandatory to create a CA certificate that is independant from our End-entity Certificate: +It is mandatory to create a CA certificate that is independant from your End-entity Certificate, otherwise you will have an error such as `CA_CERT_USED_AS_END_ENTITY` in Firefox. For this article, I arbitrarily chose to generate an Elliptic Curve Key (and not a RSA one) that will be our CA private key. @@ -47,7 +50,7 @@ openssl ecparam \ For more information about this command, run `man ecparam`, read [Bortzmeyer post (FR)](https://www.bortzmeyer.org/8422.html) or directly the [RFC 8422](https://www.rfc-editor.org/rfc/rfc8422.html). -Now, we want to generate a self-signed [X.509 certificate](https://en.wikipedia.org/wiki/X.509) for our Certificate Authority from the previously generated private key. An expiration date is mandatory for a certificate. We set it to 10 years (3650 days) to not be annoyed in the near future by the expiration of our certificate but be sure to set it to a shorter time in production. +Now, we want to generate a self-signed [X.509 certificate](https://en.wikipedia.org/wiki/X.509) for our Certificate Authority from the previously generated private key. Know that an expiration date is mandatory for a certificate. We set it to 10 years (3650 days) to not be annoyed in the near future by the expiration of our certificate but be sure to set it to a shorter time in production. ```bash openssl req \ @@ -61,8 +64,9 @@ openssl req \ For more information on this command, run `man req`. -Now that our CA is ready, we can add it in the CA store of our system and/or applications. -Each software, OS and distribution as its own procedure, in this guide I only cover Fedora. +Now that our authority (CA) is ready, we can add it to the CA store of our system and/or applications. +Each software, OS and distribution as its own procedure. +For Fedora, run: ```bash sudo cp $D/ca.pem /etc/pki/ca-trust/source/anchors/localhost.crt @@ -71,11 +75,11 @@ sudo update-ca-trust For Windows, Mac OS, Debian/Ubuntu, Firefox or Chrome, you can refer to [BounCA's guide](https://www.bounca.org/tutorials/install_root_certificate.html). -And that's all, we have our certificate authority in our system! +And that's all, we have added our certificate authority to our system! ## End-entity Certificate -Now, we will generate a private key for our future application certificate and sign it with our CA. We start with the private key: +Now, we will generate our end-entity certificate, the one that will be used by our application. We start with the private key: ```bash openssl ecparam \ @@ -89,7 +93,7 @@ Then we generate a Certificate Signing Request. The `CN` field is important as it will be checked against your domain name in many cases. Here, we want a certificate for our development needs so we set it to `localhost`. -But we also want a valid certificate when we access our service through IP address. +But we also want a valid certificate when we access our service through our loopback IP address, `127.0.0.1`. Additionnaly, we want to support an infinite number of subdomains to test multiple services at the same time. At this point, we need to use an extension to set the `subjectAltName` key. @@ -112,9 +116,9 @@ openssl req \ And finally we sign the request (CSR) with our own authority (CA). This command is a bit more tricky as we have to set again some fields. It seems to be for security reasons: as this operation is thought to be done by a third party, -it should not trust your parameters and set its own. In our case, we need to re-specify the number of days and our `subjectAltName`. +it should not trust your parameters and set its owns. In our case, we need to re-specify the number of days and our `subjectAltName`. -openssl has a more advanced/high level tool, `openssl ca` (doc: `man ca`), that is able to copy some or all fields of a signing request but this tool has some other caveats. If you are interested, please read its `WARNINGS` section in the manual. +openssl has a more advanced/high level tool than the one we will use, namely `openssl ca` (doc: `man ca`). `openssl ca` is able to copy some or all fields of a signing request but this tool has, in return, some other caveats. If you are interested, please read its manual and especially the section entitled `WARNINGS`. Our final command is: @@ -135,10 +139,10 @@ You can run `man x509` to know more about this command. ## With socat -socat is a swiss army knife for your network needs. In this example, we will use it as a simple TLS +socat is the swiss army knife of the network operator. In this example, we will use it as a simple TLS proxy in front of a plain text application. -First, we need to concatenate our certificate in a bundle for socat. The key must comes first, then its X.509 certificats, and the whole chain of X.509 certificates up your root certificates. +First, we need to concatenate our certificate in a bundle for socat. The key must comes first, then its X.509 certificates, and finally the whole chain of X.509 certificates up your root certificates. For us: ```bash @@ -163,7 +167,7 @@ cert=$D/localhost-bundle.pem" \ tcp4-connect:localhost:3900 ``` -`reuseaddr` enables to not wait for an internal timeout in the kernel after shutdowning a process using the same port, the article [Bind: Address already in use](https://hea-www.harvard.edu/~fine/Tech/addrinuse.html) explains on details why. `fork` allows us to handle multiple connections in parallel. `verify` allows us to activate or deactivate mutual authentication, here we do not want to authenticate the client so we set it to zero. +You may ask yourself why we put parameters like `reuseaddr` or `fork`. By using `reuseaddr`, we can reuse a port without waiting for an internal timeout in the kernel which is required to quickly restart socat, the article [Bind: Address already in use](https://hea-www.harvard.edu/~fine/Tech/addrinuse.html) explains on details why. `fork` allows us to handle multiple connections in parallel. `verify` allows us to activate or deactivate mutual authentication, here we do not want to authenticate the client so we set it to zero. ## Other resources