aaronwmorris / indi-allsky

Software to manage a Linux-based All Sky Camera.
GNU General Public License v3.0
197 stars 31 forks source link

Run without https? #1151

Closed henrikeri closed 4 months ago

henrikeri commented 4 months ago

Hi,

I plan on running allsky behind a reverse nginx proxy. This allows me to give it a separate subdomain. I use Nginx to handle https via certbot. Is there a way I could use Allsky without https, or a way to use the letsencrypt certificates to replace the self signed one?

Thanks for an awesome piece of software!

aaronwmorris commented 4 months ago

There are ways to run with just HTTP, but I would not recommend it. I would just proxy straight through to HTTPS to HTTPS, but there are some alternatives.

You can replace the certificate files at /etc/apache2/ssl/indi-allsky_apache.pem and /etc/apache2/ssl/indi-allsky_apache.key and the setup.sh script will not try to replace them.

You could also configure your nginx reverse proxy to talk directly to the gunicorn socket. There is an example of this config at service/nginx_astroberry_ssl

Just keep in mind if you proxy to the gunicorn socket, you should try to serve the images and videos directly from nginx as it will be faster than from the gunicorn web server.

Something like:

upstream indi_allsky_server {
    server unix:/var/lib/indi-allsky/gunicorn-indi-allsky.sock fail_timeout=0;
}

server {
    listen 80;

    root /var/www/html;

    return 302 https://$host$request_uri;

    rewrite ^/$ /indi-allsky;
}

server {
    listen 443;

    root /var/www/html;

    ssl_certificate           /etc/ssl/astroberry.crt;
    ssl_certificate_key       /etc/ssl/astroberry.key;

    ssl on;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    # 1 week HSTS header
    add_header Strict-Transport-Security "max-age=604800; includeSubDomains" always;

    rewrite ^/$ https://$host/indi-allsky;

    client_max_body_size 1024M;

    location /indi-allsky/images {
        alias /var/www/html/allsky/images;
        autoindex off;

        location ~* \.(jpe?g|png|tiff?|bmp|gif|fits?|webp|jp2|mp4|webm)$ {
            expires 90d;
            add_header Pragma public;
            add_header Cache-Control "public";
        }
    }

    location /indi-allsky/static {
        alias /home/pi/git/indi-allsky/indi_allsky/flask/static;
        autoindex off;

        location ~* \.(js|css|svg)$ {
            expires 1d;
            add_header Pragma public;
            add_header Cache-Control "public";
        }
    }

    location /indi-allsky {
        try_files $uri @proxy_to_indi_allsky;
    }

    proxy_read_timeout 180s;

    location @proxy_to_indi_allsky {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header Host $http_host;
      proxy_redirect off;
      proxy_pass http://indi_allsky_server;
    }
}
aaronwmorris commented 4 months ago

Also, gunicorn expects to receive the requests at the /indi-allsky/ context. If you proxy from a different path, you will have to adjust this in the location directive.

I know how to do this in Apache, but not nginx, but it should not be too difficult.

henrikeri commented 4 months ago

Thanks for reaching out. The Nginix snippit above. How would that have to be modified if the nginx is running on a separate server. The allsky is at 192..x.8 while the server is at 192..y.3?

Essentially what I have done for other services is just to add a reference to the ip as such (this works for nina and other services):

server {
      server_name allsky.mydomain.com;

      access_log /var/log/nginx/allsky.access;
      error_log /var/log/nginx/allsky.error;

      set $allsky 192.x.y.6;

      location / {
          proxy_pass http://192.x.x.6;
          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 X-Forwarded-Protocol $scheme;
          proxy_set_header X-Forwarded-Host $http_host;

          proxy_buffering off;
      }

          location /socket {
          proxy_pass http://$192.x.y.6;
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection "upgrade";
          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 X-Forwarded-Protocol $scheme;
          proxy_set_header X-Forwarded-Host $http_host;
      }
        add_header X-Frame-Options "SAMEORIGIN";
        add_header X-XSS-Protection "1; mode=block";
        add_header X-Content-Type-Options "nosniff";

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/allsky.smydomain.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/allsky.smydomain.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = allsky.mydomain.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

      listen 80;
      server_name allsky.mydomain.com;
    return 404; # managed by Certbot

}
aaronwmorris commented 4 months ago

If indi-allsky is running on a different server, I would just leave the existing apache configuration in place with the self-signed certificate.

Try something like this on your frontend nginx reverse proxy:

      location /indi-allsky {
          proxy_pass https://192.x.x.8;
          proxy_ssl_verify off;

          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_set_header X-Forwarded-Protocol $scheme;
          proxy_set_header X-Forwarded-Host $http_host;

          proxy_buffering off;
      }

If you want to change the path to /allsky/, this might work:

      location /allsky/ {
          proxy_pass https://192.x.x.8/indi-allsky/;
          proxy_ssl_verify off;

          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_set_header X-Forwarded-Protocol $scheme;
          proxy_set_header X-Forwarded-Host $http_host;

          proxy_buffering off;
      }
henrikeri commented 4 months ago

Thanks for the help. I managed to get it working with reverse proxy. However, seeing that I am running it on port 8080 and 8443 (other services on 80 and 443 on that server), I am getting some sort of rewrite done by apache2. Do you have any suggestions as to what I should change in indi-allsky.conf under the apache directory to take it from: https://allsky.mydomain.com:8443/indiallsky to https://allsky.mydomain.com?

I suspect it is something under this section:

<VirtualHost *:8443> RewriteEngine On RewriteRule "^/$" "/indi-allsky/" [R]

But I am honestly not familiar enough with apache2. Working nginx setup below. Asking as the current rewrite prohibits me from using cloudflare relay (only 443 and 80).

@aaronwmorris

server {

      server_name allsky.mydomain.com,;
      access_log /var/log/nginx/allsky.access;
      error_log /var/log/nginx/allsky.error;

      location / {
          proxy_pass https://127.0.0.1:8443/;
          proxy_ssl_verify off;

          proxy_buffering on;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_set_header X-Forwarded-Proto $scheme;
          proxy_set_header Host $http_host;

      }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/allsky.mydomain.com-0001/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/allsky.mydomain.com-0001/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
aaronwmorris commented 4 months ago

You can remove that rewrite. That function is only there to redirect from / to /indi-allsky when indi-allsky is the only application running.

Edit: To make this clearer, that is not technically a "rewrite". It is just a redirect, due to the [R] flag at the end.

henrikeri commented 4 months ago

Thanks for helping out. I skipped apache entirely and use nginx to present the webpage

aaronwmorris commented 4 months ago

No issues with that at all.