DEV Community

Livio Ribeiro
Livio Ribeiro

Posted on

6 1

Openshift behind a proxy with SSL termination

The Openshift Container Platform is a great tool to deploy your applications and services in a container environment: It hides the complexity of Kubernetes and offers many facilities to manage builds, configurations, volumes and environment variables.

Everything was fine until I had this weird problem where I could not get Keycloak to work properly. I was unable to authenticate because the service kept telling me that it required HTTPS... and I had HTTPS!

In order to track down the problem, I wrote a small service (in Rust :) that just returned the HTTP headers it received and the result was like this:

[other headers]
X-Forwarded-Port: 80
X-Forwarded-Proto: http
[some more headers]
Enter fullscreen mode Exit fullscreen mode

That was strange! The proxy was sending the right X-Forwarded-* headers, but somewhere they were being overwriden!

I searched this behavior and found this anwswer (needs a redhat account to visualize) about changing the openshift router configuration. My solution was a bit different but worked the same.

We need to create a custom router configuration according to the documentation. First let's get a copy of the default configuration:

oc -n default rsh dc/router cat haproxy-config.template > haproxy-config.template
Enter fullscreen mode Exit fullscreen mode

Now open the haproxy-config.template file and search for the following text:

http-request set-header X-Forwarded-Port %[dst_port]
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Proto-Version h2 if { ssl_fc_alpn -i h2 }
Enter fullscreen mode Exit fullscreen mode

These lines above override the X-Forwarded-* headers sent by the proxy. My solution was to add a conditional to only set the headers if they are not present:

http-request set-header X-Forwarded-Port %[dst_port]  if { req.hdr_cnt(X-Forwarded-Port) eq 0 }
http-request set-header X-Forwarded-Proto http        if { req.hdr_cnt(X-Forwarded-Proto) eq 0 } !{ ssl_fc }
http-request set-header X-Forwarded-Proto https       if { req.hdr_cnt(X-Forwarded-Proto) eq 0 } { ssl_fc }
http-request set-header X-Forwarded-Proto-Version h2  if { req.hdr_cnt(X-Forwarded-Proto-Version) eq 0 } { ssl_fc_alpn -i h2 }
Enter fullscreen mode Exit fullscreen mode

With the file changed, now we can add it to the router:

# create a configmap to hold the file
oc -n default create configmap customrouter --from-file=haproxy-config.template
# add the configmap as a volume
oc -n default set volume dc/router --add --overwrite \
    --name=config-volume \
    --mount-path=/var/lib/haproxy/conf/custom \
    --source='{"configMap": { "name": "customrouter"}}'
# set an environment variable to tell the router were to find the configuration
oc -n default set env dc/router \
    TEMPLATE_FILE=/var/lib/haproxy/conf/custom/haproxy-config.template
Enter fullscreen mode Exit fullscreen mode

After that, Openshift will redeploy the router and the configuration will take effect.

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more

Top comments (1)

Collapse
 
dcioccarelli profile image
dcioccarelli

Easier just to set the PROXY_ADDRESS_FORWARDING environment variable to true.

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more