[keycloak-user] IP access control for /auth/admin/master/console/

Jan Nabbefeld jan at odise.de
Fri Sep 30 09:26:10 EDT 2016


Hi,

I’m currently struggling while setting up an IP based access control
filter to protect the path /auth/admin/master/console/. My Kc cluster
runs in AWS with EC2 instances managed in an autoscaling group (subnet
172.31.0.0/16). The relevant part of the standalone-ha.xml looks like
that:


<subsystem xmlns="urn:jboss:domain:undertow:3.0">
            <buffer-cache name="default"/>
            <server name="default-server">
                <ajp-listener name="ajp" socket-binding="ajp"/>
                <http-listener name="default" socket-binding="http"
redirect-socket="https" proxy-address-forwarding="true"/>
                <host name="default-host" alias="localhost">
                    <location name="/" handler="welcome-content"/>
                    <filter-ref name=“proxy-peer"/>
                    <filter-ref name="restrict-admin-console-access"/>
                    <access-log pattern="%h %l %u [%t] &quot;%r&quot;
%s %b &quot;%{i,Referer}&quot; &quot;%{i,User-Agent}&quot;"/>

                    <!—
                    <filter-ref name="request-dumper"/>
                    -->
                </host>
            </server>
            <servlet-container name="default">
                <jsp-config/>
                <websockets/>
            </servlet-container>
            <handlers>
                <file name="welcome-content"
path="${jboss.home.dir}/welcome-content"/>
            </handlers>
            <filters>
                <filter name="request-dumper"
class-name="io.undertow.server.handlers.RequestDumpingHandler"
module="io.undertow.core" />
                <request-limit name="limit-connections"
queue-size="100" max-concurrent-requests="1200"/>
                <filter name="proxy-peer" module="io.undertow.core"
class-name="io.undertow.server.handlers.ProxyPeerAddressHandler"/>
                <expression-filter  module="io.undertow.core"
name="restrict-admin-console-access"
                  expression=“path-prefix(/auth/admin/master/console/)
-> ip-access-control(default-allow=false, acl={‘127.0.0.1 allow’,
‘172.31.0.0/16 allow’, '62.96.159.233 allow'})"/>
            </filters>
        </subsystem>


With this configuration I can access the admin console only if I
connect to the instance itself bypassing the load-balancer. Requests
that hitting the endpoint via the load-balancer have all
X-Forwarding-* headers set. Here is an example for GET /auth/admin
which response 302 to /auth/admin/master/console/. Finally this
results in a 403 (the request isn’t logged by the
RequestDumpingHandler):

----------------------------REQUEST---------------------------
               URI=/auth/admin
 characterEncoding=null
     contentLength=-1
       contentType=null
            header=Accept=*/*
            header=Connection=keep-alive
            header=X-Forwarded-Proto=http
            header=X-Forwarded-Port=80
            header=X-Forwarded-For=62.96.159.233
            header=User-Agent=curl/7.43.0
            header=host=login.dev.scoober.com
            locale=[]
            method=GET
          protocol=HTTP/1.1
       queryString=
        remoteAddr=62.96.159.233:0
        remoteHost=62.96.159.233
            scheme=http
              host=login.dev.scoober.com
        serverPort=8080
--------------------------RESPONSE--------------------------
     contentLength=0
       contentType=null
            header=Connection=keep-alive
            header=Location=http://login.dev.scoober.com/auth/admin/master/console/
            header=Content-Length=0
            header=Date=Fri, 30 Sep 2016 13:07:16 GMT
            status=302

I assume that undertow is somehow blocking the X-Forwarded-* requests
and doesn’t accepts the remoteAddr as part of the ip-access-control
ACL (as this works with direct requests).

$ curl -LIv localhost:8080/auth/admin/master/console/
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> HEAD /auth/admin/master/console/ HTTP/1.1
> User-Agent: curl/7.40.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Cache-Control: no-cache
Cache-Control: no-cache
< X-Frame-Options: SAMEORIGIN
X-Frame-Options: SAMEORIGIN
< Content-Security-Policy: frame-src 'self'
Content-Security-Policy: frame-src 'self'
< Date: Fri, 30 Sep 2016 13:19:15 GMT
Date: Fri, 30 Sep 2016 13:19:15 GMT
< Connection: keep-alive
Connection: keep-alive
< X-Content-Type-Options: nosniff
X-Content-Type-Options: nosniff
< Content-Type: text/html;charset=utf-8
Content-Type: text/html;charset=utf-8
< Content-Length: 0
Content-Length: 0
< Content-Language: en
Content-Language: en

<
* Connection #0 to host localhost left intact

Setting the header:

$ curl -LIv -H “X-Forwarded-For: 172.31.19.199"
localhost:8080/auth/admin/master/console/
*   Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> HEAD /auth/admin/master/console/ HTTP/1.1
> User-Agent: curl/7.40.0
> Host: localhost:8080
> Accept: */*
> X-Forwarded-For: 172.31.19.199
>
< HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
< Connection: keep-alive
Connection: keep-alive
< Content-Length: 74
Content-Length: 74
< Content-Type: text/html
Content-Type: text/html
< Date: Fri, 30 Sep 2016 13:19:10 GMT
Date: Fri, 30 Sep 2016 13:19:10 GMT

<
* Connection #0 to host localhost left intact

Any idea to solve this? Is there any other/better way to prevent the
master realm console being publicly available?

Thanks in advance,
Jan



More information about the keycloak-user mailing list