[keycloak-user] Gatekeeper failing to proxy for redirect or mobile! :(

Nick Powers sshscp at gmail.com
Mon Sep 9 10:09:59 EDT 2019


Thanks for your quick response Bruno!

The flow of my traffic goes like this:
1) User enters https://commentconext.com/protected/dashboard/ in their
browser.
2) Commentconext.com resolves to a public IP that points to a VM on
DigitalOcean where I run Docker.
3) The traffic hits Nginx proxy that handles the HTTPS traffic and then
makes the traffic HTTP for the rest of the flow.
4) The traffic hits Gatekeeper, and if needed, Gatekeeper authenticates
with Keycloak which I have hosted on another VM on DigitalOcean where I
also run Docker.
5) KeyCloak, if needed, authenticates with the identity provider(Google).
6) Gatekeeper proxies my traffic to http://webapp

I am running Keycloak and Gatekeeper in docker containers.  Below is the
configuration of both:

Keycloak docker config:

version: '3'

services:

  keycloak:
    container_name: keycloak
    image: jboss/keycloak
    container_name: keycloak
    restart: always
    ports:
      - 0.0.0.0:8080:8080
    environment:
      DB_DATABASE: ${DB_DATABASE}
      DB_USER: ${DB_USER}
      DB_PASSWORD: ${DB_PASSWORD}
      JDBC_PARAMS: ${JDBC_PARAMS}
      KEYCLOAK_HOSTNAME: ${KEYCLOAK_HOSTNAME}
      KEYCLOAK_HTTP_PORT: ${KEYCLOAK_HTTP_PORT}
      KEYCLOAK_USER: ${KEYCLOAK_USER}
      KEYCLOAK_PASSWORD: ${KEYCLOAK_PASSWORD}
      VIRTUAL_HOST: ${VIRTUAL_HOST}
      VIRTUAL_PORT: ${VIRTUAL_PORT}
      PROXY_ADDRESS_FORWARDING: ${PROXY_ADDRESS_FORWARDING}
      LETSENCRYPT_HOST: ${LETSENCRYPT_HOST}
      LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL}
    depends_on:
      - postgres

Here is my .env file, that sets the environment variables above:

DB_DATABASE=keycloak_db
DB_USER=keycloak_db_user
DB_PASSWORD="<snip>"
KEYCLOAK_HOSTNAME=auth.clearauth.com
KEYCLOAK_HTTP_PORT=8080
KEYCLOAK_USER=admin
KEYCLOAK_PASSWORD="<snip>"
JDBC_PARAMS="ssl=false"
PROXY_ADDRESS_FORWARDING=true
VIRTUAL_HOST=auth.clearauth.com
VIRTUAL_PORT=8080

Gatekeeper docker config:

  gatekeeper:
    container_name: gatekeeper
    restart: always
    image: keycloak/keycloak-gatekeeper:latest
    ports:
      - 0.0.0.0:3001:3001
    environment:
      VIRTUAL_HOST: ${VIRTUAL_HOST}
      VIRTUAL_PORT: ${VIRTUAL_PORT}
      LETSENCRYPT_HOST: ${LETSENCRYPT_HOST}
      LETSENCRYPT_EMAIL: ${LETSENCRYPT_EMAIL}
    volumes:
      - ./conf/gatekeeper.yml:/etc/gatekeeper.yml
    depends_on:
      - letsencrypt
      - nginx-proxy
      - webapp
    command: --config /etc/gatekeeper.yml

Here is my .env file, that sets the environment variables above:

VIRTUAL_HOST=commentcontext.com
VIRTUAL_PORT=3001
LETSENCRYPT_HOST=commentcontext.com
LETSENCRYPT_EMAIL=certs at commentcontext.com

Here is my gatekeeper.yml file:

discovery-url: http://auth.clearauth.com/auth/realms/user
client-id: context
client-secret: <snip>
listen: 0.0.0.0:3001
enable-token-header: false
enable-authorization-header: false
http-only-cookie: true
enable-refresh-tokens: true
enable-logging: true
enable-json-logging: true
enable-encrypted-token: false
no-redirects: false
redirection-url: https://commentcontext.com/
encryption-key: <snip>
cookie-access-name: sso-token
cookie-refresh-name: sso-refresh
upstream-url: http://webapp
upstream-keepalives: true
skip-upstream-tls-verify: true
enable-security-filter: true
headers:
  myheader_name: my_header_value
resources:
- uri: /protected/*
  methods:
  - GET
- uri: /*
  methods:
  - PUT

Below are the logs from Gatekeeper under several different scenarios:

Logs from gatekeeper during successful attempt from desktop(chrome):

{"level":"error","ts":1568035870.989644,"msg":"no session found in request,
redirecting for authorization","error":"authentication session not found"}
{"level":"info","ts":1568035870.990942,"msg":"client
request","latency":0.004156151,"status":307,"bytes":95,"client_ip":"
192.168.64.3:55072","method":"GET","path":"/protected/dashboard/"}
{"level":"info","ts":1568035871.037399,"msg":"client
request","latency":0.000132817,"status":307,"bytes":296,"client_ip":"
192.168.64.3:55074","method":"GET","path":"/oauth/authorize"}
{"level":"info","ts":1568035895.414867,"msg":"issuing access token for
user","email":"nick at nickpowers.info
","expires":"2019-09-09T13:36:35Z","duration":"4m59.585136403s"}
{"level":"info","ts":1568035895.4164033,"msg":"client
request","latency":0.165521442,"status":307,"bytes":57,"client_ip":"
192.168.64.3:55076","method":"GET","path":"/oauth/callback"}
{"level":"info","ts":1568035896.4183657,"msg":"client
request","latency":0.954246584,"status":200,"bytes":159843,"client_ip":"
192.168.64.3:55080","method":"GET","path":"/protected/dashboard/"}
{"level":"info","ts":1568035896.5251906,"msg":"client
request","latency":0.00505199,"status":200,"bytes":6341,"client_ip":"
192.168.64.3:55110
","method":"GET","path":"/protected/dashboard/styles/extras.1.3.1.min.css"}
{"level":"info","ts":1568035896.5272646,"msg":"client
request","latency":0.00889763,"status":200,"bytes":1208,"client_ip":"
192.168.64.3:55112
","method":"GET","path":"/protected/dashboard/images/shards-dashboards-logo.svg"}
{"level":"info","ts":1568035896.6020262,"msg":"client
request","latency":0.082489547,"status":200,"bytes":805628,"client_ip":"
192.168.64.3:55108
","method":"GET","path":"/protected/dashboard/styles/shards-dashboards.1.3.1.css"}
{"level":"info","ts":1568035896.7910855,"msg":"client
request","latency":0.009341256,"status":200,"bytes":8807,"client_ip":"
192.168.64.3:55124
","method":"GET","path":"/protected/dashboard/scripts/app/app-analytics-overview.1.3.1.js"}
{"level":"info","ts":1568035896.7940302,"msg":"client
request","latency":0.011186249,"status":200,"bytes":3898,"client_ip":"
192.168.64.3:55120
","method":"GET","path":"/protected/dashboard/scripts/extras.1.3.1.min.js"}
{"level":"info","ts":1568035896.7954087,"msg":"client
request","latency":0.011887251,"status":200,"bytes":6614,"client_ip":"
192.168.64.3:55122
","method":"GET","path":"/protected/dashboard/scripts/shards-dashboards.1.3.1.min.js"}
{"level":"info","ts":1568035897.4635108,"msg":"client
request","latency":0.001947231,"status":404,"bytes":281,"client_ip":"
192.168.64.3:55132","method":"GET","path":"/favicon.ico"}


Logs from gatekeeper during unsuccessful attempt from desktop(chrome), this
is from a redirect in the app, after the successful login above.

{"level":"info","ts":1568036254.6685731,"msg":"client
request","latency":0.551675736,"status":302,"bytes":0,"client_ip":"
192.168.64.3:55272","method":"GET","path":"/protected/dashboard/delete.php"}


Here is the delete.php, that calls the redirect that seems to cause this
issue.  It works fine, as long as I have the correct REFERER and it doesn't
need to do the redirect.  But, if I just type the link in directly, so it
doesn't have a REFERER then it hits that header("Location:
/protected/dashboard"); which should redirect to
https://commentcontext.com/protected/dashboard but instead it sends me to
https://webapp/protected/dashboard.  To me this seems to indicate that
Gatekeeper cannot proxy the redirect.

<?php require_once '../include/YouTube.php';

if( 'https://commentcontext.com/protected/dashboard/index.php' !=
$_SERVER['HTTP_REFERER'] ) {
       #
       # Invalid location, refresh to dashboard
       #
       header("Location: /protected/dashboard");
       exit;

}

#
# Delete comment from youtube
#
$youtube->comments->delete($_POST["commentId"]);

echo "comment deleted<br>";


Logs from Gatekeeper when trying to connect from my tablet (android
chrome).  NOTE: this failed every attempt up until now, when I just tried
it actually sent me to my site, like it should.  I'm not sure what changed.

{"level":"error","ts":1568036488.9318864,"msg":"no session found in
request, redirecting for authorization","error":"authentication session not
found"}
{"level":"info","ts":1568036488.933154,"msg":"client
request","latency":0.00135279,"status":307,"bytes":95,"client_ip":"
192.168.64.3:55284","method":"GET","path":"/protected/dashboard/"}
{"level":"info","ts":1568036488.9949393,"msg":"client
request","latency":0.00016756,"status":307,"bytes":296,"client_ip":"
192.168.64.3:55286","method":"GET","path":"/oauth/authorize"}
{"level":"info","ts":1568036496.060338,"msg":"issuing access token for
user","email":"nick at nickpowers.info
","expires":"2019-09-09T13:46:36Z","duration":"4m59.939664871s"}
{"level":"info","ts":1568036496.0613837,"msg":"client
request","latency":0.047718755,"status":307,"bytes":57,"client_ip":"
192.168.64.3:55288","method":"GET","path":"/oauth/callback"}
{"level":"info","ts":1568036496.7325685,"msg":"client
request","latency":0.597993206,"status":200,"bytes":159843,"client_ip":"
192.168.64.3:55292","method":"GET","path":"/protected/dashboard/"}
{"level":"info","ts":1568036496.933339,"msg":"client
request","latency":0.008060276,"status":200,"bytes":6341,"client_ip":"
192.168.64.3:55324
","method":"GET","path":"/protected/dashboard/styles/extras.1.3.1.min.css"}
{"level":"info","ts":1568036496.9355507,"msg":"client
request","latency":0.011554557,"status":200,"bytes":1208,"client_ip":"
192.168.64.3:55326
","method":"GET","path":"/protected/dashboard/images/shards-dashboards-logo.svg"}
{"level":"info","ts":1568036496.9998045,"msg":"client
request","latency":0.080612073,"status":200,"bytes":805628,"client_ip":"
192.168.64.3:55320
","method":"GET","path":"/protected/dashboard/styles/shards-dashboards.1.3.1.css"}
{"level":"info","ts":1568036497.2263498,"msg":"client
request","latency":0.006648847,"status":200,"bytes":3898,"client_ip":"
192.168.64.3:55332
","method":"GET","path":"/protected/dashboard/scripts/extras.1.3.1.min.js"}
{"level":"info","ts":1568036497.231792,"msg":"client
request","latency":0.01331805,"status":200,"bytes":6614,"client_ip":"
192.168.64.3:55334
","method":"GET","path":"/protected/dashboard/scripts/shards-dashboards.1.3.1.min.js"}
{"level":"info","ts":1568036497.2363207,"msg":"client
request","latency":0.006584008,"status":200,"bytes":8807,"client_ip":"
192.168.64.3:55340
","method":"GET","path":"/protected/dashboard/scripts/app/app-analytics-overview.1.3.1.js"}
{"level":"info","ts":1568036498.20545,"msg":"client
request","latency":0.00212513,"status":404,"bytes":281,"client_ip":"
192.168.64.3:55344","method":"GET","path":"/favicon.ico"}

{"level":"error","ts":1568036488.9318864,"msg":"no session found in
request, redirecting for authorization","error":"authentication session not
found"}
{"level":"info","ts":1568036488.933154,"msg":"client
request","latency":0.00135279,"status":307,"bytes":95,"client_ip":"
192.168.64.3:55284","method":"GET","path":"/protected/dashboard/"}
{"level":"info","ts":1568036488.9949393,"msg":"client
request","latency":0.00016756,"status":307,"bytes":296,"client_ip":"
192.168.64.3:55286","method":"GET","path":"/oauth/authorize"}
{"level":"info","ts":1568036496.060338,"msg":"issuing access token for
user","email":"nick at nickpowers.info
","expires":"2019-09-09T13:46:36Z","duration":"4m59.939664871s"}
{"level":"info","ts":1568036496.0613837,"msg":"client
request","latency":0.047718755,"status":307,"bytes":57,"client_ip":"
192.168.64.3:55288","method":"GET","path":"/oauth/callback"}
{"level":"info","ts":1568036496.7325685,"msg":"client
request","latency":0.597993206,"status":200,"bytes":159843,"client_ip":"
192.168.64.3:55292","method":"GET","path":"/protected/dashboard/"}
{"level":"info","ts":1568036496.933339,"msg":"client
request","latency":0.008060276,"status":200,"bytes":6341,"client_ip":"
192.168.64.3:55324
","method":"GET","path":"/protected/dashboard/styles/extras.1.3.1.min.css"}
{"level":"info","ts":1568036496.9355507,"msg":"client
request","latency":0.011554557,"status":200,"bytes":1208,"client_ip":"
192.168.64.3:55326
","method":"GET","path":"/protected/dashboard/images/shards-dashboards-logo.svg"}
{"level":"info","ts":1568036496.9998045,"msg":"client
request","latency":0.080612073,"status":200,"bytes":805628,"client_ip":"
192.168.64.3:55320
","method":"GET","path":"/protected/dashboard/styles/shards-dashboards.1.3.1.css"}
{"level":"info","ts":1568036497.2263498,"msg":"client
request","latency":0.006648847,"status":200,"bytes":3898,"client_ip":"
192.168.64.3:55332
","method":"GET","path":"/protected/dashboard/scripts/extras.1.3.1.min.js"}
{"level":"info","ts":1568036497.231792,"msg":"client
request","latency":0.01331805,"status":200,"bytes":6614,"client_ip":"
192.168.64.3:55334
","method":"GET","path":"/protected/dashboard/scripts/shards-dashboards.1.3.1.min.js"}
{"level":"info","ts":1568036497.2363207,"msg":"client
request","latency":0.006584008,"status":200,"bytes":8807,"client_ip":"
192.168.64.3:55340
","method":"GET","path":"/protected/dashboard/scripts/app/app-analytics-overview.1.3.1.js"}
{"level":"info","ts":1568036498.20545,"msg":"client
request","latency":0.00212513,"status":404,"bytes":281,"client_ip":"
192.168.64.3:55344","method":"GET","path":"/favicon.ico"}

Please let me know if you would like to see any other info on this.

Thank you so much! :)

Nick

On Mon, Sep 9, 2019 at 3:30 AM Bruno Oliveira <bruno at abstractj.org> wrote:

> Hi Nick,
>
> I've never seen this behavior before, in order to understand exactly
> what's going on would be nice to have a Jira in place describing the
> whole scenario, the steps to reproduce and also code snippets if
> possible.
>
> The more details you provide the better.
>
> On 2019-09-07, Nick Powers wrote:
> > I have Keycloak and Gatekeeper configured to use Google as an identity
> > provider to front end my PHP application and most of the time it works
> > great but sometimes it exposes my internal host (which Gatekeeper should
> be
> > proxying for).  If I login from my desktop(chrome) it works fine unless
> > instead of clicking on a link my app tries to use a redirect header.
> i.e.
> > my PHP example: header("Location: /protected/dashboard");  When that
> > happens instead of redirecting to
> > https://commentcontext.com/protected/dashboard, like it should, I see
> > https://webapp/protected/dashboard in the URL field.  This fails because
> > there is no DNS for webapp.  webapp is the name I use internally and it
> > should never be exposed externally.  Also, if I try to connect using my
> > phone or tablet (both android) I get through the Google authentication
> fine
> > but then it tries to send me to https://webapp/protected/dashboard,
> which
> > again is a FAIL :(
> >
> > Why is Gatekeeper failing to proxy sessions when initiated via a redirect
> > or when they come from mobile browser?  Has anyone seen this behavior
> > before?  Any help anyone could provide on this issue would be greatly
> > appreciated.
> >
> > Thanks,
> >
> > Nick
> > _______________________________________________
> > keycloak-user mailing list
> > keycloak-user at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/keycloak-user
>
> --
>
> abstractj
>


More information about the keycloak-user mailing list