Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update HTTPS functionality #2150

Open
shaqaruden opened this issue Dec 4, 2024 · 11 comments
Open

Update HTTPS functionality #2150

shaqaruden opened this issue Dec 4, 2024 · 11 comments

Comments

@shaqaruden
Copy link

When filing a bug, please include the following headings if possible. Any example text in this template can be deleted.

Overview of the Issue

Currently there is no Official way to enable HTTPS. I have been able to "hack" it in by modifying the docker-compose.yml file but for other users this should be easier. Currently there is a bash script called enable_ssl.sh but this does not seem to do anything. My assumption this is from the old non docker architecture.

Reproduction Steps

Steps to reproduce this issue, eg:

N/A

Environment

  • Raspberry Pi Hardware Version: Zimaboard running Debian 12 Bookworm
  • Raspberry Pi Network Setup: (ex. built-in WiFi, Ethernet, USB WiFi Adapter) USB Wifi adapter
  • Anthias Version: latest
@nicomiguelino
Copy link
Contributor

nicomiguelino commented Dec 4, 2024

@shaqaruden

There's an old pull request for this — #1940 — but it's not a good practice to ship self-signed certificates.
Feel free to share your changes here or open a pull request. I'd be happy to see your changes, be it a workaround or not.

@shaqaruden
Copy link
Author

shaqaruden commented Dec 4, 2024

I somewhat disagree with @vpetersson position on this. Self signed certs can be a right solution in some cases. For example where I work, we have setup the infrastructure to use self-signed certs for all our internal applications that are not exposed to the outside world where we are not able to use a service like Let's Encrypt or ZeroSSL. I would agree though that there should also be an option for using such services to obtain an certificate.

The way I have implemented this in my scenario I think would allow for the automatic retrieval of certs from Let's Encrypt or ZeroSSL as I am opted to exchange the nginx reverse proxy for a caddy reverse proxy which as long as the Caddyfile specifies https and does not specify any tls configuration will attempt to retrieve a certificate from one of those two services.

Here are the changes I made:

I created the directory $USER/screenly/docker/caddy and added my certificate, private key certificate to it.

To docker-compose.yml I removed anthias-nginx and added anthias-caddy and updated the reference to anthias-nginx in the anthias-viewer service

services:
  ...
  anthias-viewer:
    ...
    environment:
      ...
      - LISTEN=anthias-caddy
 ...
 anthias-caddy:
   image: caddy:latest
   ports:
     - 80:80
     - 443:443
   environment:
     - HOME=/data
   depends_on:
     - anthias-server
     - anthias-websocket
   restart: always
   volumes:
     - resin-data:/data:ro
     - /home/pacerboard/.screenly:/data/.screenly:ro
     - /home/pacerboard/screenly_assets:/data/screenly_assets:ro
     - /home/pacerboard/screenly/staticfiles:/data/screenly/staticfiles:ro
     - /etc/timezone:/etc/timezone:ro
     - /etc/localtime:/etc/localtime:ro
     - ./docker/caddy:/etc/caddy
     - ./docker/caddy/Zima140.pem:/etc/caddy/Zima140.pem:ro # this is my certificate, marked with :ro to make it read only
     - ./docker/caddy/cert-key.pem:/etc/caddy/cert-key.pem:ro # this is my private key certificate marked with :ro

Created $USER/screenly/docker/caddy/Caddyfile with the following content. This config mimics the nginx config as close as possible and redirects http traffic to https. There could be some errors in my efforts here

:80 {
        redir https://{host}{uri} 301
}

:443 {
       tls /etc/caddy/Zima140.pem /etc/caddy/cert-key.pem

       # Proxy requests to anthias-server
       @anthias {
               not path /static/* /ws /hotspot /screenly_assets /static_with_mime
       }
       reverse_proxy @anthias anthias-server:8080 {
               header_up Host anthias-server
               header_up X-Real-IP {remote}
               header_up X-Forwarded-For {remote}
       }

       # Handle API backup requests with extended timeouts
       @backup path_regexp /api/[0-9a-z]+/backup$
       reverse_proxy @backup anthias-server:8080 {
               transport http {
                       read_timeout 1800s
                       write_timeout 1800s
                       dial_timeout 1800s
               }
               header_up Host anthias-server
               header_up X-Real-IP {remote}
               header_up X-Forwarded-For {remote}
       }

       # Serve static files
       handle_path /static/* {
               root * /data/screenly/staticfiles
               file_server
       }

       # Handle WebSocket requests
       handle_path /ws {
               reverse_proxy anthias-websocket:9999 {
                       header_up Host {host}
                       header_up Upgrade {>Upgrade}
                       header_up Connection {>Connection}
               }
       }

       # Hotspot location
       @hotspot not file /data/.screenly/initialized
       handle_path /hotspot {
               root * /data
               rewrite * /hotspot/hotspot.html
               file_server
               @allowed_cidr {
                       remote_ip 172.16.0.0/12
               }
       }

       # Restrict /screenly_assets access
       handle_path /screenly_assets* {
               root * /data/screenly_assets
               file_server
               @allowed_cidr {
                       remote_ip 172.16.0.0/12
               }
       }

       # Static files with MIME type restrictions
       handle_path /static_with_mime* {
               root * /data/screenly/staticfiles
               file_server
               @allowed_cidr {
                       remote_ip 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
               }
       }
}

This approach with a little massaging would allow both using a self-signed certificate or retrieving one from Let's Encrypt or ZeroSSL. Again for the self-signed cert the user would need to provide this themselves and would not be shipped with Anthias

@nicomiguelino nicomiguelino changed the title Update HTTPS fucntionality Update HTTPS functionality Dec 4, 2024
@shaqaruden
Copy link
Author

shaqaruden commented Dec 5, 2024

@nicomiguelino I just came across an error with 403 Forbidden CSRF error. Will need to look into my the CSRF token is not being included on form submission

image

@nicomiguelino
Copy link
Contributor

@shaqaruden, does that issue occur when you are in HTTPS? If you temporarily switch back to HTTP, does it still happen?

@nicomiguelino
Copy link
Contributor

nicomiguelino commented Dec 5, 2024

@shaqaruden, we recently upgraded from Django 3 to 4, so there's a backwards-incompatible change related to CSRF.
If it happens on HTTPS, you can do the following:

Step 1 — Edit your NGINX config

Edit your nginx.production.conf or nginx.development.conf (depending on your environment) so that in includes the following changes:

proxy_set_header Origin https://anthias;

Now it will look something like this:

server {
    # ...

    location / {
        proxy_pass http://anthias;

        client_max_body_size 4G;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host anthias-server;
        proxy_set_header Origin http://anthias;
        proxy_set_header Origin https://anthias; # new line to be added
    }

  # ...
}

Step 2 — Edit your Django project settings

Modify anthias_django/settings.py and look for the CSRF_TRUSTED_ORIGINS setting and add https://anthias in the list.
After editing, the config should look like this:

# ...
CSRF_TRUSTED_ORIGINS = [
    'http://anthias',
    'https://anthias'
]
# ...

Final Steps

  • Restart and rebuild your containers to see if the changes take effect and if it works.

@shaqaruden
Copy link
Author

It's working fine over HTTP so I will need to make those changes.

Thanks! I'll give it a shot

@shaqaruden
Copy link
Author

I am trying to get building the images to work but the documentation provided in the master repo is not correct. I do not have a bin/install_poetry.sh file. Even after manually installing it I cannot get it to work it throws an error

The Poetry configuration is invalid:

  • 'authors' is a required property
  • Additional properties are not allowed ('package-mode' was unexpected)

@nicomiguelino
Copy link
Contributor

@shaqaruden, I can create a pull request that updates the documentation.
Meanwhile, you can try to install Poetry manually.

After installing and setting up Poetry, you can install the dependencies by running:

poetry install --only=docker-image-builder

You can build the images by running:

poetry run python -m tools.image_builder \
    --build-target=x86 \
    --dockerfiles-only \
    --disable-cache-mounts

# Temporary changes only
sed -i s/pull/build/g bin/upgrade_containers.sh

./bin/upgrade_containers.sh

@nicomiguelino
Copy link
Contributor

@shaqaruden, I created a pull request, #2153. I already requested a review for it.

@shaqaruden
Copy link
Author

@nicomiguelino another thing that needs to updated is an author needs to be added to pyproject.toml and package-mode needs to be remove, they cause poetry to throw errors

$ poetry install

The Poetry configuration is invalid:

  • 'authors' is a required property
  • Additional properties are not allowed ('package-mode' was unexpected)

@nicomiguelino
Copy link
Contributor

nicomiguelino commented Dec 9, 2024

@shaqaruden, what version of Poetry and Python are you using? Let me try to replicate the issue.

  • I'm using Python 3.11 and Poetry 1.8.5.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants