Skip to content

Commit

Permalink
Add TLS Cipher header
Browse files Browse the repository at this point in the history
  • Loading branch information
jadolg committed Jul 22, 2024
1 parent b81b791 commit 978507a
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 126 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
name: Main Process
runs-on: ubuntu-latest
env:
GO_VERSION: 1.19
GO_VERSION: 1.22
GOLANGCI_LINT_VERSION: v1.50.0
YAEGI_VERSION: v0.14.2
CGO_ENABLED: 0
Expand All @@ -24,20 +24,20 @@ jobs:

# https://github.com/marketplace/actions/setup-go-environment
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v2
uses: actions/setup-go@v5
with:
go-version: ${{ env.GO_VERSION }}

# https://github.com/marketplace/actions/checkout
- name: Check out code
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
path: go/src/github.com/${{ github.repository }}
fetch-depth: 0

# https://github.com/marketplace/actions/cache
- name: Cache Go modules
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
Expand Down
9 changes: 4 additions & 5 deletions .traefik.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
displayName: Demo Plugin
displayName: TLS headers
type: middleware
iconPath: .assets/icon.png

import: github.com/traefik/plugindemo
import: github.com/RiskIdent/traefik-tls-headers-plugin

summary: '[Demo] Add Request Header'
summary: 'Add TLS information to request headers'

testData:
Headers:
X-Demo: test
X-URL: '{{URL}}'
X-TLS-Cipher: TLS_AES_128_GCM_SHA256
66 changes: 0 additions & 66 deletions demo.go

This file was deleted.

49 changes: 0 additions & 49 deletions demo_test.go

This file was deleted.

4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module github.com/traefik/plugindemo
module github.com/RiskIdent/traefik-tls-headers-plugin

go 1.19
go 1.22.5
Empty file added go.sum
Empty file.
57 changes: 57 additions & 0 deletions plugin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Package plugin contains the Traefik plugin for adding headers based on the
// TLS information
package plugin

import (
"context"
"crypto/tls"
"errors"
"net/http"
)

var errMissingHeaderConfig = errors.New("missing header config: must set headers.cipher")

// Config the plugin configuration.
type Config struct {
Headers ConfigHeaders `json:"headers,omitempty"`
}

// ConfigHeaders defines the headers to use for the different values.
type ConfigHeaders struct {
Cipher string `json:"port,omitempty"`
}

// CreateConfig creates the default plugin configuration.
func CreateConfig() *Config {
return &Config{
Headers: ConfigHeaders{},
}
}

// TLSHeadersPlugin is the main handler model for this Traefik plugin.
type TLSHeadersPlugin struct {
next http.Handler
headers ConfigHeaders
name string
}

// New created a new TLSHeadersPlugin.
func New(_ context.Context, next http.Handler, config *Config, name string) (http.Handler, error) {
if config.Headers == (ConfigHeaders{}) {
return nil, errMissingHeaderConfig
}

return &TLSHeadersPlugin{
headers: config.Headers,
next: next,
name: name,
}, nil
}

func (a *TLSHeadersPlugin) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if a.headers.Cipher != "" && req.TLS != nil {
req.Header.Set(a.headers.Cipher, tls.CipherSuiteName(req.TLS.CipherSuite))
}

a.next.ServeHTTP(rw, req)
}
60 changes: 60 additions & 0 deletions plugin_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package plugin_test

import (
"context"
"io"
"net/http"
"net/http/httptest"
"testing"

plugin "github.com/RiskIdent/traefik-tls-headers-plugin"
)

func TestInvalidConfig(t *testing.T) {
cfg := plugin.CreateConfig()
next := http.HandlerFunc(func(http.ResponseWriter, *http.Request) {})
_, err := plugin.New(context.Background(), next, cfg, "traefik-tls-headers-plugin")
if err == nil {
t.Fatal("expected error")
}
}

func TestTLSCipher(t *testing.T) {
cfg := plugin.CreateConfig()
cfg.Headers.Cipher = "X-TLS-Cipher"
next := http.HandlerFunc(func(_ http.ResponseWriter, r *http.Request) {
assertHeader(t, r.Header, "X-TLS-Cipher", "TLS_AES_128_GCM_SHA256")
})
handler, err := plugin.New(context.Background(), next, cfg, "traefik-tls-headers-plugin")
if err != nil {
t.Fatal(err)
}

server := httptest.NewTLSServer(handler)
defer server.Close()

req, err := http.NewRequest(http.MethodGet, server.URL, nil)
if err != nil {
t.Fatal(err)
}

client := server.Client()
resp, err := client.Do(req)
if err != nil {
t.Fatal(err)
}
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
t.Fatal(err)
}
}(resp.Body)
}

func assertHeader(t *testing.T, header http.Header, key, expected string) {
t.Helper()

if header.Get(key) != expected {
t.Errorf("invalid header value\nwant: %s=%q\ngot: %s=%q", key, expected, key, header.Get(key))
}
}

0 comments on commit 978507a

Please sign in to comment.