Oh, so you want to work at Traefik?
A pretty unusual way to apply for a developer job at Traefik...
04/12/2024 · 4 min read · sapling 🪴
Introduction
When looking for an alternative to HAProxy or Nginx, I came across Traefik, a modern HTTP reverse proxy and load balancer made to deploy microservices with ease, even featuring Kubernetes Ingress support, or Let’s Encrypt integration.
By digging a little more on their website, I found a developer job application form. I was surprised to see that there was no traditional CV to send, but a docker command to run.
The challenge
Spun up the image as requested, I was greeted with a nice error message:
I immediately thought of Helm, the package manager for Kubernetes, so I went ahead and started a minikube
cluster.
Note: I used the v1.19
version of Kubernetes because it was the latest available at the time of the last update of the Docker image. (see the version list)
And then started a pod with the image.
Still getting an error message, but this time it was different:
I was now sure that I was on the right track.
The image was kindly asking us to give it more permissions, so I naturally gave it the cluster-admin
role. (I know, I know, it’s not a good practice, but it’s just for a CTF, right?)
Applying the created manifest.
We now have a service account with the cluster-admin
role, so let’s set it to the pod.
We have a pod running with the cluster-admin
role, so we should be able to take a look at the logs.
Setting up an ingress on port 8888
should do the trick.
And restarting the pod.
The logs now say:
It should now be as simple as port-forwarding the ingress to our local machine.
And then, we can access the pod on localhost:8888
.
I see what you did there, Traefik .
As Traefik provides an ingress controller for Kubernetes, I think it’s safe to assume that they want us to use it.
Well, well, well… Let’s create a Traefik Proxy. I followed the quick-start guide from the documentation.
Various resources are created:
The Traefik deployment itself:
And finally, the service:
Applying the manifests.
We now have a Traefik proxy running on our cluster, and as Traefik relies on ingress resources, our pod should be directly accessible via the proxy.
The HTTP Service for our pod is effectively listed in the dashboard:
Forwarding the proxy port to something fancy:
Visiting localhost:1337
:
The message is a bit cryptic, but it seems that we have to find something in the image.
Running docker inspect
on the image, we get a ton of information:
And look at that, there is a helmsman
label with a value.
This looked juicy, so I first tried to decode the value as hex, but the output was… weird.
Base64 wasn’t any better.
Sorry, I don’t speak Minecraft enchantment table…
I then remembered the end of the message:
But remember, it’s a secret
It is just a secret, so there is no need to decode it, we just have to set it as some kind of header or maybe an environment variable. Setting various headers on the HTTP requests didn’t do anything, so I looked up on the Internet how to set env. variables on containers. After a few minutes, I was feeling that I was going nowhere, so I continued looking for other ways to provide the secret to the pod.
And guess what, the answer was simply to literally set the secret as… a secret.
This can be done with the kubectl create secret
command.
Restarting the pod, port-forwarding the proxy, and visiting localhost:1337
again, we now get a nice form to fill and submit.
Conclusion
This was a fun challenge, and I learned a lot about Kubernetes and Traefik in the process. I hope you enjoyed reading this article as much as I enjoyed solving this CTF
In the end, I learned how to use Traefik, which proved to be an amazing alternative to Apache or Nginx. It’s really easy to set up, and the fact that it can automatically discover services and create routes for them is really cool. I am definitely going to use this in future projects.
All the manifests used in this article are available on GitHub.
Disclaimer
If you are using this article to solve the challenge, please make sure to not just copy-paste the commands, but to understand what they do. My goal was to allow you to learn something new, not to give you the solution on a silver platter