GeoNode / geonode-docker

Django base images for GeoNode
Other
9 stars 33 forks source link

Option to force the scheme forwarded by Nginx #46

Open giohappy opened 1 week ago

giohappy commented 1 week ago

Overview

There are cases where the Nginx deployed with GeoNode sits itself behind an HTTP proxy, and this proxy often performs the SSL termination itself. In this cases Nginx is served over port 80 and the HTTP_HOST variable is used to set the server name, instead of HTTPS_HOST. The scheme forwarded by Nginx is obtained from the HTTP(S)_HOST variable, so if Nginx is served over 80, it will forward the http scheme to Django, even if GeoNode is served over https by the external HTTP server. This breaks the GeoNode APIs, because they get advertized (URLS and links inside the API responses) as being served over http, instead of https.

We introduce a new optional HTTP_FORWARDED_SCHEME .env variable that can be set to force the scheme forwarded by Nginx. In case it is empty the current heuristic based on the host is maintained.

Solution

+if [ -n "${HTTP_FORWARDED_SCHEME}" ]; then

ridoo commented 1 week ago

I configured external proxies (doing the TLS stuff) without that extra property. There is actually no need to disable https.

The proxy nginx includes this geonode.conf:

location / {
    proxy_pass http://geonode;  # proxy runs in the same network
    proxy_request_buffering off;
    client_max_body_size 0;

    proxy_set_header  Host $http_host;
    proxy_set_header  Origin $scheme://$http_host;
    proxy_set_header  X-Forwarded-Host $http_host;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header  X-Forwarded-Proto https;
}

However, we are using $http_host which keeps the scheme in the host. See here:

  proxy_redirect              off;
  proxy_set_header            Host $http_host;
  proxy_set_header            Origin $HTTP_SCHEME://$http_host;
  proxy_set_header            X-Real-IP $remote_addr;
  proxy_set_header            X-Forwarded-Host $http_host;
  proxy_set_header            X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header            X-Forwarded-Proto $HTTP_SCHEME;
  proxy_hide_header           X-Frame-Options;
  proxy_request_buffering     off;

BTW: $http_host was mentioned already as solution in

giohappy commented 1 week ago

@ridoo the point is that without disabling https you might end up having a partially configured SSL termination in the Nginx proxy (either because Letsencrypt won't reach it, you don't have custom SSL certs for it, or you don't want to use self-signed certs).

I don't think $http_host; is relevant here. It was mainly proposed to forward the port (I haven't had the chance yet to test the proposal from Ricardo). The scheme is already forwarded by X-Forwarded-Proto $HTTP_SCHEME;

ridoo commented 1 week ago

the point is that without disabling https you might end up having a partially configured SSL termination in the Nginx proxy (either because Letsencrypt won't reach it, you don't have custom SSL certs for it, or you don't want to use self-signed certs).

I overlay the actual cert config like so:

  volumes:
    - statics:/mnt/volumes/statics
    # Link to a custom certificate here
    - /etc/letsencrypt/live/<your_domain>/fullchain.pem:/geonode-certificates/autoissued/fullchain.pem
    - /etc/letsencrypt/live/<your_domain>/privkey.pem:/geonode-certificates/autoissued/privkey.pem
giohappy commented 1 week ago

ok so @ridoo you're using a self-signed cert for the internal Nginx.

ridoo commented 1 week ago

ok so @ridoo you're using a self-signed cert for the internal Nginx.

actually, what is created and updated by letsencrypt. This is not a self-signed certificate. Actually, what the GeoNode's letsencrypt service is doing, but managed by the server setup.

giohappy commented 4 days ago

In my case the certificates are managed outside GeoNode and SSL termination is performed by the frontend server. The internal GeoNode's Nginx is not exposed to the internet. This is the reason we don't need (and don't want in this specific case) to set it up over SSL.