Setting Up Traefik Proxy on k3s with Forward Auth using Authorization Header Part 1
Traefik is a popular open-source reverse proxy and load balancer that can be used as an ingress controller in Kubernetes. It has many advanced features, including support for multiple protocols, load balancing algorithms, and dynamic configuration. One of the most useful features of Traefik is its support for forward authentication, which allows you to delegate authentication to an external provider.
In this tutorial, we will set up Traefik on k3s and use it as an ingress controller to protect a web application with forward auth. We will use the Authorization
header to pass authentication information to Traefik, and we will implement a simple Node.js Express app to handle the callback from the authentication provider.
Prerequisites
To follow along with this tutorial, you will need:
- A Kubernetes cluster running k3s
- The kubectl command-line tool installed on your local machine
- A domain name pointing to your Kubernetes cluster
- A GitHub account and OAuth app
Step 1: Set up Traefik
The first step is to install and configure Traefik in our Kubernetes cluster. We will use the official Traefik Helm chart to install Traefik.
First, add the Traefik Helm repository:
helm repo add traefik https://helm.traefik.io/traefik
Then, create a values file with the following contents:
# values.yaml
additionalArguments:
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --providers.kubernetesingress
- --certificatesresolvers.myresolver.acme.email=<your-email>
- --certificatesresolvers.myresolver.acme.storage=/data/acme.json
- --certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
- --certificatesresolvers.myresolver.acme.tlschallenge=true
- --ping.entrypoint=web
- --log.level=DEBUG
In this values file, we have specified the following:
- We will use the Kubernetes Ingress provider to configure Traefik as an ingress controller
- We will use Let’s Encrypt to automatically obtain SSL/TLS certificates for our domains
- We will use HTTP challenge to obtain certificates
- We have specified that the
web
entrypoint is listening on ports 80 and 443 - We have specified the email address to use for Let’s Encrypt registration
- We have set the log level to
DEBUG
for troubleshooting purposes
Next, install Traefik using the following command:
helm install traefik traefik/traefik -f values.yaml
This will install Traefik in the default namespace with the name traefik
.
Step 2: Set up the OAuth App
The next step is to create a new OAuth app on GitHub, which we will use as our authentication provider. Here’s how:
- Go to your GitHub account settings and click on
Developer settings
. - Click on
OAuth Apps
and thenNew OAuth App
. - Fill in the required fields:
Application Name
: A name for your appHomepage URL
: The URL of your app (e.g.,https://myapp.example.com
)Authorization callback URL
: The URL where your app will handle the OAuth callback (e.g.,https://myapp.example.com/auth/github/callback
)
- Click
Register Application
to create the app.
Make a note of the Client ID
and Client Secret
values, as we will need them later.
Step 3: Create the Node.js Express App
We will now create a simple Node.js Express app that will handle the OAuth callback from GitHub. Here’s how:
- Create a new directory for your app:
mkdir myapp
cd myapp
- Initialize a new Node.js project and install the required dependencies:
npm init -y
npm install express dotenv
- Create a new file called
app.js
with the following contents:
const express = require('express')
const dotenv = require('dotenv')
const app = express()
// Load environment variables
dotenv.config()
// Handle OAuth callback
app.get('/auth/github/callback', (req, res) => {
const code = req.query.code
const state = req.query.state
// TODO: Exchange code for access token
// TODO: Verify access token and extract user information
// TODO: Set authentication cookie and redirect to original URL
})
// Start server
const port = process.env.PORT || 3000
app.listen(port, () => {
console.log(`Server listening on port ${port}`)
})
In this file, we have created a simple Express app that listens for GET requests on the /auth/github/callback
URL. We will use this URL to handle the OAuth callback from GitHub.
We have also loaded environment variables using the dotenv
package. You should create a .env
file in the root directory of your app and set the following environment variables:
CLIENT_ID=<your-github-client-id>
CLIENT_SECRET=<your-github-client-secret>
REDIRECT_URI=https://myapp.example.com/auth/github/callback
Replace the placeholders with your actual values. You can obtain the CLIENT_ID
and CLIENT_SECRET
values from the OAuth app you created earlier. The REDIRECT_URI
should be the same as the Authorization callback URL
you specified earlier.
Finally, we have started the server on port 3000 (or the value of the PORT
environment variable, if set).
To be continued… Part 2.