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.

Image of Timescale

🚀 pgai Vectorizer: SQLAlchemy and LiteLLM Make Vector Search Simple

We built pgai Vectorizer to simplify embedding management for AI applications—without needing a separate database or complex infrastructure. Since launch, developers have created over 3,000 vectorizers on Timescale Cloud, with many more self-hosted.

Read 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