- Go 100%
| acl.json | ||
| go.mod | ||
| LICENSE.md | ||
| main.go | ||
| README.md | ||
authz
This is a pretty hacky approach to add a okay-ish-grained ACL to traefik mTLS via a forwardauth middleware.
Deployment
execute the binary with the acl.json file in the working directory. currently it automatically listens to all interfaces on 8080.
Configuration
ACL
Basically, define a list of hosts that can be accessed with a role, then define what certificate has what role. the certificate is determined by it's Common Name (be careful tho, there currently is a hardcoded manipulation of the CN to fit my setup). The onyl exception is superadmin, which is a hardcoded role that always grants access.
{
"roles": {
"infra": [
"traefik.example.com"
],
"media": [
"jellyfin.seed.example.com",
"jellyseerr.seed.example.com"
],
"media-infra": [
"sonarr.seed.example.com",
"radarr.seed.example.com",
"prowlarr.seed.example.com",
"bazarr.seed.example.com"
],
"secret": [
"secret.example.com"
]
},
"certificates": {
"Max-MacBook": ["superadmin"],
"Max-iPhone": ["media", "notes"],
"Max-Linux-Workstation": ["media", "media-infra", "notes"]
}
}
Everything else
you configure the software by editing the source code. Especially when it comes to validating your cert, I dont care about anyone but me and my specific usecase.
traefik config
you need some sort of root CA setup beforehand. I have one set up with an intermediary CA for the specific use case.
# this configures traefik to use your custom certificates/CA for https and mTLS.
tls:
certificates: # these are signed by the same intermediate CA as the mTLS certs
- certFile: /etc/traefik/certs/traefik.crt
keyFile: /etc/traefik/certs/traefik.key
options:
mtls:
minVersion: VersionTLS12
clientAuth:
caFiles:
- /etc/traefik/certs/ca-chain.crt # This is the chain of rootCA -> Intermediate CA used to validate the certificates in the first step.
clientAuthType: RequireAndVerifyClientCert
http:
middlewares:
client-cert-authz: # this is the actual auth part
forwardAuth:
address: "http://host.containers.internal:8080/fw/verify" # change
trustForwardHeader: true # yes this is correct. HOWEVER this is insecure THE SECOND you don't have client-cert-info in the middleware chain BEFORE client-cert-authz
client-cert-info: # this ensures that the right values of the cert are passed down
passTLSClientCert:
info:
subject:
commonName: true
organization: true
organizationalUnit: true
routers:
dashboard: # and this is how you use it
rule: "Host(`traefik.home.lan`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
service: api@internal
entryPoints: [websecure]
tls:
options: mtls@file # this enables mTLS. If you just want plain https via the CA, only put "tls: {}".
middlewares: # MAKE SURE THEY ARE IN ORDER
- client-cert-info
- client-cert-authz