Shinyproxy: Run shinyproxy on https (443) only

Created on 21 Dec 2018  ·  25Comments  ·  Source: openanalytics/shinyproxy

Hi,

Have tried to set up ShinyProxy on https only. This seems possible as per the documentation - https://www.shinyproxy.io/security/#https-ssl-tls

Note that when only https is available (i.e. no redirects from http configured in nginx), it is required to add the following to the application.yml in order to use forward headers:
server:
useForwardHeaders: true

The problem is that when setting up with https only, NGINX ingress and OpenID, the https scheme is not passed through from the NGINX ingress to the ShinyProxy container which in-turn causes a number of issues with OpenId. Namely:

  • The Return URL that shinyproxy generates for OpenID on https is generated with http

The reason this happens is due to ShinyProxy using the default codes here - spring-security DefaultOAuth2AuthorizationRequestResolver.java # L141

bug

Most helpful comment

Managed to fix it.
This code

 server:
      useForwardHeaders: true

needs to be outside proxy:

All 25 comments

@garyallenkt Were you able to work around this issue?
Thanks!

Any updates on this issue ?

OpenAnalytics did a great job in helping resolve this.

You should be able to get the latest version of ShinyProxy (2.3.0) and follow the updated documentation here - https://www.shinyproxy.io/security/#https-ssl-tls

Best of luck.

Hi @garyallenkt,

Thank you for your quick response. I tried with the latest version but the issue persists in my case. I am embedding the entire shinyproxy in Iframe. In order to login, the server redirects the HTTPS connection to HTTP connection which is not allowed by the majority of the browsers. Do you know how I may fix this?

Regards

@fmichielssen

I am using a fork from Telethon kids repo and they use 2.3.0 too, but just to be sure I also pulled openanalytics's image. For your reference, here are my configs.

docker_compose.yaml

version: "3.6"
services:
  nginx:
    image: nginx:alpine
    container_name: tki_nginx
    restart: on-failure
    networks:
      - tki-net
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    ports:
      - 80:80
      - 443:443
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
    depends_on:
      - shinyproxy

  certbot:
    image: certbot/certbot
    container_name: certbot
    restart: on-failure
    volumes:
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"

  influxdb:
    image: influxdb:1.7.3-alpine
    container_name: tki_influxdb
    restart: on-failure
    volumes:
      - ./run_first_time.sh:/home/run_first_time.sh
      - type: volume
        source: shinyproxy_usage
        target: /var/lib/influxdb
        volume:
          nocopy: true
    networks:
      - tki-net
    ports:
      - 8083:8083
      - 8086:8086

  shinyproxy:
    depends_on:
      - influxdb
    image: openanalytics/shinyproxy
    container_name: open_analytics_shinyproxy
    restart: on-failure
    networks:
      - tki-net
    volumes:
      - ./application.yml:/opt/shinyproxy/application.yml
      - /var/run/docker.sock:/var/run/docker.sock
    expose:
      - 8080


networks:
  tki-net:
    name: tki-net

volumes:
  shinyproxy_usage:

application.yaml

proxy:
  title: Lorem ipsum

  hide-navbar: true
  landing-page: /
  heartbeat-rate: 10000
  heartbeat-timeout: 600000
  port: 8080
  docker:
    internal-networking: true
  authentication: openid
  openid:
    auth-url: https://lorem-ipsum.auth0.com/authorize
    token-url: https://lorem-ipsumauth0.com/oauth/token
    jwks-url: https://lorem-ipsum.auth0.com/.well-known/jwks.json
    client-id: SUPERCOOL
    client-secret: SUPERCOOLSECRET

  server:
      useForwardHeaders: true
  specs:
  - id: lorem_ipsum
    display-name: Lorem Ipsum
    description:  
    container-cmd: ["R", "-e", "shiny::runApp('/root/app')"]
    container-image: lorem/ipsum
    container-network: tki-net
    container-env:
      user: "shiny"
      environment:
        - APPLICATION_LOGS_TO_STDOUT=false
  usage-stats-url: http://influxdb:8086/write?db=shinyproxy_usagestats

and nginx.conf

worker_processes 1;
events {
  worker_connections 1024;
}

http {
  sendfile on;
  upstream tki_shinyproxy {
    server open_analytics_shinyproxy:8080;
  }


  server {
    listen 80;
    server_name example.org;
    server_tokens off;
  }

  server {
    listen 443;
    server_name example.org;
    server_tokens off;

    ssl on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;


    # SSL 
    ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;


    location / {
      proxy_pass http://tki_shinyproxy;

      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_read_timeout 600s;

      proxy_redirect off;
      proxy_set_header Host $http_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;
    }
  }
}

Any possible update on this? @garyallenkt @fmichielssen

Managed to fix it.
This code

 server:
      useForwardHeaders: true

needs to be outside proxy:

server is indeed a top-level block and not inside proxy

Unfortunately I am having the same problem with shinyproxy 2.3.1

I have this block outside the proxy block in the application.yml file

server:
useForwardHeaders: true

and I have the Nginx proxy set up exaclty as described in the documentation. I also (to test if i just had made some dumb ngnix error set up an Apache server and had the exact same problem).

My Nginx config blocks are:

server {
  listen                80;
  server_name           mydomain.com;
  rewrite     ^(.*)     https://$server_name$1 permanent;
}

server {
  listen                443 ssl;
  server_name           mydomain.com;
  access_log            /var/log/nginx/shinyproxy.access.log;
  error_log             /var/log/nginx/shinyproxy.error.log error;

  ssl on;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

  ssl_certificate      <path to crt>
  ssl_certificate_key   <path to key> 

   location / {
       proxy_pass          http://127.0.0.1:3600/;

       proxy_http_version 1.1;
       proxy_set_header Upgrade $http_upgrade;
       proxy_set_header Connection "upgrade";
       proxy_read_timeout 600s;

       proxy_redirect    off;
       proxy_set_header  Host             $http_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;
     }

}

Does anyone have any ideas about what might be wrong? or even thoughts about how to fix it?

What's the error? Can you share your config files like how I did? Maybe I can help you

@greenspray thank you for taking a look! I really am so stumped on this! My Nginx config it in the comment above, and this is what my application.yml looks like:

Aside from changing the port and adding the serverforward header line, i have tried to keep everything exactly as it was installed. I even tested this with shiny proxy 2.3.0 since that seemed to be working for everyone on this thread, but that had the same problem.

proxy:
  title: My Title
  logo-url: http://www.openanalytics.eu/sites/www.openanalytics.eu/themes/oa/logo.png
  landing-page: /
  heartbeat-rate: 10000
  heartbeat-timeout: 60000
  port: 3600
  authentication: simple
  admin-groups: scientists
  users:
  - name: jack
    password: password1
    groups: scientists
  - name: jeff
    password: password1
    groups: mathematicians
  # Docker configuration
  docker:
    cert-path: /home/none
    url: http://localhost:2375
    port-range-start: 20000
  specs:
  - id: 01_hello
    display-name: Hello Application
    description: Application which demonstrates the basics of a Shiny app
    container-cmd: ["R", "-e", "shinyproxy::run_01_hello()"]
    container-image: openanalytics/shinyproxy-demo
    access-groups: [scientists, mathematicians]

server:
  useForwardHeaders: true

logging:
  file:
    shinyproxy3.log

I also tested using apache as the webserver instead, and I have the same problem. My two current theories are that either something is wrong with my application.yml set up , or that because i dont understand proxy/reverse proxy that well something in my proxy block is allowing redirect to http.

@Claire-Kelley what's your exact error ?

@greenspray9 I am not getting an error ! It works perfectly so that when i go to my website i can see the shiny proxy log in page and it is served over HTTPS (this is the desired behavior). The problem is that when i log in (using simple authentication for now) the page starts being served over HTTP (not HTTPS- this is the problem! )

@ckelley-ct Sorry I have no experience with the type of login you want. Maybe there is some kind of redirect happening?

I have the same problem, did you find a solution?

@HEPBO3AH yes I did - for me the the problem was with the insecure image (the line logo-url: http://www.openanalytics.eu/sites/www.openanalytics.eu/themes/oa/logo.png in the example code above ). If you change that to an image served over https or remove it, then the problem resolves.

@HEPBO3AH @ckelley-ct FYI, we have moved the image to https://www.openanalytics.eu/shinyproxy/logo.png

I managed to make the reverse proxy with nginx and login securely using simple authentication, but once i try to use openid it fails because it uses http as callback protocol:

https://login.microsoftonline.com/9ac05e7d-e6a1-433a-9801-a60642903c2b/oauth2/authorize?response_type=code&client_id=d1abf394-b312-4717-a1c4-daaeee4f3b28&scope=openid%20email&state=5ZEbvVrVKBGpwId02I91SNRN-oPSbqkSR9oOlj7PRRQ%3D&redirect_uri=http://52.152.166.27/login/oauth2/code/shinyproxy&nonce=EhOFxVuVRksPOxd0hG-CKPDd2s78bhFIzSSC_PPU5-Q

getting error AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application: 'd1abf394-b312-4717-a1c4-daaeee4f3b28'.

This is my application.yml for shinyproxy 2.4.0, shiny proxy 2.3.1 seems to work from microsoft edge

proxy:
  title: Open Analytics Shiny Proxy
  logo-url: https://www.openanalytics.eu/shinyproxy/logo.png
  landing-page: /
  heartbeat-rate: 10000
  heartbeat-timeout: 60000
  port: 8080
  authentication: openid
  admin-groups: scientists
  #bind-address: 127.0.0.1
  # Example: 'simple' authentication configuration
  users:
  - name: jack
    password: password
    groups: scientists
  - name: jeff
    password: password
    groups: mathematicians
  # Example: 'openid' authentication configuration
  openid:
    auth-url: https://login.microsoftonline.com/9ac05e7d-e6a1-433a-9801-a60642903c2b/oauth2/authorize
    token-url: https://login.microsoftonline.com/9ac05e7d-e6a1-433a-9801-a60642903c2b/oauth2/token
    jwks-url: https://login.microsoftonline.com/common/discovery/keys
    client-id: d1abf394-b312-4717-a1c4-daaeee4f3b28
    client-secret: xxx
  # Docker configuration
  docker:
    container-backend: docker
    port-range-start: 20000
    container-protocol: https
  specs:
  - id: euler
    display-name: Euler's number
    #container-cmd: ["R", "-e", "shiny::runApp('/root/euler')"]
    container-image: euler
    access-groups: scientists


server:
    useForwardHeaders: true

logging:
  file:
    shinyproxy.log

I managed to make the reverse proxy with nginx and login securely using simple authentication, but once i try to use openid it fails because it uses http as callback protocol:

https://login.microsoftonline.com/9ac05e7d-e6a1-433a-9801-a60642903c2b/oauth2/authorize?response_type=code&client_id=d1abf394-b312-4717-a1c4-daaeee4f3b28&scope=openid%20email&state=5ZEbvVrVKBGpwId02I91SNRN-oPSbqkSR9oOlj7PRRQ%3D&redirect_uri=http://52.152.166.27/login/oauth2/code/shinyproxy&nonce=EhOFxVuVRksPOxd0hG-CKPDd2s78bhFIzSSC_PPU5-Q

getting error AADSTS50011: The reply URL specified in the request does not match the reply URLs configured for the application: 'd1abf394-b312-4717-a1c4-daaeee4f3b28'.

same error for me with 2.4

Hi @danielfm123, @roberts2727 so with ShinyProxy 2.4 the following config won't work anymore:

server:
    useForwardHeaders: true

instead you have to use:

server:
  forward-headers-strategy: native

Can you report back whether this solves the issue for you?

Issue Resolved! Thank you Sir.

Yes, it works but kills the package DT

ShinyProxy 2.4 the following conf

Would it be worth mentioning that on https://www.shinyproxy.io/security/?

Hi @shosaco this is already added to our new website: https://www.shinyproxy.io/documentation/security/#forward-headers . The URL your pointing to is an remainder from the old website, which I now cleaned up.

Was this page helpful?
0 / 5 - 0 ratings