Geonode: Geonode CORS issue via https behind a proxy.

Created on 30 Jul 2019  路  16Comments  路  Source: GeoNode/geonode

Expected Behavior

Geonode working via https behind a proxy.

Actual Behavior

CORS issue in Angular caused by

assets.min.js?v=2.10rc5:34 Error: [$sce:insecurl] Blocked loading resource from url not allowed by $sceDelegate policy.  URL: http://ggg.be:443/static/geonode/js/templates/cart.html
http://errors.angularjs.org/1.4.0/$sce/insecurl?p0=http%3A%2F%2Fggg.be%3A443%2Fstatic%2Fgeonode%2Fjs%2Ftemplates%2Fcart.html
    at assets.min.js?v=2.10rc5:32
    at j (assets.min.js?v=2.10rc5:34)
    at Object.d.<computed> [as getTrustedResourceUrl] (assets.min.js?v=2.10rc5:34)

Steps to Reproduce the Problem

  1. Install Geonode via Docker compose
  2. Update the docker-compose.override.yml
    SITEURL=https://ggg.be
  3. Run: docker-compose -f docker-compose.yml -f docker-compose.override.yml up -d
  4. tasks.py creates the ~/.override_env file which is sourced to set the necessary environment variable. In the ~/.override_env file the variable SITEURL=http://ggg.be:443/ is exported but the value here is not using the SITEURL from the docker-compose.override.yml.

The ~/.override_env file is created in tasks.py starting from line 28.
There you can see that the SITEURL is reconstructed via pub_ip and pub_port and forced to http.

    envs = {
        "public_fqdn": "{0}:{1}".format(pub_ip, pub_port or 80),
        "public_host": "{0}".format(pub_ip),
        "dburl": db_url,
        "geodburl": geodb_url,
        "override_fn": override_env
    }
    if os.environ.get(
        'GEONODE_LB_HOST_IP'
    ) and os.environ.get(
        'GEONODE_LB_PORT'
    ):
        ctx.run("echo export GEOSERVER_PUBLIC_LOCATION=\
http://{public_fqdn}/geoserver/ >> {override_fn}".format(**envs), pty=True)
        ctx.run("echo export GEOSERVER_WEB_UI_LOCATION=\
http://{public_fqdn}/geoserver/ >> {override_fn}".format(**envs), pty=True)
        ctx.run("echo export SITEURL=\
http://{public_fqdn}/ >> {override_fn}".format(**envs), pty=True)

The Django applications uses the SITEURL in his base template causing CORS issues because the application is loaded via https but ajax call or targeted to http (due to the SITEURL variable is forced to http).

Specifications

  • GeoNode version: 2.10rc5
  • Installation method (manual, GeoNode Docker, SPCGeoNode Docker): Docker compose
  • Platform: Debian
  • Additional details:
docker feature needs further investigation wontfix

All 16 comments

Hello,
I have the exact same issue as @wimpeelaerts

Specifications :

  • A bare-metal server with Docker and a nginx + letsencrypt companion setup
  • Geonode version : 2.10rc5
  • Installation method (manual, GeoNode Docker, GeoNode Core Docker): Docker compose
  • Platform : Debian

Customized compose file :

I adapted the provided docker-compose files to isolate the GeoNode stack from others in the server. Please find below the docker-compose.yml I customized to fit my needs.

The import-osm things eases the creation of an offline basemap for GeoNode.

version: '2.2'
services:

  db:
    image: geonode/postgis:10
    restart: unless-stopped
    container_name: db4${COMPOSE_PROJECT_NAME}
    stdin_open: true
    # tty: true
    labels:
        org.geonode.component: db
        org.geonode.instance.name: geonode
    volumes:
      - dbdata:/var/lib/postgresql/data
      - dbbackups:/pg_backups
    env_file:
      - ./scripts/docker/env/${SET_DOCKER_ENV}/db.env
    networks:
      - geonode

  geoserver:
    image: geonode/geoserver:2.15.2
    restart: unless-stopped
    container_name: geoserver4${COMPOSE_PROJECT_NAME}
    stdin_open: true
    # tty: true
    labels:
        org.geonode.component: geoserver
        org.geonode.instance.name: geonode
    depends_on:
      - db
      - data-dir-conf
    volumes:
      - geoserver-data-dir:/geoserver_data/data
    env_file:
      - ./scripts/docker/env/${SET_DOCKER_ENV}/geoserver.env
    networks:
      - geonode


  django:
    restart: unless-stopped
    image: geonode/geonode:latest
    container_name: django4${COMPOSE_PROJECT_NAME}
    stdin_open: true
    # tty: true
    labels:
        org.geonode.component: django
        org.geonode.instance.name: geonode
    depends_on:
      - db
      - data-dir-conf
    # command: paver start_django -b 0.0.0.0:8000
    # command: uwsgi --ini uwsgi.ini
    volumes:
      - statics:/mnt/volumes/statics
      - geoserver-data-dir:/geoserver_data/data
    env_file:
      - ./scripts/docker/env/${SET_DOCKER_ENV}/django.env
    networks:
      - geonode

  geonode:
    image: geonode/nginx:${SET_DOCKER_ENV}
    restart: unless-stopped
    container_name: nginx4${COMPOSE_PROJECT_NAME}
    stdin_open: true
    # tty: true
    labels:
        org.geonode.component: nginx
        org.geonode.instance.name: geonode
    depends_on:
      - django
      - geoserver
    #ports:
    #  - "80:80"
    volumes:
      - statics:/mnt/volumes/statics
    environment:
      # Modify the following parameters like this :
      #    - VIRTUAL_HOST -> the nexcloud instance subdomain name
      #    - LETSENCRYPT_HOST -> same here
      #    - LETSENCRYPT_EMAIL -> the email you want to receive renewal issues in
      - VIRTUAL_HOST=<fqdn>
      - VIRTUAL_PORT=80
      - LETSENCRYPT_HOST=<fqdn>
      - LETSENCRYPT_EMAIL=<address>@gmail.com
    networks:
      - default
      - geonode

  pgadmin4:
    image: dpage/pgadmin4
    volumes:
      - '/private/var/lib/pgadmin:/var/lib/pgadmin'
      - '/path/to/certificate.cert:/certs/server.cert'
      - '/path/to/certificate.key:/certs/server.key'
      - '/tmp/servers.json:/servers.json'
    environment:
      - PGADMIN_DEFAULT_EMAIL=<address>@gmail.com
      - PGADMIN_DEFAULT_PASSWORD=<passwd>
      - VIRTUAL_HOST=<fqdn>
      - VIRTUAL_PORT=80
      - LETSENCRYPT_HOST=<fqdn>
      - LETSENCRYPT_EMAIL=<address>@gmail.com
    networks:
      - default
      - geonode

  import-osm:
    build: ./geonode-basemap-toolkit/osm2pgsql
    env_file: .imports_env
    networks:
      - default
      - geonode

  data-dir-conf:
    image: geonode/geoserver_data:2.15.2
    restart: on-failure
    container_name: gsconf4${COMPOSE_PROJECT_NAME}
    labels:
        org.geonode.component: conf
        org.geonode.instance.name: geonode
    command: /bin/true
    volumes:
      - geoserver-data-dir:/geoserver_data/data
    networks:
      - geonode

volumes:
  statics:
    name: ${COMPOSE_PROJECT_NAME}-statics
  geoserver-data-dir:
    name: ${COMPOSE_PROJECT_NAME}-gsdatadir
  dbdata:
    name: ${COMPOSE_PROJECT_NAME}-dbdata
  dbbackups:
    name: ${COMPOSE_PROJECT_NAME}-dbbackups
  rabbitmq:
    name: ${COMPOSE_PROJECT_NAME}-rabbitmq

networks:
  default:
    external:
      #Replace here the backend network name obtained from sudo docker network ls
      name: frontend-https-revproxy_backend
  geonode:

Thanks @wimpeelaerts and @ginkun. HTTPS in not supported yet, I've added the label feature indeed

@ginkun There is SPC-GeoNode which is also a docker composition and is able to get served via LetsEnscrypt and https. Take a look at it: https://github.com/GeoNode/geonode/tree/master/scripts/spcgeonode

@gannebamm Thank you very much, it does makes sense indeed :) I'll have a look at it and provide feedback if it fails.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

up

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Please reopen.

Docker SPC doesn't have CORS enabled by default. These part is not present in web.xml :

https://docs.geoserver.org/latest/en/user/production/container.html#enable-cors

<web-app>
  <filter>
      <filter-name>cross-origin</filter-name>
      <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>cross-origin</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
 </web-app>

I just enter in a container, edit the file with Vi (What a pain, I ate Vi ! ), then shutdown.sh script and restart docker geoserver and it works ! I didn't have a good answer in Leaflet from GetFeatureInfo

You'll need to add the following variable to JAVA_OPTS

-DGEOSERVER_CSRF_DISABLED=true

I'll create a PR in order to add this one to the default config and docker images.

See https://github.com/GeoNode/geonode/pull/5600/files#diff-575d7b5b3e81e24fba66d955352253b0R55

What about security issue then ?

@afabiani instead of -DGEOSERVER_CSRF_DISABLED would -DGEOSERVER_CSRF_WHITELIST be of an option as well? This would be a bit more secure. Of course, we could then not set it as default but just document it.

By default should be good : may be I'm wrong but an SDI without GetFeatureInfo is not really usefull !
Using WMS is the main part of SDI in GIS or web app librairies like leaflet ...

@kikislater From what I read the option is a CRSF protection: https://docs.geoserver.org/stable/en/user/security/webadmin/csrf.html So it's not only about the proxy but for preventing CRSF attacks in general. However, I would not overcomplicate it. If Alessio sets it as default I'm fine with it .

As usual, the default GeoNode setup is meant to be an "easy to deploy and test" instance.
Far to be used in a production environment.
Until now we always have been threated those topics separately, even though the public documentation is still incomplete regarding the sections describing on how to secure your system.

Good for me !

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

hishamkaram picture hishamkaram  路  9Comments

jondoig picture jondoig  路  8Comments

ingenieroariel picture ingenieroariel  路  10Comments

t-book picture t-book  路  5Comments

HaidarZ picture HaidarZ  路  4Comments