# Letsencrypt Tutorial

## Introduction

At some point you probably want to access your opentrigger setup from outside your firewall. This tutorial will guide you how to setup password protection and encrypt your traffic with [Letsencrypt](https://letsencrypt.org/). Please be aware that security is always an investment, and there is no such thing as *absolute security*. Blindly following this tutorial alone will not protect your data.

Forwarding ports on your firewall and setting up domain names is a very specific task we can not cover in this tutorial. Your Router/Firewall/... usually comes with documentation which should cover the former.\
Another source of information would be: [portforward.com](http://portforward.com/) (only read the articles, they also want to sell you software which does it for you - but do you really want to thrust that?).\
If you need a free subdomain with dyndns service have a look at: [freedns.afraid.org](http://freedns.afraid.org/)

## Requirements

For this tutorial we assume that you are running Raspbian jessie, your opentrigger stack ist already set up and you have a domain name configured.\
Your domain name resolution has to work from outside (the public internet) and on your local network. The TCP Ports 80 and 443 must be mapped to your device - nothing more, nothing less. Keep away form that DMZ or ExposedHost settings. We will use `letutorial.dev.opentrigger.com` as domain for this tutorial, please replace that with your hostname.

## Installing required Packages

```bash
sudo apt-get install nginx apache2-utils haveged
```

`nginx` is a resource friendly, but fully featured webserver.\
`apache2-utils` contain the `htpasswd` tool we will use to add basic authentication.\
`haveged` helps with entropy problems, its not a hard requirement, but will speed things up a bit.

After that nginx is running on port 80 and if you navigate to `http://letutorial.dev.opentrigger.com/` you should see the nginx default page.

We also need `certbot` which currently is the recomendet way of getting Letsencrypt certificates.

```
wget https://dl.eff.org/certbot-auto
sudo install certbot-auto /usr/local/bin/
rm certbot-auto
```

## Certificates

Now we start `certbot-auto` which will download and install its dependencies and performs (self)updates when needed. So the first run will take a little longer.

```bash
certbot-auto certonly --webroot -w /var/www/html/ -d letutorial.dev.opentrigger.com
```

Some dialogs will pop up and asking you to provide an Email address and agree to the 'Terms of Service'.

After the procedure is complete, certbot will tell you where your new certificates are stored:&#x20;

![](https://i.imgur.com/KKmxxI8.png)

## Configuring nginx

Generating dhparams, even with `havegd` running, this could take some time.

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

If you don't want to wait you could start another terminal session and leave that running in the background. (or use your shell to make that happen).

Setup your credentials. Substitute `<username>` with your preferred username.

```
sudo htpasswd -c /etc/nginx/letutorial.dev.opentrigger.com.htpasswd <username>
```

You will be asked for the password (twice). Please refer to `man htpasswd` on how to manage users.

Create a new *site* configuration file.

```
sudo nano /etc/nginx/sites-available/https
```

Paste the following content.

```
## sudo apt-get install nginx apache2-utils haveged

server {

    listen 443 ssl;
    server_name letutorial.dev.opentrigger.com; ## hostname

    ssl                         on;
    ssl_dhparam                 /etc/nginx/dhparam.pem;   ## create with: `sudo openssl dhparam -out /etc/nginx/dhparam.pem 2048` 
    ssl_certificate             /etc/letsencrypt/live/letutorial.dev.opentrigger.com/fullchain.pem;
    ssl_certificate_key         /etc/letsencrypt/live/letutorial.dev.opentrigger.com/privkey.pem;

    ssl_session_cache           shared:SSL:30m;
    ssl_session_timeout         30m;
    ssl_protocols               TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers                 ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
    ssl_buffer_size             8k;
    ssl_prefer_server_ciphers   on;

    add_header    Strict-Transport-Security max-age=31536000;

    ## if you want error or access logs
    # access_log  /var/log/nginx/letutorial.dev.opentrigger.com.access.log;
    # error_log /var/log/nginx/letutorial.dev.opentrigger.com.error.log;

    ## basic authentication - see `man htpasswd`
    auth_basic "Restricted";
    auth_basic_user_file /etc/nginx/letutorial.dev.opentrigger.com.htpasswd;    ## create with: `sudo htpasswd -c /etc/nginx/letutorial.dev.opentrigger.com.htpasswd <username>`

    ## you migt want to serve some static files
    # root /var/www/html;
    # location / { try_files $uri $uri/ =404; }
    # location ~ /\.  { return 404; }


    ## reverse proxy for node-red
    location /node-red/ {
      proxy_pass                      http://127.0.0.1:1880/;

      proxy_read_timeout              90;
      proxy_set_header                Host $host;
      proxy_set_header                X-Real-IP $remote_addr;
      proxy_set_header                X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header                X-Forwarded-Proto $scheme;
      proxy_set_header                Upgrade $http_upgrade;
      proxy_set_header                Connection $http_connection;
      proxy_http_version              1.1;
      proxy_pass_request_headers      on;

    }

    ## reverse proxy for mosquitto websockets (if it is configured and listening on port 8080)
    location /mosquitto-websockets/ {
      proxy_pass          http://127.0.0.1:8080/;

      proxy_http_version  1.1;
      proxy_set_header    Upgrade $http_upgrade;
      proxy_set_header    Connection "upgrade";
    }   

}
```

## Testing

Check if `openssl dhparam` is finished by now, if not you have to wait for it.

Enable the *site*.

```
sudo ln -s /etc/nginx/sites-available/https /etc/nginx/sites-enabled/
sudo service nginx restart
```

Now you should be able to access your device over a password protected and encrypted Link:

![](https://i.imgur.com/370GQGp.png)

Now go to&#x20;

[ssllabs.com/ssltest](https://www.ssllabs.com/ssltest/)

&#x20;and run the test. You should not go for less than A:&#x20;

![](https://i.imgur.com/PWmdyd9.png)

## Renewal

Your certificate is valid for 90 days, but renewal is easy:

```
certbot renew
```

It would be best to automate the renewal process, please consult [certbot's documentation](https://certbot.eff.org/docs/using.html#renewal) for that.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://acolono.gitbook.io/opentrigger/tutorials/letsencrypt-tutorial.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
