3 min read

Setting Up Traefik Proxy on k3s with Forward Auth using Authorization Header Part 1

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:

  1. Go to your GitHub account settings and click on Developer settings.
  2. Click on OAuth Apps and then New OAuth App.
  3. Fill in the required fields:
    • Application Name: A name for your app
    • Homepage 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)
  4. 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:

  1. Create a new directory for your app:
mkdir myapp
cd myapp
  1. Initialize a new Node.js project and install the required dependencies:
npm init -y
npm install express dotenv
  1. 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.