Skip to content

Commit

Permalink
doc: add certificate update notes
Browse files Browse the repository at this point in the history
Add notes on website certificate renewal based on what was done
the last time we updated in January 2022.

Refs: nodejs#2811
  • Loading branch information
richardlau committed Apr 25, 2022
1 parent c9210ef commit 5f1d6c7
Showing 1 changed file with 151 additions and 0 deletions.
151 changes: 151 additions & 0 deletions doc/update-certificates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# Replacing the main Node.js TLS/SSL certificate

Node.js' public facing websites are secured by a TLS/SSL wildcard certificate. Currently this is a [multi-year subscription][] obtained via the OpenJS Foundation via [GoGetSSL][].

You will need build-infra level access to be able to retrieve the certificate and update the build infrastructure. Login information for Build WG accounts are in the [secrets repository][] (restricted).

## Places that need to be updated

* [Cloudflare](#updating-cloudflare)
* [Nginx web servers](#updating-nginx-servers)
* ci ([ci.nodejs.org]())
* ci-release ([ci-release.nodejs.org][])
* unencrypted ([unencrypted.nodejs.org][])
* www ([nodejs.org][])
* [Secrets repository](#update-copy-of-certificate-and-key-in-secrets)

## Purchasing the new certificate

This is done via a request to the OpenJS Foundation. GoGetSSL should send notifications to the Build WG email address from 30 days before the existing certificate expires.

## Generating new certificate and key

Create a new key each time you renew the certificate.

Currently we use RSA, 4096 bits (validate on each renewal that this is still the recommended/reasonable values).

In the `/root/tmp` directory, create the key with the following command on the www server:
```
openssl genrsa -out star_nodejs_org.key 4096
```

Generate a CSR request with the following command
```
openssl req -new -key star_nodejs_org.key -out star_nodejs_org_chained.csr
```
and provide the following info when prompted:

key | value
---|---
Country Name | US
State or Province Name | California
Locality | San Francisco
Organization Name | OpenJS Foundation
Organizational Unit Name | Node.js
Common Name | *.nodejs.org

Go to https://my.gogetssl.com and choose `SSL Certificates` -> (The new certificate) -> `View` -> `Generate Certificate` and paste the CSR into the box provided.

When asked to choose a validation approach, use DNS validation. This requires logging into Cloudflare and creating a CNAME entry. The process warns that this can take 10 minutes to 24 hours, although it took only a few minutes the previous time the certificate was renewed.

Once the CNAME entry is created you will get an email with the certificate. We ran into some problems using the certificate from the email, so instead downloaded the certificate from the GoGetSSL UI via `SSL Certificates`->(The new certificate) -> `View` -> `Certificate` into `/root/tmp/star_nodejs_org_chained.csr`.

Now you have the key and certificates that are needed to update the web servers and Cloudflare as outlined in the subsequent sections.

## Updating Cloudflare

Upload under `nodejs.org` -> `SSL/TLS` -> `Edge Certificates` menu, expand the entry for `*.nodejs.org, nodejs.org` and then select the wrench. This should bring up the `Replace SSL certificate and key` dialog. Copy in the certificate and key.

Use the following options for the drop downs on the page
Option | Value
---|---
Private Key Restrictions | Distribute to all Cloudflare data centers
Legacy Client Support | Legacy

And then select `Upload Custom Certificate`.

Validate that the `Expires on` for the entry now shows the updated expiry date. It make take some time for the update to propagate across the Cloudflare servers.

## Updating nginx servers

For each webserver, the certificate is installed into `/etc/nginx/ssl`. The following steps use `unencrypted` as an example:

Upload the certificate and key to the server.
```
ssh unencrypted mkdir /root/tmp
scp star_nodejs_org.key star_nodejs_org_chained.crt unencrypted:/root/tmp/
```

Open an ssh session on the server, backup the existing keys and then copy over the new ones
```
ssh unencrypted
cd /etc/nginx/ssl/
cp nodejs_chained.crt nodejs_chained.crt.old
cp nodejs.key nodejs.key.old
cp /root/tmp/star_nodejs_org_chained.crt nodejs_chained.crt
cp /root/tmp/star_nodejs_org.key nodejs.key
```

Restart nginx
```
systemctl restart nginx
```

Use a web browser to go to the server (e.g. https://unencrypted.nodejs.org (make sure you go to the https URL and not http)) and use the browser to view the certificate and expiry to check it matches the new expected validity dates.

Delete `/root/tmp` on the server

## Update copy of certificate and key in secrets

Encrypt the key and certificate. We generally DO NOT fork projects in the nodejs-private organization. Instead we clone the [secrets repository][] directly from nodejs-private and create a new branch in that private repo.

From where you have temporarily stored the certificates/key and assuming you have checked out the secrets repo at ~/secrets and have created a new branch.

```
cat star_nodejs_org_chained.crt | dotgpg create ~/secrets/build/infra/star_nodejs_org_chained.crt
```

```
cat star_nodejs_org.key | dotgpg create ~/secrets/build/infra/star_nodejs_org.key
```

Validate that both are encrypted by looking at:

```
cat ~/secrets/build/infra/star_nodejs_org.key
```

and

```
cat ~/secrets/build/infra/star_nodejs_org_chained.crt
```

The should have similar footers/trailers to the existing content of https://github.com/nodejs-private/secrets/blob/master/build/infra/star_nodejs_org_chained.crt with the middle content being the encrypted part.

Decrypt the new files with

```
dotgpg cat ~/secrets/build/infra/star_nodejs_org.key
```

and

```
dotgpg cat ~/secrets/build/infra/star_nodejs_org_chained.crt
```

and compare against the original files you had encrypted.

Add the new files in git and commit.
Push your branch in nodejs-private and then create a pull request.

Delete any local copies of the non-encrypted key/certificate files

[ci.nodejs.org]: https://ci.nodejs.org
[ci-release.nodejs.org]: https://ci-release.nodejs.org
[GoGetSSL]: https://www.gogetssl.com/
[multi-year subscription]: https://www.gogetssl.com/wiki/general/multi-year-subscription-ssl/
[nodejs.org]: https://nodejs.org
[secrets repository]: https://github.com/nodejs-private/secrets
[unencrypted.nodejs.org]: https://unencrypted.nodejs.org

0 comments on commit 5f1d6c7

Please sign in to comment.