# Setting up SSL on Ubuntu

The easiest way to secure connection to your UI Bakery instance with an SSL certificate is to use an additional web server that will proxy requests to your UI Bakery instance. \
Below you can find instructions on how to do that using:&#x20;

* a popular **web server** [**Nginx**](https://www.nginx.com/)
* a **free SSL certificate** that is generated by [Let's Encrypt](https://letsencrypt.org/) or a **self-signed certificate**
* a **tool** **to rotate SSL certificates** called [Certbot](https://certbot.eff.org/)

{% hint style="info" %}
This tutorial assumes that you would like to configure your UI Bakery instance to be run at the domain **`https://bakery.example.com`** and that your environmental variable **UI\_BAKERY\_APP\_SERVER\_NAME** is set to **`https://bakery.example.com`**
{% endhint %}

## Install and configure Nginx

We will use additional web server Nginx to proxy requests to your UI Bakery instance. To install Nginx on your machine run:

```bash
sudo apt update
sudo apt install nginx
```

After Nginx is installed, you need to create a configuration for your UI Bakery platform in its configuration. Assuming, that you would like to run UI Bakery at the domain name `bakery.example.com` you need to create the following file located at **`/etc/nginx/sites-enabled/bakery.example.com`**:

```nginx
server {
    listen 80;
    listen [::]:80;
    
    index index.html index.htm index.nginx-debian.html;
    
    server_name bakery.example.com;
    client_max_body_size 50M;
    
    location / {
        proxy_pass http://localhost:3030;
    }
}
```

Afterward, you can verify the syntax of your config file using the following command:

```bash
sudo nginx -t
```

If you get any error, open your configuration file and check that the syntax is correct.

## Option 1. Use Lets-Encrypt certificate

[Let's Encrypt](https://letsencrypt.org/) is a Certificate Authority (CA) that facilitates obtaining and installing free TLS/SSL certificates.

### Install Certbot

[Certbot](https://certbot.eff.org/) is a tool that helps you automate the process of acquiring and rotating of SSL certificates. The Certbot team suggests installing the tool using `snap`. Install it if you don't have it installed already.

```bash
sudo snap install core; sudo snap refresh core
```

Afterward, you can install the Certbot tool:

```bash
sudo snap install --classic certbot
```

Finally, you can link Certbot to the directory available in PATH so you could easily run this tool from the command line without using the full path to the executable:

```bash
sudo ln -s /snap/bin/certbot /usr/bin/certbot
```

### Configure Certbot

The easiest way to obtain a certificate and use it in your Nginx configuration is through the Certbot Nginx plugin:

```bash
sudo certbot --nginx -d bakery.example.com
```

After you run this command, the SSL certificate would be generated and the Nginx configuration file will be updated. So the only thing left to do is to reload the Nginx server:

```bash
sudo systemctl reload nginx
```

{% hint style="warning" %}
Make sure that port **443** is accessible on your VM!&#x20;
{% endhint %}

## Option 2. Use self-signed certificate

### Create self signed certificate

To generate a self-signed key and certificate pair using OpenSSL type the following command:

```bash
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
```

You will be asked to to fill out the prompts. Make sure the Common Name (e.g. server FQDN or YOUR name) matches the domain in your nginx config.&#x20;

Then you will need to create a strong Diffie-Hellman (DH) group with the following command:&#x20;

```bash
sudo openssl dhparam -out /etc/nginx/dhparam.pem 4096
```

### Configure Nginx

Create a configuration snippet pointing to the SSL key and certificate in the **`/etc/nginx/snippets/self-signed.conf`** file:

```
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
```

Put into the **`/etc/nginx/snippets/ssl-params.conf`** file the following SSL settings:&#x20;

```nginx
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/dhparam.pem; 
ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
ssl_ecdh_curve secp384r1;
ssl_session_timeout  10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable strict transport security for now. You can uncomment the following
# line if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
```

Update your site configuration at  **`/etc/nginx/sites-enabled/bakery.example.com` :**

<pre class="language-nginx"><code class="lang-nginx">server {
    listen 443 ssl;
    listen [::]:443 ssl;
    include snippets/self-signed.conf;
    include snippets/ssl-params.conf;

<strong>    server_name bakery.example.com;
</strong>    client_max_body_size 50M;
    
    location / {
        proxy_pass http://localhost:3030;
    }
}

server {
    listen 80;
    listen [::]:80;

    server_name bakery.example.com;

    return 302 https://$server_name$request_uri;
}
</code></pre>

After that you can check that your Nginx configuration is correct with the command:

```bash
sudo nginx -t
```

And then restart the Nginx service:

```bash
sudo systemctl restart nginx
```
