Reza
June 13, 2020, 10:02pm
1
The idea is to use Istio (v1.6.1) authenticate a service (httpbin here) with an external IDP (Dex) via an OAuth proxy. For the sake of completeness I will put all the code here.
The filter seem to be intercepting on port 80 but the patch to ext.authz doesn’t seem to do anything. It just times out even though the service on the uri is up and accessible. The outbound cluster is also accessible and listed in the istio proxy of the httpbin pod.
Filter:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: authn-filter
namespace: istio-system
spec:
workloadSelector:
labels:
app: httpbin
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
portNumber: 80
filterChain:
filter:
name: "envoy.http_connection_manager"
subFilter:
name: "envoy.router"
patch:
operation: INSERT_BEFORE
value:
name: envoy.ext_authz
typed_config:
"@type": type.googleapis.com/envoy.config.filter.http.ext_authz.v2.ExtAuthz
http_service:
server_uri:
uri: http://oauthproxy-service.default.svc.cluster.local
cluster: outbound|4180||oauthproxy-service.default.svc.cluster.local:4180
timeout: 3s
Other pieces:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: httpbin-gateway
namespace: foo
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
namespace: foo
spec:
hosts:
- "*"
gateways:
- httpbin-gateway
http:
- route:
- destination:
port:
number: 8000
host: httpbin.foo.svc.cluster.local
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: httpbin
namespace: foo
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
namespace: foo
spec:
ports:
- name: http
port: 8000
targetPort: 80
selector:
app: httpbin
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
serviceAccountName: httpbin
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
ports:
- containerPort: 80
--
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: oauth2-proxy
name: oauth2-proxy
namespace: default
spec:
replicas: 1
selector:
matchLabels:
k8s-app: oauth2-proxy
template:
metadata:
labels:
k8s-app: oauth2-proxy
spec:
containers:
- args:
- --cookie-secure=false
- --upstream=file://dev/null
- --http-address=0.0.0.0:4180
- --cookie-secret=changeme
- --client-id=changeme
- --client-secret=changeme
- --email-domain="*"
- --provider=oidc
- --provider-display-name="Dex oidc"
- --redirect-url=http://10.106.200.144:4180/oauth2/callback
#following should match what is configured in dex
- --oidc-issuer-url=http://192.168.64.1:5556/dex
image: quay.io/pusher/oauth2_proxy:v5.1.1
imagePullPolicy: Always
name: oauth2-proxy
ports:
- containerPort: 4180
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: oauth2-proxy
name: oauthproxy-service
namespace: default
spec:
ports:
- name: http
port: 4180
protocol: TCP
targetPort: 4180
selector:
k8s-app: oauth2-proxy
I can see in the forum few similar questions most of them with no final outcome. I am suspecting the viability of this solution using filters altogether.
Reza
June 16, 2020, 2:18am
2
this is the filter that eventually worked for me
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: authn-filter
#namespace: istio-system
namespace: foo
spec:
workloadSelector:
labels:
app: httpbin
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
portNumber: 80
filterChain:
filter:
name: "envoy.http_connection_manager"
subFilter:
name: "envoy.router"
patch:
operation: INSERT_BEFORE
value:
#name: envoy.filters.http.ext_authz
name: envoy.ext_authz
typed_config:
"@type": type.googleapis.com/envoy.config.filter.http.ext_authz.v2.ExtAuthz
http_service:
server_uri:
uri: http://oauthproxy-service.default.svc.cluster.local:4180
cluster: outbound|4180||oauthproxy-service.default.svc.cluster.local
timeout: 3s
authorizationRequest:
allowedHeaders:
patterns:
- exact: "cookie"
1 Like
I’m having some issues with getting this setup.
What I am trying to get done is use Istio + Dex + oauth2-proxy. Is this the latest configuration working for you?
Currently this is what I have configured.
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: authn-filter
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway
configPatches:
- applyTo: HTTP_FILTER
match:
context: GATEWAY
listener:
filterChain:
filter:
name: 'envoy.http_connection_manager'
subFilter:
name: 'envoy.router'
patch:
operation: INSERT_BEFORE
values:
name: 'envoy.filters.http.ext_authz'
config:
http_service:
server_uri:
uri: http://oauth2-proxy.network.svc.cluster.local
cluster: outbound|80||oauth2-proxy.network.svc.cluster.local
timeout: 10s
authorization_request:
allowed_headers:
patterns:
- exact: 'cookie'
Reza
August 21, 2020, 11:58am
5
I don’t know what issues you’re facing but one header is not enough.
This worked for me before: https://github.com/rezagh/istio-auth
Thanks @Reza I applied your EnvoyFilter with the only adjustment being I changes the label and namespace to be the following:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: authn-filter
namespace: istio-system
spec:
workloadSelector:
labels:
app: kiali
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
#context: GATEWAY
listener:
portNumber: 80
filterChain:
filter:
name: 'envoy.http_connection_manager'
subFilter:
name: 'envoy.router'
patch:
operation: INSERT_BEFORE
value:
#name: envoy.filters.http.ext_authz
name: envoy.ext_authz
typed_config:
'@type': type.googleapis.com/envoy.config.filter.http.ext_authz.v2.ExtAuthz
http_service:
server_uri:
uri: http://oauthproxy-service.default.svc.cluster.local:4180
cluster: outbound|4180||oauthproxy-service.default.svc.cluster.local
timeout: 3s
authorizationRequest:
allowedHeaders:
patterns:
- exact: 'cookie'
- exact: 'x-forwarded-access-token'
- exact: 'x-forwarded-user'
- exact: 'x-forwarded-email'
- exact: 'authorization'
- exact: 'x-forwarded-proto'
- exact: 'proxy-authorization'
- exact: 'user-agent'
- exact: 'x-forwarded-host'
- exact: 'from'
- exact: 'x-forwarded-for'
- exact: 'accept'
- prefix: 'x-forwarded'
- prefix: 'x-auth-request'
- prefix: _oauth2_proxy
- exact: cookie
authorizationResponse:
allowed_upstream_headers:
patterns:
- exact: authorization
- exact: Cookie
- exact: cookie
- prefix: x-forwarded
- prefix: x-auth-request
- prefix: _oauth2_proxy
allowedClientHeaders:
patterns:
- exact: 'location'
- exact: 'proxy-authenticate'
- exact: 'set-cookie'
- exact: 'authorization'
- exact: 'www-authenticate'
- prefix: 'x-forwarded'
- prefix: 'x-auth-request'
allowedUpstreamHeaders:
patterns:
- exact: 'location'
- exact: 'proxy-authenticate'
- exact: 'set-cookie'
- exact: 'authorization'
- exact: 'www-authenticate'
- prefix: 'x-forwarded'
- prefix: 'x-auth-request'
When I attempt to reach kiali.example.com I’m sent directly to the service, I would have expected to be routed to my oauth proxy?
Reza
August 22, 2020, 3:34am
7
so the filter is not picking it up? please double check port /label.
you can also look at the logs of the proxy in debug mode.
otherwise need to see your whole config of the service etc.
Kiali service:
apiVersion: v1
kind: Service
metadata:
name: kiali
namespace: istio-system
labels:
app: kiali
install.operator.istio.io/owning-resource: istio
install.operator.istio.io/owning-resource-namespace: istio-system
operator.istio.io/component: AddonComponents
release: istio
spec:
clusterIP: 10.105.139.248
ports:
- name: http-kiali
port: 20001
protocol: TCP
targetPort: 20001
selector:
app: kiali
sessionAffinity: None
type: ClusterIP
EnvoyFilter
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: authn-filter
namespace: istio-system
spec:
workloadSelector:
labels:
app: kiali
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
#context: GATEWAY
listener:
portNumber: 20001
filterChain:
filter:
name: 'envoy.http_connection_manager'
subFilter:
name: 'envoy.router'
patch:
operation: INSERT_BEFORE
value:
#name: envoy.filters.http.ext_authz
name: envoy.ext_authz
typed_config:
'@type': type.googleapis.com/envoy.config.filter.http.ext_authz.v2.ExtAuthz
http_service:
server_uri:
uri: http://oauth2-proxy.network.svc.cluster.local:80
cluster: outbound|80||oauth2-proxy.network.svc.cluster.local
timeout: 10s
authorizationRequest:
allowedHeaders:
patterns:
- exact: 'cookie'
- exact: 'x-forwarded-access-token'
- exact: 'x-forwarded-user'
- exact: 'x-forwarded-email'
- exact: 'authorization'
- exact: 'x-forwarded-proto'
- exact: 'proxy-authorization'
- exact: 'user-agent'
- exact: 'x-forwarded-host'
- exact: 'from'
- exact: 'x-forwarded-for'
- exact: 'accept'
- prefix: 'x-forwarded'
- prefix: 'x-auth-request'
- prefix: _oauth2_proxy
- exact: cookie
authorizationResponse:
allowed_upstream_headers:
patterns:
- exact: authorization
- exact: Cookie
- exact: cookie
- prefix: x-forwarded
- prefix: x-auth-request
- prefix: _oauth2_proxy
allowedClientHeaders:
patterns:
- exact: 'location'
- exact: 'proxy-authenticate'
- exact: 'set-cookie'
- exact: 'authorization'
- exact: 'www-authenticate'
- prefix: 'x-forwarded'
- prefix: 'x-auth-request'
allowedUpstreamHeaders:
patterns:
- exact: 'location'
- exact: 'proxy-authenticate'
- exact: 'set-cookie'
- exact: 'authorization'
- exact: 'www-authenticate'
- prefix: 'x-forwarded'
- prefix: 'x-auth-request'
❯ istioctl experimental authz check kiali-6fcb9f7c-t2p82
Checked 10/26 listeners with node IP 172.16.36.201.
LISTENER[FilterChain] CERTIFICATE mTLS (MODE) AuthZ (RULES)
0.0.0.0_80[0] none no (none) no (none)
0.0.0.0_80[1] none no (none) no (none)
0.0.0.0_3030[0] none no (none) no (none)
0.0.0.0_3030[1] none no (none) no (none)
0.0.0.0_8383[0] none no (none) no (none)
0.0.0.0_8383[1] none no (none) no (none)
0.0.0.0_9411[0] none no (none) no (none)
0.0.0.0_9411[1] none no (none) no (none)
0.0.0.0_14250[0] none no (none) no (none)
0.0.0.0_14250[1] none no (none) no (none)
virtualOutbound none no (none) no (none)
virtualInbound[0] noneSDS: default yes (none) no (none)
virtualInbound[1] none no (none) no (none)
virtualInbound[2] noneSDS: default yes (none) no (none)
virtualInbound[3] none no (none) no (none)
virtualInbound[4] none no (none) no (none)
virtualInbound[5] none no (none) no (none)
virtualInbound[6] noneSDS: default yes (PERMISSIVE) no (none)
virtualInbound[7] none no (PERMISSIVE) no (none)
0.0.0.0_15010[0] none no (none) no (none)
0.0.0.0_15010[1] none no (none) no (none)
0.0.0.0_15014[0] none no (none) no (none)
0.0.0.0_15014[1] none no (none) no (none)
0.0.0.0_20001[0] none no (none) no (none)
0.0.0.0_20001[1] none no (none) no (none)
After some further tweaking I’ve got it semi-working, just need to iron out the network flow between DEX and oauth2-proxy and I should be good!
1 Like
jnitin
August 2, 2021, 10:00am
11
Thanks for sharing the example . I am also working on a similar feature but instead of applying the authz filter at sidecar i wanted to apply at gateway level. Is there any way by which i can route only specific requests to oauth proxy based on the path only instead of applying to all the requests .
In the example shared , as per understanding all incoming requests will routed to the oauth proxy ?
e.g. if we have two requests say /foo and /bar only requests /foo shall be redirected to oauth proxy .
this is now supported by using the CUSTOM action in authz policy, check the blog Istio / Better External Authorization for more details, you can put /foo in the authz policy for this purpose.
Can the path be added to a envoy filter