Using Certbot and Express.js to secure your CRA that uses React Hooks on Ubuntu 18

Suru Dissanaike
HiMinds
Published in
7 min readJun 4, 2019

--

What do you do when you have developed a fantastic Create React App?
The obvious answer is that you need to deploy it and share the love!
The source code for this article is located here.

Background

The code used in this article is based on the work done by Robin Wieruch. I am a massive fan of Robin, and I highly recommend his blog and books. I have used parts of the following article; it covers the topic of fetching data using React Hooks. In this article, we create a React app that uses:

We also look at the following technologies in this article:

We have the following file structure in the repo used in this article:

.├── hn-app├── hn-secure-deploy└── node-certbot
  • hn-app is the hacker news search app that we are going to implement
  • hn-secure-deploy is an Express app that creates an HTTPS server and serves the CRA pages
  • node-certbot helps you install the Let’s encrypt certificates

hn-app

This is what the React app looks like:

The node-certbot project starts a web server and serves the challenge that is needed to prove your ownership of your domain.

To build the project, you need to run the following:

npm run build

It will look like this:

:~/git/himinds-boosting-innovation-web-secure-cra/hn-app$ npm run build> hn-app@0.1.0 build /home/<user>/git/himinds-boosting-innovation-web-secure-cra/hn-app> react-scripts buildCreating an optimized production build...Compiled successfully.File sizes after gzip:66.95 KB        build/static/js/2.eeba2585.chunk.js1.33 KB (+2 B)  build/static/js/main.69373626.chunk.js762 B           build/static/js/runtime~main.a8a9905a.js271 B           build/static/css/main.34de6062.chunk.cssThe project was built assuming it is hosted at the server root.You can control this with the homepage field in your package.json.For example, add this to build it for GitHub Pages:"homepage" : "http://myname.github.io/myapp",The build folder is ready to be deployed.You may serve it with a static server:serve -s buildFind out more about deployment here:https://bit.ly/CRA-deploy

Ubuntu 18.04 LTS firewall settings

We are using port 5000 to server our hacker-news app.

This is what you need to know to get started.

open TCP port in the firewall

Open incoming TCP port 5000 to any source IP address:

sudo ufw allow from any to any port 5000 proto tcp

List All UFW rules

sudo ufw status

Delete UFW rule

sudo ufw status numbered
sudo ufw delete <number>

Using Certbot to generate certificates

On Ubuntu 18 do the following to install Certbot.

$ sudo apt-get update
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository universe
$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install certbot

I partly followed this blog post and did the following:

sudo mkdir -p /home/<user>/certbot/{.config,etc}

It symlinks the let’s encrypt directory for easier access. Next step is to create ini-files that are used when generating the certificates. It makes all directories accessible via your home directory.

touch /home/<user>/certbot/cli.ini

The content of the cli.ini file:

# E-mail address for your account
email = your-email-address@example.org
config-dir = /home/<user>/certbot/etc
work-dir = /home/<user>/certbot/var/lib
logs-dir = /home/<user>certbot/var/log

Now it is time to generate the certificates, run the following command:

sudo certbot certonly -d EXAMPLE.com --manual -c /home/<user>/certbot/cli.ini

Below you will find my complete run; when you see the text “Create a file containing just this data: ” and the text “And make it available on your web server at this URL:” just use the node-certbot project to serve your challenge file.

$ certbot certonly -d my.domain.com — manual -c /home/<user>/certbot/cli.iniSaving debug log to /home/<user>/certbot/var/log/letsencrypt.logPlugins selected: Authenticator manual, Installer None- — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -Please read the Terms of Service athttps://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You mustagree in order to register with the ACME server athttps://acme-v02.api.letsencrypt.org/directory- — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -(A)gree/©ancel: A- — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -Would you be willing to share your email address with the Electronic FrontierFoundation, a founding partner of the Let’s Encrypt project and the non-profitorganization that develops Certbot? We’d like to send you email about our workencrypting the web, EFF news, campaigns, and ways to support digital freedom.- — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -(Y)es/(N)o: YObtaining a new certificatePerforming the following challenges:http-01 challenge for my.domain.com- — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -NOTE: The IP of this machine will be publicly logged as having requested thiscertificate. If you’re running certbot in manual mode on a machine that is notyour server, please ensure you’re okay with that.Are you OK with your IP being logged?- — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -(Y)es/(N)o: Y- — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -Create a file containing just this data:rVYzXXXtzbUHFtPJf_CzJqHA5AQioXXXnnlwdwVRr3E.0ppq8Ojs-5PHG75xLuxVwrvKXXXt8XJmt7LVPi9nVAAnd make it available on your web server at this URL:http://my.domain.com/.well-known/acme-challenge/rVYzXXXtzbUHFtPJf_CzJqHA5AQioXXXnnlwdwVRr3E- — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — -Press Enter to Continue (READ INSTRUCTIONS above!!!)Waiting for verification…Cleaning up challengesNon-standard path(s), might not work with crontab installed by your operating system package managerIMPORTANT NOTES:- Congratulations! Your certificate and chain have been saved at:/home/<user>/certbot/etc/live/my.domain.com/fullchain.pemYour key file has been saved at:/home/<user>/certbot/etc/live/my.domain.com/privkey.pemYour cert will expire on 2019–08–25. To obtain a new or tweakedversion of this certificate in the future, simply run certbotagain. To non-interactively renew *all* of your certificates, run“certbot renew”- Your account credentials have been saved in your Certbotconfiguration directory at /home/<user>/certbot/etc. You should makea secure backup of this folder now. This configuration directorywill also contain certificates and private keys obtained by Certbotso making regular backups of this folder is ideal.- If you like Certbot, please consider supporting our work by:Donating to ISRG / Let’s Encrypt: https://letsencrypt.org/donateDonating to EFF: https://eff.org/donate-le

My certificates have been generated, and I will find them here:

/home/<user>/certbot/etc/live/my.domain.com/

Now I can use them…

The certificates are valid for three months; the most common way of renewing them is to use Certbot and run it as a cronjob. Remember that you need to stop your services and restart them after the renewal is done.

Using PM2

PM2 is a production-ready runtime and process manager for Node.js applications. It is very convenient to use; in my production environment, I have created a custom user for running the NodeJS applications.

Run the following command to get access to your certificates in your home directory:

sudo env PATH=$PATH:/usr/local/bin pm2 startup -u <user>

Some useful commands when using PM2:

  • pm2 ls
  • pm2 start
  • pm2 stop
  • pm2 delete

If you want to change the name that you see when you do a pm2 ls; you can start your application in the following way:

pm2 start secure-server.js --name "secure deploy of CRA"

hn-secure-deploy

The hn-secure-deploy project is an Express.js application that acts as an HTTPS-server. For it to work, you need to set the following environment variables:

  • process.env.SERVE_DIRECTORY
  • process.env.SERVER_PORT

You need to modify your .~/.profile (Ubuntu) or ~/.bash_profile (Mac):

export SERVER_PORT=5000
export SERVE_DIRECTORY = /home/<user>/git/himinds-boosting-innovation-web-secure-cra/hn-app/build

You also need to modify the secure-server.js so that it points to the correct certificates.

pm2 start secure-server.js --name "secure deploy of CRA"

Summary

I must admit that I struggled quite a bit to get everything working. At some point, I decided to switch to using Reach Hooks, and that was a game changer for me. I never felt comfortable using classes in React, and the life-cycle-management never felt intuitive. I have just begun to learn React but I am eager to learn more because I really enjoy the coding.

Thank you for reading! Take care and hope to see you soon. 🙏🏽

This article is a living document please reach out to me if you want to contribute or see anything inaccurate here. This article is part of our “Boosting Innovation” project.

--

--