How to install NGINX as Reverse Proxy and configure Certbot on Amazon Linux 2023
Tags: aws, devops, cloud, linux
Published: 2023-04-28 13:16:03

In today's digital landscape, the importance of securing your web server and website cannot be overstated. One of the ways to achieve this is by using an HTTPS protocol, which encrypts the data transmitted between the server and client, ensuring that the information is safe from prying eyes. One of the most popular web servers used to achieve this is NGINX, which offers a robust and efficient platform for serving web content. In this article, we will walk you through the process of installing and configuring NGINX on an Amazon Linux 2023 instance, as well as setting up Certbot to obtain and renew SSL/TLS certificates for your website, ensuring that your website remains secure and trustworthy. Whether you are a seasoned web developer or a novice, this article will provide you with the knowledge and skills you need to secure your website on the AWS cloud.

## Disclaimer
In this article, only NGINX and Certbot will be installed for educational purposes. The configuration of NGINX may not be production ready.

## Preconditions

In this guide, we will connect to an AWS EC2 instance running Amazon Linux 2023 that has already been started and configured with an Elastic IP.
You can follow these steps by referring to the official AWS guide:
- [Launch an AWS EC2 Amazon Linux 2023 instance](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html);
- [Assign an Elastic IP address to the EC2 instance;](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html)


## Install NGINX

First of all, let's connect via SSH to our EC2 instance:

```
$ ssh -i ~/<PATH_TO_YOUR_PEM_FILE> ec2-user@<EC2_ELASTIC_IP>
```

Next, execute these commands to install NGINX and enable on startup:

```
$ sudo yum install nginx
$ sudo systemctl enable nginx && sudo systemctl start nginx
```

Now, let's assume that we want to configure NGINX to act as a reverse proxy on port 80 for a service running on port 5555.

 Let's open the NGINX configuration file:

```
sudo nano /etc/nginx/nginx.conf
```

And let's modify the server configuration by changing the value of `YOUR_DOMAIN` with the domain name associated with the EC2 instance (if any), and `EC2_PRIVATE_IPV4_ADDRESS` with the private IPv4 address of the EC2 instance, which can be retrieved from the AWS control panel:

```
    server {
        listen       80;
        listen       [::]:80;
        server_name  <YOUR_DOMAIN>;
        location / {
            proxy_pass http://<EC2_PRIVATE_IPV4_ADDRESS>:5555;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    }

```

After saving and closing the file, let's run a test to verify if the configuration is valid and restart the process:

```
$ sudo nginx -t
$ sudo systemctl restart nginx
```

Now, if the configuration is correct, it should be possible to reach our service through the address `http://<EC2_ELASTIC_IP>` or `http://<YOUR_DOMAIN>`.


## Install Cerbot

For installing Certbot and enabling HTTPS on NGINX, we will rely on Python. So, first of all, let's set up a virtual environment:

```
$ sudo python3 -m venv /opt/certbot/
$ sudo /opt/certbot/bin/pip install --upgrade pip
```

Afterwards, run this command to install Certbot:

```
$ sudo /opt/certbot/bin/pip install certbot certbot-nginx
```

Now, execute the following command to ensure that the `certbot` command can be run:

```
sudo ln -s /opt/certbot/bin/certbot /usr/bin/certbot
```

Finally, run the following command to obtain a certificate and let Certbot automatically modify the NGINX configuration, enabling HTTPS:

```
$ sudo certbot --nginx
```

After following the certificate generation wizard, we will be able to access our EC2 instance via HTTPS using the address `https://<EC2_ELASTIC_IP>` or `https://<YOUR_DOMAIN>`.

### Set up automatic renewal

To enable Certbot to automatically renew the certificates, it is sufficient to add a cron job by running the following command:

```
$ echo "0 0,12 * * * root /opt/certbot/bin/python -c 'import random; import time; time.sleep(random.random() * 3600)' && sudo certbot renew -q" | sudo tee -a /etc/crontab > /dev/null
```