Traefik does not use cert file provided for OpenConnect VPN - traefik

I have setup traefik in docker and use let's encrypt on the domain example.tld with some
services:
traefik:
image: "traefik:2.8.2"
container_name: "traefik"
hostname: "traefik"
restart: always
command:
- "--serverstransport.insecureskipverify=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.letsencrypt.acme.email=mail#example.tld"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--providers.file.filename=/etc/traefik/rules.yml"
- "--providers.file.watch=true"
ports:
- "443:443"
- "80:80"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "./volumes/traefik/log:/etc/traefik/log"
- "./volumes/traefik/rules.yml:/etc/traefik/rules.yml"
- "./volumes/traefik/letsencrypt/:/letsencrypt/"
whoami:
image: "traefik/whoami"
container_name: "simple-service"
restart: always
labels:
- "traefik.enable=true"
- 'traefik.http.routers.whoami.tls.certresolver=letsencrypt'
- "traefik.http.routers.whoami.rule=Host(`whoami.example.tld`)"
This all functions, but now I wanted to add a OpenConnect VPN on the same port.
So in a file provider:
http:
routers:
router-vpn:
entryPoints:
- websecure
rule: Host(`vpn.example.tld`) # (same domain)
service: service-vpn
store: default
services:
service-vpn:
loadBalancer:
servers:
- url: "https://ocserver:3334"
tls:
stores:
default:
defaultCertificate:
certFile: /etc/traefik/log/certs/cert.pem
keyFile: /etc/traefik/log/certs/key.pem
certificates:
- certFile: /etc/traefik/log/certs/cert.pem
keyFile: /etc/traefik/log/certs/key.pem
The cert is copied from the OpenConnect server. The problem is that the OCC (OpenConnect Client) and the OCS (OpenConnect Server) connect over http CONNECT (the OCS receives the request) and use the public shown cert for encryption, but because traefik show's the lets encrypt cert the server can't decrypt the answer of the client and so does fail.
So now my question is how can i (on the same domain) force traefik to use the cert file (no matter if valid) for vpn.example.tld and for the rest of the domains use the LE cert?

Traefik currently only supports SNI based cert matching when the cert is valid and even this implementation is unreliable. I suggest using tls-passthrough as per documentation.

Related

How to set Let's Encrypt SSL in duckdns domain with Traefik

Now I set my IP in duckdns panel with domain 'domainname.duckdns.org'
And I want to set my Traefik web panel with Let's Encrypt SSL
And I installed Traefik with dockers stacks command
version: "3.3"
services:
traefik:
image: "traefik:v2.5"
container_name: "traefik"
command:
#- "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
- "--certificatesresolvers.myresolver.acme.email=MYEMAIL ADDRESS"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
- "--pilot.token=MY PILOT TOKEN"
ports:
- "443:443"
- "8080:8080"
volumes:
- "./letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
labels:
- "traefik.port=8080"
- "traefik.enable=true"
- "traefik.http.routers.traefik.rule=Host(`domainname.duckdns.org`)"
- "traefik.http.routers.traefik.entrypoints=websecure"
- "traefik.http.routers.traefik.tls.certresolver=myresolver"
And When I run with this command, still I can access web panel with 8080 port with domainname.duckdns.org (Not a subdomain) But when I access with https://domainname.duckdns.org, it shows and error 'Bad Gateway' But can connect with SSL. But in my web panel it seems that SSL certificate is already applied.
Is there any problem in my docker-compose file?

Traefik cannot access Dashboard

I have a problem with Traefik. All my services are OK, Traefik does his job, retrieves the certificates of Lets Encrypt, makes Load blancing between my different applications.
My problem is that I can't access the Dashboard, it asks me a login/password, yet I informed it in the docker-compose.
version: "3.7"
services:
traefik:
image: traefik:chevrotin
command:
--entrypoints.http.address=:80
--entrypoints.https.address=:443
--providers.docker=true
--api=true
--certificatesresolvers.letsencrypt.acme.httpchallenge=true
--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http
--certificatesresolvers.letsencrypt.acme.email=mymail#mail.com
--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
labels:
- traefik.enable=true
# Redirect all HTTP traffic to HTTPS
- traefik.http.routers.to-https.rule=Host(`traefik.mydomain.com`)
- traefik.http.routers.to-https.entrypoints=http
- traefik.http.routers.to-https.middlewares=to-https
- traefik.http.routers.traefik.rule=Host(`traefik.mydomain.com`)
- traefik.http.routers.traefik.entrypoints=http
- traefik.http.routers.traefik.middlewares=auth
- traefik.http.routers.traefik.service=api#internal
- traefik.http.routers.traefik.tls=true
- traefik.http.routers.traefik.tls.certresolver=letsencrypt
- traefik.http.middlewares.to-https.redirectscheme.scheme=https
- traefik.http.middlewares.auth.basicauth.users=MyLogin:MyPassword
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /docker/letsencrypt:/letsencrypt
if you have a idea. Thanks
I find. I'm not encoded my password.
I use this website : https://www.web2generators.com/apache-tools/htpasswd-generator
to encoded my password.
"traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj
Note: all dollar signs in the hash need to be doubled for escaping

Is there a way to let some traefik services manage their tls certificates themselves?

I'll try to configure traefik for something like that:
1) server.example.com --> traefik --> httpChallengeToLetsEncrypt
2) client --> traefik (passthrough tls) --> server.example.com( with let's encrypt )
N.B.: traefik receives its requests at example.com level
What is happening:
1) Works correctly only if traefik does not manage let's encrypt certificates itself (otherwise it does not transmit any request whose pathPrefix begins with ".well-known/acme-challenge" :-\ )
2) Does not work with a config for tcp router like this:
tcp:
routers:
example:
entryPoints:
- web-secure
rule: "HostSNI(`server.example.com`)"
service: example
tls:
passthrough: true
services:
example:
loadBalancer:
servers:
- url: "https://192.168.0.1:443/"
How would you let one or more services manage their let's encrypt certificates themselves ?
And is it possible to do it at the same time that traefik also manages let's encrypt certificates or the problem mentioned in point 1 is it redibitory?
Best regards,
jmc
use tls.passthrough=true and a tcp router instead of http
below is a fully working example where apache is responsible for its own certificates.
traefik never touches them
version: "3"
services:
traefik:
image: traefik
command:
- --api.insecure=true
- --providers.docker=true
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
labels:
- traefik.http.routers.api.rule=Host(`traefik.docker.local`)
- traefik.http.routers.api.service=api#internal
whoami:
image: containous/whoami
labels:
- traefik.http.routers.whoami.rule=Host(`whoami.docker.local`)
- traefik.http.routers.whoami.service=whoami#docker
- traefik.http.services.whoami.loadbalancer.server.port=80
apache:
build: php-apache
depends_on: [traefik]
env_file: ./php-apache/env
volumes:
- "./php-apache/cert/haproxy/:/etc/ssl/haproxy/"
- "./php-apache/cert/private/:/etc/ssl/private/"
- "./php-apache/cert/trusted/:/usr/local/share/ca-certificates/"
- "./php-apache/conf/:/etc/apache2/conf-enabled/"
- "./php-apache/log/:/var/log/apache2/"
- "./php-apache/sites/available/:/etc/apache2/sites-available/"
- "./php-apache/sites/enabled/:/etc/apache2/sites-enabled/"
- "./php-apache/www/:/var/www/"
labels:
- "traefik.http.routers.apache.entrypoints=http"
- "traefik.http.routers.apache.priority=1"
- "traefik.http.routers.apache.rule=HostRegexp(`{catchall:.*}`)"
- "traefik.http.routers.apache.service=apache#docker"
- "traefik.http.services.apache.loadbalancer.server.port=80"
- "traefik.tcp.routers.apache.entrypoints=https"
- "traefik.tcp.routers.apache.rule=HostSNI(`*`)"
- "traefik.tcp.routers.apache.service=apache#docker"
- "traefik.tcp.routers.apache.tls.passthrough=true"
- "traefik.tcp.services.apache.loadbalancer.server.port=443"

Traefik and Harbor

I have changed the docker-compose.yml after the default Conf-Generation. My Proxy configuration looks like:
( I had only touched the proxy part )
proxy:
image: goharbor/nginx-photon:v1.9.4
container_name: nginx
restart: always
cap_drop:
- ALL
cap_add:
- CHOWN
- SETGID
- SETUID
- NET_BIND_SERVICE
volumes:
- ./common/config/nginx:/etc/nginx:z
networks:
- harbor
- web
dns_search: .
expose:
- 8080
ports:
- 8081:8080 #only to test if its online
labels:
- "traefik.enable=true"
- "traefik.backend=harbor-backend"
- "traefik.docker.network=web"
- "traefik.frontend.rule=Host:harbor.example.com"
- "traefik.frontend.entryPoints=https,http"
- "traefik.port=8080"
depends_on:
- registry
- core
- portal
- log
logging:
driver: "syslog"
options:
syslog-address: "tcp://127.0.0.1:1514"
tag: "proxy"
networks:
harbor:
external: false
web:
external: true
In my Harbor.yml i had leaved the http port to 80 and disabled https.
My Proxy configuration is the default one.
The Web UI works fine but when I try to login with the docker client i get this response:
root#h2791112:~# docker login registry.example.com
Username: admin
Password:
Error response from daemon: Get https://registry.example.com/v2/: unauthorized: authentication required
And that are the crendentials that work with the ui
did I miss a label ?
This worked for me: https://github.com/goharbor/harbor/issues/3114#issuecomment-432962664
Follow the steps

Redis connection refused when using traefik

I'm having a hard time trying to configure one redis container for all my applications using traefik. This is my configuration:
1 - Docker compose for Traefik and Redis:
version: '2'
services:
proxy:
container_name: traefik
image: traefik:1.3.6-alpine
command: --docker
ports:
- 80:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.toml:/traefik.toml
networks:
- proxy
labels:
- traefik.frontend.rule=Host:monitor.company.dev
- traefik.port=8080
redis:
container_name: main_redis
image: redis:3.2
restart: always
volumes:
- ./data/redis:/data
networks:
- proxy
labels:
- traefik.backend=main-redis
- traefik.default.protocol=http
- traefik.frontend.rule=Host:main-redis.company.dev
- traefik.docker.network=proxy
- traefik.port=6379
networks:
proxy:
external: true
2 - Docker compose for my PHP Application.
version: '2'
services:
...
php:
container_name: myapp_php
build: ./docker/php # php:7.1-fpm base image
networks:
- internal
- proxy
labels:
- traefik.enable=false
- traefik.docker.network=proxy
expose:
- 9000
networks:
proxy:
external: true
internal:
external: false
I tried to connect my php application to main-redis.company.dev on both ports 6379 and 80 but I get a Redis::connect(): connect() failed: Connection refused message.
I also changed these stuff in my redis.conf:
Commented the line with bind 127.0.0.1
And changed protected-mode to no
My docker containers are staying in the same network, so I think it should work. Anyone knows why am I having this problem?
2022 UPDATE to #djeeg answer
For some time now you can use TCP mode for your routers. To do that you need to define the labels with TCP instead of HTTP
labels:
- "traefik.enable=true"
- "traefik.tcp.routers.redis.rule=HostSNI(`redis.example.com`)"
- "traefik.tcp.routers.redis.entrypoints=redis" //6379 entrypoint
- "traefik.tcp.routers.redis.tls.certresolver=myresolver" //let's encrypt resolver
- "traefik.tcp.routers.redis.service=redis"
- "traefik.tcp.services.redis.loadbalancer.server.port=6379"
once you got that working in order to connect assuming you are using TSL you will get error Error: Protocol error, got "H" as reply type byte.
To prevent this you need to do things.
Allow for tls connection in the connection string
Setup SNI for your DNS name or provide public certificate file via cert pr cacert
redis-cli -u redis://redis.example.com:6379 --tls --sni redis.example.com
First off, remove the traefik labels from your redis service definition, traefik is currently (Nov 2017) a HTTP proxy, so you can't expose the endpoint like that
See here:
https://github.com/containous/traefik/issues/10
https://github.com/containous/traefik/issues/1611
Then to connect the php service to the redis service, that looks like you are trying to do that within the same docker instance (rather than externally)
Instead of main-redis.company.dev:6379, it should be like on of these:
redis:6379
main_redis:6379
%PROJECT_NAME%_redis:6379
depending upon how you are deploying the container