lonix
May 30, 2023, 8:31am
1
I'm trying to implement traefik with basic auth to protect the dashboard. I wrote a minimal example, but it doesn't work.
I generated the password like this:
$ htpasswd -nb admin password
admin:$apr1$vO3/IDvg$JrbhU9NSQub83/mQu9/fP1
docker-compose.yml
services:
traefik:
image: traefik:v2.10.1
restart: unless-stopped
ports:
- 80:80
- 8080:8080
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/etc/traefik/traefik.yml:ro
- ./traefik_dynamic.yml:/etc/traefik/traefik_dynamic.yml:ro
traefik.yml
providers:
docker:
exposedByDefault: false
network: web
watch: true
file:
filename: /etc/traefik/traefik_dynamic.yml
watch: true
entryPoints:
web:
address: ":80"
api:
dashboard: true
insecure: true
traefik_dynamic.yml
http:
middlewares:
dashboard-auth:
basicAuth:
users:
- "admin:$apr1$vO3/IDvg$JrbhU9NSQub83/mQu9/fP1"
routers:
api:
rule: "Host(`localhost`)"
entrypoints: ["web"]
middlewares: ["dashboard-auth"]
service: "api@internal"
I can browse to http://myserver/dashboard/
which loads without errors.
But it does not ask for a username:password. How do I fix that?
Try disabling the insecure
mode:
lonix:
api:
insecure: true
lonix
May 30, 2023, 9:04am
3
Thanks. I just tried that but then it doesn't load the dashboard at all.
I think that option is for loading the dashboard over http (rather than https) - and for the minimal example I posted above, it's using http.
lonix
May 30, 2023, 11:03am
5
Thanks. I want to use the config file, not the docker-compose with labels.
That said, I took your example, removed all the https stuff, and ran it. I got the same result - it loads the dashboard without asking for the username:password.
Here's the compose file:
services:
traefik:
image: traefik:v2.10.1
ports:
- 80:80
- 8080:8080
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
command:
- --api.dashboard=true
- --api.insecure=true
- --log.level=INFO
- --providers.docker.exposedByDefault=false
- --entrypoints.web.address=:80
labels:
- traefik.enable=true
- traefik.http.routers.mydashboard.rule=Host(`localhost`)
- traefik.http.routers.mydashboard.service=api@internal
- traefik.http.routers.mydashboard.middlewares=myauth
- traefik.http.middlewares.myauth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/
lonix
May 30, 2023, 11:04am
6
Can someone confirm whether the dashboard works without https and using the config file approach? (As I've shown in the minmal example above.)
This is a hack to quickly enable dashboard on port 8080, it will ignore middlewares, remove the line:
lonix:
--api.insecure=true
And the line was not in my config
lonix
May 30, 2023, 12:00pm
8
Hi again and thanks. No, like I wrote above, without that the dashboard won't even load. There's no https in my config above.
Dashboard should be available at http://localhost/dashboard/
.
lonix
May 31, 2023, 1:28am
10
Like I wrote above, it's not the case.
With that switch it loads without asking for username/password, without the switch it doesn't load.
ldez
May 31, 2023, 2:22am
11
the problem is easy to fix, you have to remove:
network: web
because to don't have a web
docker network
watch: true
because this option is only for Swarm
insecure: true
because you want to use the secured API.
docker-compose.yml
version: '3.9'
services:
traefik:
image: traefik:v2.10.1
ports:
- 80:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/etc/traefik/traefik.yml:ro
- ./traefik_dynamic.yml:/etc/traefik/traefik_dynamic.yml:ro
traefik.yml
providers:
docker:
exposedByDefault: false
file:
filename: /etc/traefik/traefik_dynamic.yml
watch: true
entryPoints:
web:
address: ":80"
api:
dashboard: true
traefik_dynamic.yml
http:
middlewares:
dashboard-auth:
basicAuth:
users:
- "admin:$apr1$vO3/IDvg$JrbhU9NSQub83/mQu9/fP1"
routers:
api:
rule: "Host(`localhost`)"
entrypoints:
- web
middlewares:
- dashboard-auth
service: api@internal
I run those exact files and everything run fine.
launch traefik
$ docker-compose up --remove-orphans
[+] Running 1/0
✔ Container simple-traefik-1 Created 0.0s
Attaching to simple-traefik-1
simple-traefik-1 | time="2023-05-31T02:16:50Z" level=info msg="Configuration loaded from file: /etc/traefik/traefik.yml"
Dashboard access
$ curl http://localhost/dashboard/
401 Unauthorized
$ curl -u "admin:password" http://localhost/dashboard/
<!DOCTYPE html><html><head><title>Traefik</title><meta charset=utf-8><meta name=description content="Traefik UI"><meta name=format-detection content="telephone=no"><meta name=msapplication-tap-highlight content=no><meta name=viewport co
ntent="user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1,width=device-width"><link rel=icon type=image/png href=statics/app-logo-128x128.png><link rel=icon type=image/png sizes=16x16 href=statics/icons/favicon-16x16.png><
link rel=icon type=image/png sizes=32x32 href=statics/icons/favicon-32x32.png><link rel=icon type=image/png sizes=96x96 href=statics/icons/favicon-96x96.png><link rel=icon type=image/ico href=statics/icons/favicon.ico><link rel=apple-to
uch-icon href=statics/icons/apple-icon-152x152.png><link rel=apple-touch-icon sizes=152x152 href=statics/icons/apple-icon-152x152.png><link rel=apple-touch-icon sizes=167x167 href=statics/icons/apple-icon-167x167.png><link rel=apple-tou
ch-icon sizes=180x180 href=statics/icons/apple-icon-180x180.png><link href=css/041f4ca8.f6e3d404.css rel=prefetch><link href=css/067758be.3de973dd.css rel=prefetch><link href=css/09354cb8.0e433876.css rel=prefetch><link href=css/09d4499
a.34653c53.css rel=prefetch><link href=css/11f98cd8.02647ec3.css rel=prefetch><link href=css/29ab06d1.ec33fe24.css rel=prefetch><link href=css/2a73a9da.e66a33dc.css rel=prefetch><link href=css/3e3ce03c.9b22e80f.css rel=prefetch><link hr
ef=css/46fd955e.9b22e80f.css rel=prefetch><link href=css/491024e9.9b22e80f.css rel=prefetch><link href=css/52875482.9b22e80f.css rel=prefetch><link href=css/6d73c73c.9b22e80f.css rel=prefetch><link href=css/77d911b4.9b22e80f.css rel=pre
fetch><link href=css/797e4f23.9b22e80f.css rel=prefetch><link href=css/b34404c8.9b22e80f.css rel=prefetch><link href=css/e036c7dc.1666b9a0.css rel=prefetch><link href=js/041f4ca8.4f70d06d.js rel=prefetch><link href=js/067758be.c7890581.
js rel=prefetch><link href=js/09354cb8.2e39e534.js rel=prefetch><link href=js/09d4499a.d0d6efba.js rel=prefetch><link href=js/11f98cd8.e511840d.js rel=prefetch><link href=js/29ab06d1.8f1fa71a.js rel=prefetch><link href=js/2a73a9da.b2faf
5c2.js rel=prefetch><link href=js/2d21e8fd.c00ac0e6.js rel=prefetch><link href=js/3e3ce03c.293f4729.js rel=prefetch><link href=js/46fd955e.343a8488.js rel=prefetch><link href=js/491024e9.5ba4955c.js rel=prefetch><link href=js/52875482.6
5e645a6.js rel=prefetch><link href=js/6d73c73c.d8a27bbb.js rel=prefetch><link href=js/77d911b4.8d5002b7.js rel=prefetch><link href=js/797e4f23.771f63ae.js rel=prefetch><link href=js/b34404c8.7a4b9be8.js rel=prefetch><link href=js/e036c7
dc.5d7ae0bf.js rel=prefetch><link href=css/app.3d2d5994.css rel=preload as=style><link href=js/app.0981e94c.js rel=preload as=script><link href=js/runtime.3de71a2a.js rel=preload as=script><link href=js/vendor.f60bcb86.js rel=preload as
=script><link href=css/app.3d2d5994.css rel=stylesheet></head><body><div id=q-app></div><script type=text/javascript src=js/app.0981e94c.js></script><script type=text/javascript src=js/runtime.3de71a2a.js></script><script type=text/java
script src=js/vendor.f60bcb86.js></script></body></html>%
ldez
May 31, 2023, 2:36am
12
The same thing but with only docker-compose (without the file provider)
I recommend this approach.
docker-compose.yml
version: '3.9'
services:
traefik:
image: traefik:v2.10.1
ports:
- 80:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
command:
- --api
- --providers.docker.exposedbydefault=false
- --entrypoints.web.address=:80
labels:
traefik.enable: 'true'
# Dashboard
traefik.http.routers.traefik.rule: Host(`localhost`)
traefik.http.routers.traefik.entrypoints: web
traefik.http.routers.traefik.service: api@internal
traefik.http.routers.traefik.middlewares: dashboard-auth
traefik.http.middlewares.dashboard-auth.basicauth.users: admin:$$apr1$$vO3/IDvg$$JrbhU9NSQub83/mQu9/fP1 # admin/password
Launch Traefik
$ docker-compose up --remove-orphans
[+] Running 1/0
✔ Container simple-traefik-1 Recreated 0.0s
Attaching to simple-traefik-1
simple-traefik-1 | time="2023-05-31T02:33:24Z" level=info msg="Configuration loaded from flags."
Dashboard access
$ curl http://localhost/dashboard/
401 Unauthorized
$ curl -u "admin:password" http://localhost/dashboard/
<!DOCTYPE html><html><head><title>Traefik</title><meta charset=utf-8><meta name=description content="Traefik UI"><meta name=format-detection content="telephone=no"><meta name=msapplication-tap-highlight content=no><meta name=viewport content="user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1,width=device-width"><link rel=icon type=image/png href=statics/app-logo-128x128.png><link rel=icon type=image/png sizes=16x16 href=statics/icons/favicon-16x16.png><link rel=icon type=image/png sizes=32x32 href=statics/icons/favicon-32x32.png><link rel=icon type=image/png sizes=96x96 href=statics/icons/favicon-96x96.png><link rel=icon type=image/ico href=statics/icons/favicon.ico><link rel=apple-touch-icon href=statics/icons/apple-icon-152x152.png><link rel=apple-touch-icon sizes=152x152 href=statics/icons/apple-icon-152x152.png><link rel=apple-touch-icon sizes=167x167 href=statics/icons/apple-icon-167x167.png><link rel=apple-touch-icon sizes=180x180 href=statics/icons/apple-icon-180x180.png><link href=css/041f4ca8.f6e3d404.css rel=prefetch><link href=css/067758be.3de973dd.css rel=prefetch><link href=css/09354cb8.0e433876.css rel=prefetch><link href=css/09d4499a.34653c53.css rel=prefetch><link href=css/11f98cd8.02647ec3.css rel=prefetch><link href=css/29ab06d1.ec33fe24.css rel=prefetch><link href=css/2a73a9da.e66a33dc.css rel=prefetch><link href=css/3e3ce03c.9b22e80f.css rel=prefetch><link href=css/46fd955e.9b22e80f.css rel=prefetch><link href=css/491024e9.9b22e80f.css rel=prefetch><link href=css/52875482.9b22e80f.css rel=prefetch><link href=css/6d73c73c.9b22e80f.css rel=prefetch><link href=css/77d911b4.9b22e80f.css rel=prefetch><link href=css/797e4f23.9b22e80f.css rel=prefetch><link href=css/b34404c8.9b22e80f.css rel=prefetch><link href=css/e036c7dc.1666b9a0.css rel=prefetch><link href=js/041f4ca8.4f70d06d.js rel=prefetch><link href=js/067758be.c7890581.js rel=prefetch><link href=js/09354cb8.2e39e534.js rel=prefetch><link href=js/09d4499a.d0d6efba.js rel=prefetch><link href=js/11f98cd8.e511840d.js rel=prefetch><link href=js/29ab06d1.8f1fa71a.js rel=prefetch><link href=js/2a73a9da.b2faf5c2.js rel=prefetch><link href=js/2d21e8fd.c00ac0e6.js rel=prefetch><link href=js/3e3ce03c.293f4729.js rel=prefetch><link href=js/46fd955e.343a8488.js rel=prefetch><link href=js/491024e9.5ba4955c.js rel=prefetch><link href=js/52875482.65e645a6.js rel=prefetch><link href=js/6d73c73c.d8a27bbb.js rel=prefetch><link href=js/77d911b4.8d5002b7.js rel=prefetch><link href=js/797e4f23.771f63ae.js rel=prefetch><link href=js/b34404c8.7a4b9be8.js rel=prefetch><link href=js/e036c7dc.5d7ae0bf.js rel=prefetch><link href=css/app.3d2d5994.css rel=preload as=style><link href=js/app.0981e94c.js rel=preload as=script><link href=js/runtime.3de71a2a.js rel=preload as=script><link href=js/vendor.f60bcb86.js rel=preload as=script><link href=css/app.3d2d5994.css rel=stylesheet></head><body><div id=q-app></div><script type=text/javascript src=js/app.0981e94c.js></script><script type=text/javascript src=js/runtime.3de71a2a.js></script><script type=text/javascript src=js/vendor.f60bcb86.js></script></body></html>%
lonix
May 31, 2023, 2:42am
13
Thanks Idez! Unfortunately that is not working as expected.
curl http://localhost/dashboard/
curl -u "admin:password" http://localhost/dashboard/
If I add 8080:8080
to compose file, then:
curl -u "admin:password" http://localhost/dashboard/
It works! ...but only from inside that server
It doesn't work when I access it remotely: http://myserver:8080/dashboard/
Maybe I'm not understanding something important? Can I access the dashboard remotely, without https, and still have basic auth?
ldez
May 31, 2023, 2:45am
14
basic auth is not related to TLS (HTTPS).
If you are using my files, the port 8080 cannot work, it's impossible:
because port 8080 is not exposed
because http://localhost
means port 80
If you want to access remotely you have to use a real domain and change the router rule: Host(`example.com`)
1 Like
lonix
May 31, 2023, 2:50am
16
Ok I will connect it to a domain and report my findings. Thanks for your advice!
BTW I was accessing it as http://xxx.xxx.xxx.xxx:8080/dashboard/
ldez
May 31, 2023, 2:53am
17
I think you don't provide all the information.
If you are using my files (I recommend just copy-paste my files) the port 8080 is not exposed so you cannot access it through port 8080.
But maybe to have something not related to Traefik that redirects port 8080 on port 80.
Or you are not using my files and you still have api.insecure: true
and port 8080:8080
.
Your context is not clear.
lonix
May 31, 2023, 4:18am
18
Hi, I am busy setting up new domain as you suggested... I am sure you are right that is the issue.
But in the meantime, to answer your above comment:
I actually I did use your code exactly... copy-paste. And:
on server itself, curl http://localhost/dashboard/
gives 401 same as you
on server itself, curl -u "admin:password" http://localhost/dashboard/
gives 200/OK and dashboard same as you
BUT , on my computer, when I access remote server, curl -u "admin:password" http://xxx.xxx.xxx.xxx/dashboard/
it gives 404 (however when I add 8080, it loads but without username/password challenge)
So when I follow instructions exactly, it works inside server, but not when accessed from outside world.
No worries though - I will setup a domain and try again...
I am also having the same issue. I want to have my dashboard to have basic auth on "http://your-server-ip:8080/dashboard/ ". I get confused with traefik.yaml and toml files so I like everything to be on my docker-compose file as commands and/or labels.
Here is my compose file:
version: '3.8'
services:
traefik:
restart: unless-stopped
image: traefik:latest
command:
## Logs for debugging
- --log.filePath=/var/logs/traefik.log
- --log.level=INFO # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.traefik.address=:8080"
- "--certificatesresolvers.prodresolver.acme.email=${TRAEFIK_ACME_EMAIL}"
- "--certificatesresolvers.prodresolver.acme.caserver=${TRAEFIK_ACME_SERVER}"
- "--certificatesresolvers.prodresolver.acme.keytype=RSA4096"
- "--certificatesresolvers.prodresolver.acme.tlschallenge=true"
- "--certificatesresolvers.prodresolver.acme.httpchallenge=true"
- "--certificatesresolvers.prodresolver.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.prodresolver.acme.storage=/letsencrypt/acme.json"
# traefik dashboard
- --api.dashboard=true
- --api.insecure=false
- "--ping=true"
- "--ping.entrypoint=ping"
- "--global.checkNewVersion=true"
- "--global.sendAnonymousUsage=false"
- "--entryPoints.ping.address=:8082"
- --providers.docker.exposedbydefault=false
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
ports:
- "80:80"
- "443:443"
- "8080:8080"
healthcheck:
test: ["CMD", "wget", "http://localhost:8082/ping","--spider"]
interval: 10s
timeout: 5s
retries: 3
start_period: 5s
volumes:
- "./letsencrypt:/letsencrypt"
- /var/run/docker.sock:/var/run/docker.sock:ro
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule: Host(`localhost`)"
- "traefik.http.routers.traefik.entrypoints=web"
- "traefik.http.routers.traefik.service=api@internal"
- "traefik.http.routers.traefik.middlewares=traefik-auth"
- "traefik.http.middlewares.traefik-auth.basicauth.users=${BASIC_AUTH}"
- "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=web"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
networks:
- traefik-network
networks:
traefik-network:
external: true
I am getting "404 page not found" on the web browser. Can you assist me?
What URL do you request? It seems strange to have a redirect to https, but at the same time only listen on http entrypoint web
.
Compare to simple Traefik example .