Skip to content

Enabling SSL with TinyPilot

icsy7867 edited this page Dec 3, 2022 · 6 revisions

Important Note! I'm not a network guy, I'm not a security guy, I'm not even a linux guy! I pretty much just followed a recipe. If better minds than mine notice anything amiss, hopefully they will correct it.

Important Note2 I quote Michael: "The one issue I see is that it requires manually editing nginx files. Those edits will get wiped out if the user uses the quick-install script to upgrade TinyPilot because TinyPilot expects to manage those files itself."

Comment (icsy7867)- you could always just make nginx configs immutable! They should persist and should not be able to be overwritten.

It may be an idea to backup those files somewhere after you edit them.

The notes below are what worked for me and are mainly copied direct from https://www.techrepublic.com/article/how-to-enable-ssl-on-nginx/

I'm asuming basic http authentication has already been implemented: https://github.com/mtlynch/tinypilot/wiki/Enabling-HTTP-Basic-Authentication-with-TinyPilot

I’m also assuming use of a self-signed certificate

So, generate a self-signed certificate.

$ 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 a few questions (such as country name, state, locality, etc.). The most important answer is the Common Name.
For this question, answer with the Pi's IP Address e.g. 192.168.1.50 (I'm guessing you need to set a static ip for your Pi)

Now configure NGINX to use SSL.
First, create a new configuration snippet file with the command:

$ sudo nano /etc/nginx/snippets/self-signed.conf

In that new file, add the following contents:

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

Save and close that file. Next, create a second configuration snippet that points to our newly-generated SSL key and certificate. To do this, issue the command:

$ sudo nano /etc/nginx/snippets/ssl-params.conf

In that new file, add the following contents:

  ssl_protocols TLSv1.2;  
  ssl_prefer_server_ciphers on;  
  ssl_dhparam /etc/ssl/certs/dhparam.pem;  
  ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;  
  ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0  
  ssl_session_timeout  10m;  
  ssl_session_cache shared:SSL:10m;  
  ssl_session_tickets off; # Requires nginx >= 1.5.9  
  # ssl_stapling on; # Requires nginx >= 1.3.7  
  # ssl_stapling_verify on; # Requires nginx => 1.3.7  
  resolver 8.8.8.8 8.8.4.4 valid=300s;  
  resolver_timeout 5s;  
  add_header X-Frame-Options DENY;  
  add_header X-Content-Type-Options nosniff;  
  add_header X-XSS-Protection "1; mode=block";  

Because we are using a self-signed certificate, we disable SSL stapling (a method for quickly and safely determining whether or not an SSL certificate is valid). If you're not using a self-signed certificate, remove the # symbols before the two lines. You can also change the resolver line to reflect your preferred DNS servers. Save and close that file. We also need to generate the dhparam.pem file with the command:

$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

The above command will take some time.

Now we need to edit tinypilot.conf again – see below
Here’s the entire file (update YOUR_SERVER_NAME as necessary. Anything I didn’t fully understand, such as proxy_pass I left alone and it seems to work)

  server {
      listen 443 ssl;
      listen [::]:443 ssl;
      include snippets/self-signed.conf;
      include snippets/ssl-params.conf;
        
      server_name YOUR_SERVER_NAME;
      root /opt/tinypilot;
      index index.html;
      auth_basic "KVM";
      auth_basic_user_file /etc/apache2/.htpasswd;
      proxy_buffers 16 16k;
      proxy_buffer_size 16k;
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-For $remote_addr;
      proxy_http_version 1.1;
      location /socket.io {
        proxy_pass http://tinypilot;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
      }
      location /state {
        proxy_pass http://ustreamer;
      }
      location /stream {
        proxy_pass http://ustreamer;
      }
      location / {
        proxy_pass http://tinypilot;
      }
      location ~* ^/.+\.(html|js|js.map|css|jpeg|png|ico)$ {
        root "/opt/tinypilot/app/static";
      }
  }
  
  server {
      listen 80;
      listen [::]:80;
  
      server_name YOUR_SERVER_NAME;
      return 302 https://$server_name$request_uri;
  }

restart nginx

$ sudo systemctl restart nginx

Naturally you will see warnings about the self-certificate when you head to the https:// url

I hope this works for you! =o)