Pete Lorenz
08/08/2023, 4:15 AMPete Lorenz
08/08/2023, 2:38 PMJan Kos
08/08/2023, 2:42 PMJan Kos
08/08/2023, 2:42 PMPete Lorenz
08/08/2023, 2:44 PMPete Lorenz
08/08/2023, 2:45 PMPete Lorenz
08/08/2023, 2:50 PM<https://auth.stg.cwan.cloud/authorize?response_type=code&client_id=kovCkjLNAnXMUrkP2cfy1Wbng81LO2Fp&scope=openid%20profile%20offline_access&state=DOTITBwTYHfGqdd9oFNis5BiN8GvTPaff3ni4cSoUQh0&redirect_uri=http://gooddata-cn-yzaxytzlzt.uswe2.stg1.aws.cwan.io/login/oauth2/code/gooddata-cn-yzaxytzlzt.uswe2.stg1.aws.cwan.io&nonce=nIuKZljeszLxpu6we_GKPyOF0psoUz6SJyYkVacYpOI&>
I'm assuming (perhaps wrongly) that this URL originates in GD.CN. The part that isn't working is the "http" after redirect_uri. If I change this to "https" I get a login prompt. Otherwise, I see this error message:
Callback URL mismatch.
The provided redirect_uri is not in the list of allowed callback URLs.
Please go to the Application Settings page and make sure you are sending a valid callback url from your application.
I think this means that the requested URL doesn't match because it's http but the URL registered with auth0 is https. Registered callback is:
<https://gooddata-cn-yzaxytzlzt.gooddata-cn.uswe2.stg1.aws.cwan.io/login/oauth2/code/gooddata-cn-yzaxytzlzt.gooddata-cn.uswe2.stg1.aws.cwan.io>
Pete Lorenz
08/08/2023, 2:52 PMPeter Plochan
08/08/2023, 3:57 PMauthService
). This URL is just passed by Ingress there. The flow is following:
• API client calls <baseUrl>/oauth2/authorization/<domain>
• API client is redirected to OIDC IdP with the redirect_uri
query parameter set to <baseUrl>/login/oauth2/code/<domain>
As I understand, in your case, the API client is the network load balancer which uses http
. The <baseUrl>
is always computed from the API (authorization) request and it cannot be re-configured as well.
I think that this will also apply to all other GD.CN APIs. If there’re any links (e.g. self/next used for paging) generated by any GD.CN microservice, they’ll contain the http
scheme as well.Pete Lorenz
08/08/2023, 4:01 PMPete Lorenz
08/08/2023, 4:07 PMJan Kos
08/08/2023, 4:38 PMforce-ssl-redirect: "true"
use-forwarded-headers: "true"
x-forwarded-* headers help to identify public url schema for redirect_uri generation.
Can you review the following thread https://gooddataconnect.slack.com/archives/C01P3H2HTDL/p1680736799811699
if it could apply to your infrastructure?Pete Lorenz
08/08/2023, 4:44 PMPete Lorenz
08/08/2023, 4:48 PMPete Lorenz
08/08/2023, 5:41 PMallow-snippet-annotations: "{{ .Values.controller.allowSnippetAnnotations }}"
http-snippet: |
server {
listen 2443;
return 308 https://$host$request_uri;
}
Pete Lorenz
08/08/2023, 5:44 PMPete Lorenz
08/08/2023, 5:52 PMPete Lorenz
08/08/2023, 11:10 PMuse-forwarded-headers: "true"
force-ssl-redirect: "true"
Observed: browser returns an ERR_TOO_MANY_REDIRECTS error.
Experiment 2: we set only the following annotation under "data:" in controller-configmap.yaml under ingress-nginx templates (which seems to be Robert's initial suggestion):
use-forwarded-headers: "true"
Observed: this does not solve the problem as the callback URL scheme is still "http" instead of "https". The oauth provider fails with a validation error saying that our callback URL (with http) does not match the allowed callback (with https).
We need guidance about how to configure the ingress-nginx controller for oauth with a load balancer that terminates TLS and forwards HTTP to the ingresses.Martin Štefany
08/09/2023, 9:03 AMkubectl get cm -n ingress-nginx ingress-nginx-controller -o yaml
so that I can see the actual ConfigMap in the cluster?
Any changes should be modified in values.yaml
and then installed to cluster using Helm. Modifications to Helm Chart (templates) are not recommended as your changes might be reverted during upgrades.
Output should look something like:
$ kubectl get cm -n ingress-nginx ingress-nginx-controller -o yaml
apiVersion: v1
data:
allow-snippet-annotations: "true"
brotli-min-length: "1024"
brotli-types: application/vnd.gooddata.api+json application/xml+rss application/atom+xml
application/javascript application/x-javascript application/json application/rss+xml
application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json
application/xhtml+xml application/xml font/opentype image/svg+xml image/x-icon
text/css text/javascript text/plain text/x-component
client-body-buffer-size: 1m
enable-brotli: "true"
force-ssl-redirect: "true"
gzip-min-length: "3072"
gzip-types: application/vnd.gooddata.api+json application/atom+xml application/javascript
application/x-javascript application/json application/rss+xml application/vnd.ms-fontobject
application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml
application/xml font/opentype image/svg+xml image/x-icon text/css text/plain text/x-component
large-client-header-buffers: 4 32k
proxy-buffer-size: 32k
use-forwarded-headers: "true"
use-gzip: "true"
kind: ConfigMap
metadata:
[...]
Pete Lorenz
08/09/2023, 2:32 PMPete Lorenz
08/09/2023, 2:33 PMPete Lorenz
08/09/2023, 2:44 PMPete Lorenz
08/09/2023, 2:45 PMPete Lorenz
08/09/2023, 2:52 PMuse-forwarded-headers: "true"
force-ssl-redirect: "true"
results in a permanent redirect loop (308 status)Pete Lorenz
08/09/2023, 2:54 PMMartin Štefany
08/09/2023, 4:17 PMkubectl get service -n ingress-nginx ingress-nginx-controller -o yaml
so that we can review annotations present? (<http://service.beta.kubernetes.io/aws-load-balancer-*|service.beta.kubernetes.io/aws-load-balancer-*>
).
Is the NLB+TLS setup from k8s by AWS Load Balancer Controller or somehow manually/programatically without k8s? I am asking because in the next step I would like you to try this:
• remove use-forwarded-headers: "true"
from the config/ConfigMap
• try annotation <http://service.beta.kubernetes.io/aws-load-balancer-backend-protocol|service.beta.kubernetes.io/aws-load-balancer-backend-protocol>: tcp
if now it’s http (default) or vice-versaPete Lorenz
08/09/2023, 4:25 PMPete Lorenz
08/09/2023, 4:27 PMMartin Štefany
08/09/2023, 4:30 PMingress-nginx-controller
service:
<http://service.beta.kubernetes.io/aws-load-balancer-proxy-protocol|service.beta.kubernetes.io/aws-load-balancer-proxy-protocol>: "*"
• remove use-forwarded-headers
from ConfigMap
• and set also use-proxy-protocol: "true"
in the ConfigMap?Pete Lorenz
08/09/2023, 4:31 PMMartin Štefany
08/09/2023, 4:32 PMPete Lorenz
08/09/2023, 4:32 PMPete Lorenz
08/09/2023, 4:32 PMPete Lorenz
08/09/2023, 4:35 PMPete Lorenz
08/09/2023, 4:36 PMPete Lorenz
08/09/2023, 4:39 PMPete Lorenz
08/09/2023, 4:42 PMPete Lorenz
08/09/2023, 4:45 PMRobert Moucha
08/14/2023, 1:58 PMingress.lbProtocol
from default https
to http
?Robert Moucha
08/14/2023, 1:59 PMPete Lorenz
08/14/2023, 1:59 PMlbProtocol
is httpsRobert Moucha
08/16/2023, 3:30 PMX-Forwarded-Host
, X-Forwarded-Port
, X-Forwarded-Proto
, X-Forwarded-Ssl
, and X-Forwarded-Prefix
headers. These headers are NOT set by NLB, because it runs on Layer 4 (TCP) and is not aware of any Layer 7 (HTTP) headers.
2. As these headers are NOT present in requests passed from NLB, the ingress controller sets these headers based on available information - e.g. X-Forwarded-Proto
is set based on $scheme
value.
3. Your configuration terminates SSL on NLB and the request is passed to ingress-ctl on port 80 as plain HTTP, so $scheme
is http
. Header is set using proxy_set_header X-Forwarded-Proto $pass_access_scheme
(initialized from $scheme
).
4. There's no straightforward way how to later modify proxy headers that were already set by ingress-ctl template. If I attempt to add the same request header with different value, two headers will be set and it is wrong. One option is to write custom LUA plugin that would set pass_access_scheme
variable to something else. But it is rather complex workaround.
To sum it up: it's virtually impossible to properly deliver required X-Forwarded-*
headers downstream. So I recommend updating your existing configuration of ingress controller with these changes. The other settings are OK and need not to be modified:
controller:
service:
annotations:
# => Replace the current value "http" with "ssl".
<http://service.beta.kubernetes.io/aws-load-balancer-backend-protocol|service.beta.kubernetes.io/aws-load-balancer-backend-protocol>: "ssl"
targetPorts:
http: http
https: https # Now you have "http"
You may consider adding annotation <http://service.beta.kubernetes.io/aws-load-balancer-target-group-attributes|service.beta.kubernetes.io/aws-load-balancer-target-group-attributes>: "deregistration_delay.connection_termination.enabled=true,preserve_client_ip.enabled=true"
but it is not necessary.Pete Lorenz
08/16/2023, 3:35 PMRobert Moucha
08/16/2023, 3:54 PMredirect_uri
is created automatically by Spring framework using "{baseUrl}/{action}/oauth2/code/{registrationId}"
URI template. I can't estimate how much effort it will take to reimplement part of Spring Security framework to make the scheme
(and possibly also host and port) configurable for this single use case.
@Peter Plochan Any guess? (not sure where exactly it is, probably in org.springframework.security.config.oauth2.client)Robert Moucha
08/16/2023, 3:55 PMPete Lorenz
08/16/2023, 5:07 PMPete Lorenz
08/16/2023, 8:25 PMPete Lorenz
08/16/2023, 9:39 PM2023/08/16 21:37:10 [error] 814#814: *902209 upstream sent too big header while reading response header from upstream, client: 10.162.150.221, server: <http://gooddata-cn-yzaxytzlzt.gooddata-cn.uswe2.stg1.aws.cwan.io|gooddata-cn-yzaxytzlzt.gooddata-cn.uswe2.stg1.aws.cwan.io>, request: "GET /login/oauth2/code/gooddata-cn-yzaxytzlzt.gooddata-cn.uswe2.stg1.aws.cwan.io?code=TrvKiDLBbxrYzLsyCYYIzFuOWpH3ZzCDex298ce90FVD7&state=7z0qqcW6HLOOKO0QVycvjv14qovVjdu-7CHYrj7HrZuk HTTP/1.1", upstream: "<http://10.162.96.97:9050/login/oauth2/code/gooddata-cn-yzaxytzlzt.gooddata-cn.uswe2.stg1.aws.cwan.io?code=TrvKiDLBbxrYzLsyCYYIzFuOWpH3ZzCDex298ce90FVD7&state=7z0qqcW6HLOOKO0QVycvjv14qovVjdu-7CHYrj7HrZuk>", host: "<http://gooddata-cn-yzaxytzlzt.gooddata-cn.uswe2.stg1.aws.cwan.io|gooddata-cn-yzaxytzlzt.gooddata-cn.uswe2.stg1.aws.cwan.io>", referrer: "<https://clearwateranalytics.okta.com/>"
Pete Lorenz
08/16/2023, 10:12 PM<http://nginx.ingress.kubernetes.io/proxy-buffer-size|nginx.ingress.kubernetes.io/proxy-buffer-size>: "1024k"
<http://nginx.ingress.kubernetes.io/proxy-buffers-number|nginx.ingress.kubernetes.io/proxy-buffers-number>: "8"
After adding these annotations and recreating our ingresses, we no longer get the "Bad Gateway" error and we can log in to our org workspace.Robert Moucha
08/17/2023, 8:04 AMproxy-buffer-size: 32k
- it should be enough for the most of situations. Proxy-buffers-number is not explicitly set so it defaults to 4.
It's possible your oauth2 tokens contain a lot of claims so as they are passed and encrypted to application cookies, the header size exceeds the given 32k limit.