Add Traefik2 suite and refactor Traefik suite (#562)

* Update Traefik 1.x to v1.7.20 for integration tests

* Add suite for Traefik 2.x

* Refactor Traefik2 suite to utilise Docker labels

* Move Traefik2 middleware definition to a file based provider

* Expose Traefik2 dashboard
The API/Dashboard can be reached at https://traefik.example.com:8080/

* Move Traefik frontend/backend definitions to Docker labels

* Move Traefik2 router/service definitions to Docker labels

* Normalise all Traefik configuration via labels and commands
When the the middleware issue with Traefik 2.x (#476) is resolved this means all Traefik related configuration can be self-contained within the respective docker-compose.yml files.

* Define ports for Authelia frontend/backend services

* Adjust Traefik2 suite to new dev workflow

* Normalise all Traefik2 middlewares via labels

* Fix typo in middleware and comment labels specifying Traefik version
This commit is contained in:
Amir Zarrinkafsh 2020-01-19 21:06:37 +11:00 committed by Clément Michaud
parent 6054addfcc
commit a02fb1438e
35 changed files with 308 additions and 138 deletions

View File

@ -4,4 +4,4 @@ networks:
driver: bridge
ipam:
config:
- subnet: 192.168.240.0/24
- subnet: 192.168.240.0/24

View File

@ -14,4 +14,6 @@ RUN mkdir -p /var/lib/authelia && chown dev:dev /var/lib/authelia
USER dev
VOLUME /etc/authelia
VOLUME /var/lib/authelia
VOLUME /var/lib/authelia
EXPOSE 9091

View File

@ -6,4 +6,7 @@ ARG GROUP_ID
RUN deluser node && \
addgroup --gid ${GROUP_ID} dev && \
adduser --uid ${USER_ID} -G dev -D dev
USER dev
USER dev
EXPOSE 3000

View File

@ -1,4 +1,4 @@
version: "3"
version: '3'
services:
authelia-backend:
build:
@ -10,9 +10,14 @@ services:
command: /resources/entrypoint-backend.sh
working_dir: /app
volumes:
- "./example/compose/authelia/resources/:/resources"
- ".:/app"
- "${GOPATH}:/go"
- './example/compose/authelia/resources/:/resources'
- '.:/app'
- '${GOPATH}:/go'
labels:
- 'traefik.frontend.rule=Host:login.example.com;PathPrefix:/api'
- 'traefik.http.routers.authelia_backend.rule=Host(`login.example.com`) && PathPrefix(`/api`)'
- 'traefik.http.routers.authelia_backend.entrypoints=https'
- 'traefik.http.routers.authelia_backend.tls=true'
environment:
- ENVIRONMENT=dev
networks:

View File

@ -1,7 +1,12 @@
version: "3"
version: '3'
services:
authelia-backend:
image: authelia:dist
labels:
- 'traefik.frontend.rule=Host:login.example.com'
- 'traefik.http.routers.authelia.rule=Host(`login.example.com`)'
- 'traefik.http.routers.authelia.entrypoints=https'
- 'traefik.http.routers.authelia.tls=true'
environment:
- ENVIRONMENT=dev
restart: always

View File

@ -1,4 +1,4 @@
version: "3"
version: '3'
services:
authelia-frontend:
build:
@ -7,10 +7,15 @@ services:
args:
USER_ID: ${USER_ID}
GROUP_ID: ${GROUP_ID}
command: /resources/entrypoint-frontend.sh
command: '/resources/entrypoint-frontend.sh'
working_dir: /app
volumes:
- "./example/compose/authelia/resources/:/resources"
- "./web:/app"
- './example/compose/authelia/resources/:/resources'
- './web:/app'
labels:
- 'traefik.frontend.rule=Host:login.example.com'
- 'traefik.http.routers.authelia_frontend.rule=Host(`login.example.com`)'
- 'traefik.http.routers.authelia_frontend.entrypoints=https'
- 'traefik.http.routers.authelia_frontend.tls=true'
networks:
- authelianet

View File

@ -1,8 +1,8 @@
version: "3"
version: '3'
services:
authelia-frontend:
image: nginx:alpine
volumes:
- "./example/compose/authelia/resources/nginx.conf:/etc/nginx/nginx.conf"
- './example/compose/authelia/resources/nginx.conf:/etc/nginx/nginx.conf'
networks:
- authelianet

View File

@ -1,7 +1,7 @@
version: "3"
version: '3'
services:
duo-api:
build:
context: ./example/compose/duo-api
networks:
- authelianet
- authelianet

View File

@ -4,11 +4,11 @@ services:
build:
context: ./example/compose/kind
volumes:
- kind-volume:/kind/config
- /var/run/docker.sock:/var/run/docker.sock
- ./example/kube:/authelia
- ./example/compose/kind/config.yml:/etc/kind/config.yml
command: kubectl port-forward --address 0.0.0.0 -n authelia service/nginx-ingress-controller-service 8080:443
- 'kind-volume:/kind/config'
- '/var/run/docker.sock:/var/run/docker.sock'
- './example/kube:/authelia'
- './example/compose/kind/config.yml:/etc/kind/config.yml'
command: 'kubectl port-forward --address 0.0.0.0 -n authelia service/nginx-ingress-controller-service 8080:443'
networks:
authelianet:
aliases:
@ -25,9 +25,9 @@ services:
build:
context: ./example/compose/kind
volumes:
- kind-volume:/kind/config
- ./example/compose/kind/entrypoint-dashboard.sh:/entrypoint-dashboard.sh
command: "/entrypoint-dashboard.sh"
- 'kind-volume:/kind/config'
- './example/compose/kind/entrypoint-dashboard.sh:/entrypoint-dashboard.sh'
command: '/entrypoint-dashboard.sh'
networks:
authelianet:
aliases:

View File

@ -1,4 +1,4 @@
version: "3"
version: '3'
services:
openldap:
image: osixia/openldap:1.3.0
@ -13,8 +13,8 @@ services:
- LDAP_FORCE_RECONFIGURE=true
- LDAP_TLS_VERIFY_CLIENT=try
volumes:
- ./example/compose/ldap/ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom
- './example/compose/ldap/ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom'
command:
- --copy-service
- '--copy-service'
networks:
- authelianet
- authelianet

View File

@ -1,4 +1,4 @@
version: "3"
version: '3'
services:
mariadb:
image: mariadb:10.4.10

View File

@ -7,6 +7,6 @@ services:
- MONGO_INITDB_ROOT_USERNAME=authelia
- MONGO_INITDB_ROOT_PASSWORD=authelia
ports:
- "27017:27017"
- '27017:27017'
networks:
- authelianet
- authelianet

View File

@ -1,11 +1,17 @@
version: "3"
version: '3'
services:
nginx-backend:
build:
context: example/compose/nginx/backend
labels:
- traefik.frontend.rule=Host:home.example.com,public.example.com,secure.example.com,admin.example.com,singlefactor.example.com
- traefik.frontend.auth.forward.address=http://authelia-backend:9091/api/verify?rd=https://login.example.com:8080/
- traefik.frontend.auth.forward.tls.insecureSkipVerify=true
- 'traefik.frontend.rule=Host:home.example.com,public.example.com,secure.example.com,admin.example.com,singlefactor.example.com' # Traefik 1.x
- 'traefik.frontend.auth.forward.address=http://authelia-backend:9091/api/verify?rd=https://login.example.com:8080/' # Traefik 1.x
- 'traefik.frontend.auth.forward.tls.insecureSkipVerify=true' # Traefik 1.x
- 'traefik.http.routers.protectedapps.rule=Host(`home.example.com`, `public.example.com`, `secure.example.com`, `admin.example.com`, `singlefactor.example.com`)' # Traefik 2.x
- 'traefik.http.routers.protectedapps.entrypoints=https' # Traefik 2.x
- 'traefik.http.routers.protectedapps.tls=true' # Traefik 2.x
- 'traefik.http.routers.protectedapps.middlewares=authelia' # Traefik 2.x
- 'traefik.http.middlewares.authelia.forwardAuth.address=http://authelia-backend:9091/api/verify?rd=https://login.example.com:8080/' # Traefik 2.x
- 'traefik.http.middlewares.authelia.forwardAuth.tls.insecureSkipVerify=true' # Traefik 2.x
networks:
- authelianet
- authelianet

View File

@ -3,9 +3,13 @@ services:
smtp:
image: schickling/mailcatcher
ports:
- "1025:1025"
- '1025:1025'
labels:
- traefik.frontend.rule=Host:mail.example.com
- traefik.port=1080
- 'traefik.frontend.rule=Host:mail.example.com'
- 'traefik.port=1080'
- 'traefik.http.routers.mail.rule=Host(`mail.example.com`)'
- 'traefik.http.routers.mail.entrypoints=https'
- 'traefik.http.routers.mail.tls=true'
- 'traefik.http.services.mail.loadbalancer.server.port=1080'
networks:
- authelianet
- authelianet

View File

@ -1,13 +1,22 @@
version: '3'
services:
traefik:
image: traefik:v1.7.9-alpine
image: traefik:v1.7.20-alpine
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./example/compose/traefik/traefik.toml:/etc/traefik/traefik.toml
- '/var/run/docker.sock:/var/run/docker.sock'
labels:
- traefik.frontend.rule=Host:traefik.example.com
- traefik.port=8081
- 'traefik.frontend.rule=Host:traefik.example.com'
- 'traefik.port=8081'
command:
- '--api'
- '--api.entrypoint=api'
- '--docker'
- '--defaultentrypoints=https'
- '--logLevel=DEBUG'
- '--traefiklog=true'
- '--traefiklog.filepath=/var/log/traefik.log'
- '--entryPoints=Name:https Address::8080 TLS'
- '--entryPoints=Name:api Address::8081'
networks:
authelianet:
# Set the IP to be able to query on port 8080

View File

@ -1,55 +0,0 @@
defaultEntryPoints = ["http", "https"]
logLevel = "DEBUG"
[traefikLog]
filePath = "/var/log/traefik.log"
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":8080"
[entryPoints.https.tls]
[entryPoints.api]
address = ":8081"
[file]
[frontends]
[frontends.authelia_api]
backend = "authelia_api_backend"
[frontends.authelia_api.routes.route0]
rule = "Host:login.example.com; PathPrefix:/api;"
[frontends.authelia_front]
backend = "authelia_front_backend"
[frontends.authelia_front.routes.route0]
rule = "Host:login.example.com"
[backends]
[backends.authelia_api_backend]
[backends.authelia_api_backend.servers.server]
url = "http://authelia-backend:9091"
[backends.authelia_front_backend]
[backends.authelia_front_backend.servers.server]
url = "http://authelia-frontend:3000"
[api]
# This is exposed via a subdomain and a proxy
entryPoint = "api"
dashboard = true
[docker]
# Docker server endpoint. Can be a tcp or a unix socket endpoint.
endpoint = "unix:///var/run/docker.sock"
# network = "traefik_default"
# Default domain used.
# Can be overridden by setting the "traefik.domain" label on a container.
domain = "localhost"
# Enable watch docker changes
watch = true

View File

@ -0,0 +1,23 @@
version: '3'
services:
traefik:
image: traefik:v2.1.2
volumes:
- '/var/run/docker.sock:/var/run/docker.sock'
labels:
- 'traefik.http.routers.api.rule=Host(`traefik.example.com`)'
- 'traefik.http.routers.api.entrypoints=https'
- 'traefik.http.routers.api.service=api@internal'
- 'traefik.http.routers.api.tls=true'
command:
- '--api'
- '--providers.docker=true'
- '--entrypoints.https=true'
- '--entrypoints.https.address=:8080'
- '--log=true'
- '--log.level=DEBUG'
- '--log.filepath=/var/log/traefik.log'
networks:
authelianet:
# Set the IP to be able to query on port 8080
ipv4_address: 192.168.240.100

View File

@ -1,4 +1,4 @@
version: "3.4"
version: '3.4'
services:
authelia:
image: authelia/authelia:latest
@ -6,8 +6,8 @@ services:
configs:
- source: authelia
target: /etc/authelia/configuration.yml
uid: "0"
gid: "0"
uid: '0'
gid: '0'
mode: 0444
environment:
- NODE_TLS_REJECT_UNAUTHORIZED=0
@ -45,4 +45,4 @@ networks:
# This is needed if Docker configs are being used to provide Authelia with its configuration.
configs:
authelia:
external: true
external: true

View File

@ -1,6 +1,6 @@
version: "3"
version: '3'
services:
authelia-backend:
volumes:
- "./internal/suites/BypassAll/configuration.yml:/etc/authelia/configuration.yml:ro"
- "./internal/suites/BypassAll/users.yml:/var/lib/authelia/users.yml"
- './internal/suites/BypassAll/configuration.yml:/etc/authelia/configuration.yml:ro'
- './internal/suites/BypassAll/users.yml:/var/lib/authelia/users.yml'

View File

@ -1,6 +1,6 @@
version: "3"
version: '3'
services:
authelia-backend:
volumes:
- "./internal/suites/Docker/configuration.yml:/etc/authelia/configuration.yml:ro"
- "./internal/suites/Docker/users.yml:/var/lib/authelia/users.yml"
- './internal/suites/Docker/configuration.yml:/etc/authelia/configuration.yml:ro'
- './internal/suites/Docker/users.yml:/var/lib/authelia/users.yml'

View File

@ -1,6 +1,6 @@
version: "3"
version: '3'
services:
authelia-backend:
volumes:
- "./internal/suites/DuoPush/configuration.yml:/etc/authelia/configuration.yml:ro"
- "./internal/suites/DuoPush/users.yml:/var/lib/authelia/users.yml"
- './internal/suites/DuoPush/configuration.yml:/etc/authelia/configuration.yml:ro'
- './internal/suites/DuoPush/users.yml:/var/lib/authelia/users.yml'

View File

@ -1,6 +1,6 @@
version: "3"
version: '3'
services:
authelia-backend:
volumes:
- "./internal/suites/HAProxy/configuration.yml:/etc/authelia/configuration.yml:ro"
- "./internal/suites/HAProxy/users.yml:/var/lib/authelia/users.yml"
- './internal/suites/HAProxy/configuration.yml:/etc/authelia/configuration.yml:ro'
- './internal/suites/HAProxy/users.yml:/var/lib/authelia/users.yml'

View File

@ -1,5 +1,5 @@
version: "3"
version: '3'
services:
authelia-backend:
volumes:
- "./internal/suites/HighAvailability/configuration.yml:/etc/authelia/configuration.yml:ro"
- './internal/suites/HighAvailability/configuration.yml:/etc/authelia/configuration.yml:ro'

View File

@ -1,5 +1,5 @@
version: "3"
version: '3'
services:
authelia-backend:
volumes:
- "./internal/suites/LDAP/configuration.yml:/etc/authelia/configuration.yml:ro"
- './internal/suites/LDAP/configuration.yml:/etc/authelia/configuration.yml:ro'

View File

@ -1,6 +1,6 @@
version: "3"
version: '3'
services:
authelia-backend:
volumes:
- "./internal/suites/Mariadb/configuration.yml:/etc/authelia/configuration.yml:ro"
- "./internal/suites/Mariadb/users.yml:/var/lib/authelia/users.yml"
- './internal/suites/Mariadb/configuration.yml:/etc/authelia/configuration.yml:ro'
- './internal/suites/Mariadb/users.yml:/var/lib/authelia/users.yml'

View File

@ -1,6 +1,6 @@
version: "3"
version: '3'
services:
authelia-backend:
volumes:
- "./internal/suites/NetworkACL/configuration.yml:/etc/authelia/configuration.yml:ro"
- "./internal/suites/NetworkACL/users.yml:/var/lib/authelia/users.yml"
- './internal/suites/NetworkACL/configuration.yml:/etc/authelia/configuration.yml:ro'
- './internal/suites/NetworkACL/users.yml:/var/lib/authelia/users.yml'

View File

@ -1,6 +1,6 @@
version: "3"
version: '3'
services:
authelia-backend:
volumes:
- "./internal/suites/Postgres/configuration.yml:/etc/authelia/configuration.yml:ro"
- "./internal/suites/Postgres/users.yml:/var/lib/authelia/users.yml"
- './internal/suites/Postgres/configuration.yml:/etc/authelia/configuration.yml:ro'
- './internal/suites/Postgres/users.yml:/var/lib/authelia/users.yml'

View File

@ -1,6 +1,6 @@
version: "3"
version: '3'
services:
authelia-backend:
volumes:
- "./internal/suites/ShortTimeouts/configuration.yml:/etc/authelia/configuration.yml:ro"
- "./internal/suites/ShortTimeouts/users.yml:/var/lib/authelia/users.yml"
- './internal/suites/ShortTimeouts/configuration.yml:/etc/authelia/configuration.yml:ro'
- './internal/suites/ShortTimeouts/users.yml:/var/lib/authelia/users.yml'

View File

@ -1,6 +1,6 @@
version: "3"
version: '3'
services:
authelia-backend:
volumes:
- "./internal/suites/Standalone/configuration.yml:/etc/authelia/configuration.yml:ro"
- "./internal/suites/Standalone/users.yml:/var/lib/authelia/users.yml"
- './internal/suites/Standalone/configuration.yml:/etc/authelia/configuration.yml:ro'
- './internal/suites/Standalone/users.yml:/var/lib/authelia/users.yml'

View File

@ -1,6 +1,6 @@
version: "3"
version: '3'
services:
authelia-backend:
volumes:
- "./internal/suites/Traefik/configuration.yml:/etc/authelia/configuration.yml:ro"
- "./internal/suites/Traefik/users.yml:/var/lib/authelia/users.yml"
- './internal/suites/Traefik/configuration.yml:/etc/authelia/configuration.yml:ro'
- './internal/suites/Traefik/users.yml:/var/lib/authelia/users.yml'

View File

@ -0,0 +1,42 @@
###############################################################
# Authelia minimal configuration #
###############################################################
port: 9091
logs_level: debug
jwt_secret: unsecure_secret
authentication_backend:
file:
path: /var/lib/authelia/users.yml
session:
secret: unsecure_session_secret
domain: example.com
expiration: 3600 # 1 hour
inactivity: 300 # 5 minutes
storage:
local:
path: /var/lib/authelia/db.sqlite
access_control:
default_policy: bypass
rules:
- domain: "public.example.com"
policy: bypass
- domain: "admin.example.com"
policy: two_factor
- domain: "secure.example.com"
policy: two_factor
- domain: "singlefactor.example.com"
policy: one_factor
notifier:
smtp:
host: smtp
port: 1025
sender: admin@example.com
disable_require_tls: true

View File

@ -0,0 +1,6 @@
version: '3'
services:
authelia-backend:
volumes:
- './internal/suites/Traefik2/configuration.yml:/etc/authelia/configuration.yml:ro'
- './internal/suites/Traefik2/users.yml:/var/lib/authelia/users.yml'

View File

@ -0,0 +1,29 @@
###############################################################
# Users Database #
###############################################################
# This file can be used if you do not have an LDAP set up.
# List of users
users:
john:
password: "{CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
email: john.doe@authelia.com
groups:
- admins
- dev
harry:
password: "{CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
email: harry.potter@authelia.com
groups: []
bob:
password: "{CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
email: bob.dylan@authelia.com
groups:
- dev
james:
password: "{CRYPT}$6$rounds=500000$jgiCMRyGXzoqpxS3$w2pJeZnnH8bwW3zzvoMWtTRfQYsHbWbD/hquuQ5vUeIyl9gdwBIt6RWk2S6afBA0DPakbeWgD/4SZPiS0hYtU/"
email: james.dean@authelia.com

View File

@ -0,0 +1,59 @@
package suites
import (
"fmt"
"time"
)
var traefik2SuiteName = "Traefik2"
func init() {
dockerEnvironment := NewDockerEnvironment([]string{
"docker-compose.yml",
"internal/suites/Traefik2/docker-compose.yml",
"example/compose/authelia/docker-compose.backend.{}.yml",
"example/compose/authelia/docker-compose.frontend.{}.yml",
"example/compose/nginx/backend/docker-compose.yml",
"example/compose/traefik2/docker-compose.yml",
"example/compose/smtp/docker-compose.yml",
})
setup := func(suitePath string) error {
err := dockerEnvironment.Up()
if err != nil {
return err
}
return waitUntilAutheliaBackendIsReady(dockerEnvironment)
}
onSetupTimeout := func() error {
backendLogs, err := dockerEnvironment.Logs("authelia-backend", nil)
if err != nil {
return err
}
fmt.Println(backendLogs)
frontendLogs, err := dockerEnvironment.Logs("authelia-frontend", nil)
if err != nil {
return err
}
fmt.Println(frontendLogs)
return nil
}
teardown := func(suitePath string) error {
err := dockerEnvironment.Down()
return err
}
GlobalRegistry.Register(traefik2SuiteName, Suite{
SetUp: setup,
SetUpTimeout: 5 * time.Minute,
OnSetupTimeout: onSetupTimeout,
TestTimeout: 2 * time.Minute,
TearDown: teardown,
TearDownTimeout: 2 * time.Minute,
})
}

View File

@ -0,0 +1,27 @@
package suites
import (
"testing"
"github.com/stretchr/testify/suite"
)
type Traefik2Suite struct {
*SeleniumSuite
}
func NewTraefik2Suite() *Traefik2Suite {
return &Traefik2Suite{SeleniumSuite: new(SeleniumSuite)}
}
func (s *Traefik2Suite) TestOneFactorScenario() {
suite.Run(s.T(), NewOneFactorScenario())
}
func (s *Traefik2Suite) TestTwoFactorScenario() {
suite.Run(s.T(), NewTwoFactorScenario())
}
func TestTraefik2Suite(t *testing.T) {
suite.Run(t, NewTraefik2Suite())
}