How to configure traefik for dns over tls?

Viewed 198

I have a problem configuring my traefik + pihole setup. I want to configure dns over tls. Maybe someone can point me out in right directions?

In debug process, i found about tool kdig. I have tried it:

 kdig -d @myiphere +tls-ca +tls-host=mydnshere  example.com                                                                                  07:36:12
;; DEBUG: Querying for owner(example.com.), class(1), type(1), server(myiphere), port(853), protocol(TCP)
;; DEBUG: TLS, imported 127 system certificates
;; WARNING: TLS, handshake failed (A TLS fatal alert has been received.)

Okay, so maybe a certificate is wrong? It does not look like it:

openssl s_client -connect mydnshere:853                                                                                                                                                    
CONNECTED(00000003)
/***bunch of text here***/
SSL handshake has read 5070 bytes and written 382 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_128_GCM_SHA256
Server public key is 4096 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
---
Post-Handshake New Session Ticket arrived:
/***bunch of text here***/

Can someone point me out in right direction or tell what i am missing?

I have to mention that dig domain.com @myiphere and dig +tcp domain.com @myiphere are working fine.

Here is my configs:

traefik:

version: "3.8"                                                                                                                                                                                                     
                                                                                                                                                                                                                   
services:                                                                                                                                                                                                          
  reverse-proxy:                                                                                                                                                                                                   
    image: traefik                                                                                                                                                                                                 
    restart: unless-stopped                                                                                                                                                                                        
    command:                                                                                                                                                                                                       
      - "--api=true"                                                                                                                                                                                               
      - "--providers.docker=true"                                                                                                                                                                                  
      - "--providers.docker.exposedbydefault=false"                                                                                                                                                                
      - "--entrypoints.web.address=:80"                                                                                                                                                                            
      - "--entrypoints.dns.address=:53"                                                                                                                                                                            
      - "--entrypoints.dot.address=:853"                                                                                                                                                                           
      - "--entrypoints.dns-udp.address=:53/udp"                                                                                                                                                                    
      - "--entrypoints.websecure.address=:443"                                                                                                                                                                     
      - "--entrypoints.vpn-udp.address=:51820/udp"                                                                                                                                                                 
      - "--entrypoints.syncthing-tcp.address=:20000"                                                                                                                                                               
      - "--entrypoints.syncthing-udp.address=:20000/udp"                                                                                                                                                           
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"                                                                                                                                              
      - "--entrypoints.web.http.redirections.entryPoint.scheme=https"                                                                                                                                              
      - "--certificatesresolvers.le.acme.email=wkill95@gmail.com"                                                                                                                                                  
      - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"                                                                                                                                           
      - "--certificatesresolvers.le.acme.httpchallenge=true"                                                                                                                                                       
      - "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"                                                                                                                                             
      - "--pilot.token=${TRAEFIK_PILOT_TOKEN:-}"                                                                                                                                                                   
      - "--serversTransport.insecureSkipVerify=true"                                                                                                                                                               
      - "--log.level=${TRAEFIK_LOG_LEVEL:-ERROR}"                                                                                                                                                                  
    ports:                                                                                                                                                                                                         
      # TODO: found out how to show remote ip in pihole                                                                                                                                                            
      #- "53:53"                                                                                                                                                                                                   
      #- "53:53/udp"                                                                                                                                                                                               
      - "853:853"                                                                                                                                                                                                  
      # The HTTP port                                                                                                                                                                                              
      - "80:80"                                                                                                                                                                                                    
      - "443:443"                                                                                                                                                                                                  
      # VPN                                                                                                                                                                                                        
      - "51820:51820/udp"                                                                                                                                                                                          
      # The Web UI (enabled by --api.insecure=true)                                                                                                                                                                
      #- "8080:8080"       
      # Syncthing
      - "22000:22000"
      - "22000:22000/udp"
    volumes:
      # So that Traefik can listen to the Docker events
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - traefik_certs:/letsencrypt
    networks:
      - reverse-proxy
    dns:
      - 1.1.1.1
      - 1.0.0.1
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.api-data.rule=Host(`${TRAEFIK_API_DOMAIN?No traefik api domain set}`) && ( Path(`/api/version`) || PathPrefix(`/api/http/`) || PathPrefix(`/api/tcp/`))"
      - "traefik.http.routers.api-data.entrypoints=websecure"
      - "traefik.http.routers.api-data.service=api@internal"
      - "traefik.http.routers.api-data.tls=true"
      - "traefik.http.routers.api-data.tls.certresolver=${TRAEFIK_API_CERTRESOLVER?No traefik api certificate resolver}"
      - "traefik.http.routers.api.rule=Host(`${TRAEFIK_API_DOMAIN?No traefik api domain set}`)"
      - "traefik.http.routers.api.entrypoints=websecure"
      - "traefik.http.routers.api.service=api@internal"
      - "traefik.http.routers.api.tls=true"
      - "traefik.http.routers.api.tls.certresolver=${TRAEFIK_API_CERTRESOLVER?No traefik api certificate resolver}"
      - "traefik.http.routers.api.middlewares=authelia@docker"

      - "flame.type=application"
      - "flame.name=Traefik"
      - "flame.url=https://${TRAEFIK_API_DOMAIN}"
      - "flame.icon=router-network"

volumes:
  traefik_certs:

networks:
  reverse-proxy:
    name: reverse-proxy

pihole:

version: '3.8'                                                                                                                                                                                                     
                                                                                                                                                                                                                   
services:                                                                                                                                                                                                          
  pihole:                                                                                                                                                                                                          
    image: pihole/pihole                                                                                                                                                                                           
    restart: unless-stopped                                                                                                                                                                                        
    env_file: pihole.environment                                                                                                                                                                                   
    cap_add:                                                                                                                                                                                                       
      - CAP_NET_ADMIN                                                                                                                                                                                              
    networks:                                                                                                                                                                                                      
      - reverse-proxy                                                                                                                                                                                              
    dns:                                                                                                                                                                                                           
      - 127.0.0.1                                                                                                                                                                                                  
      - 1.1.1.1                                                                                                                                                                                                    
    ports:                                                                                                                                                                                                         
      - 53:53/tcp                                                                                                                                                                                                  
      - 53:53/udp                                                                                                                                                                                                  
    volumes:                                                                                                                                                                                                       
      - 'pihole_configs:/etc/pihole/'                                                                                                                                                                              
    labels:                                                                                                                                                                                                        
      - "traefik.enable=true"                                                                                                                                                                                      
      - "traefik.docker.network=reverse-proxy"                                                                                                                                                                     
                                                                                                                                                                                                                   
      - "traefik.http.routers.pihole-api.rule=Host(`${PIHOLE_DOMAIN:?No pihole domain set}`) && Path(`/admin/api.php`)"                                                                                            
      - "traefik.http.routers.pihole-api.tls=true"                                                                                                                                                                 
      - "traefik.http.routers.pihole-api.tls.certresolver=${PIHOLE_CERTRESOLVER?No pihole certificate resolver}"
      - "traefik.http.routers.pihole-api.entrypoints=websecure"
      - "traefik.http.routers.pihole-api.service=pihole"
      - "traefik.http.services.pihole-api.loadBalancer.server.port=80"

      - "traefik.http.routers.pihole.rule=Host(`${PIHOLE_DOMAIN:?No pihole domain set}`)"
      - "traefik.http.routers.pihole.tls=true"
      - "traefik.http.routers.pihole.tls.certresolver=${PIHOLE_CERTRESOLVER?No pihole certificate resolver}"
      - "traefik.http.routers.pihole.entrypoints=websecure"
      - "traefik.http.routers.pihole.service=pihole" 
      - "traefik.http.routers.pihole.middlewares=authelia@docker"
      - "traefik.http.services.pihole.loadBalancer.server.port=80"
      - "flame.type=application"
      - "flame.name=DNS"
      - "flame.url=https://${PIHOLE_DOMAIN}/admin"
      - "flame.icon=pi-hole"

      - "traefik.tcp.routers.dnsovertls.rule=HostSNI(`mydnshere`)"
      - "traefik.tcp.routers.dnsovertls.entrypoints=dot"
      - "traefik.tcp.routers.dnsovertls.tls.certresolver=le"
      - "traefik.tcp.routers.dnsovertls.service=pihole"

      # Normal DNS coming in on 53 TCP, no TLS
      - "traefik.tcp.routers.dns.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.dns.entrypoints=dns"
      - "traefik.tcp.routers.dns.service=pihole"

      # recieves traffic from both the TLS and non-TLS traefik routers
      - "traefik.tcp.services.pihole.loadbalancer.server.port=53"

      # Normal DNS coming in on 53 UDP
      - "traefik.udp.routers.udpdns.entrypoints=dns-udp"
      - "traefik.udp.routers.udpdns.service=pihole"
      - "traefik.udp.services.pihole.loadbalancer.server.port=53"
volumes:
  pihole_configs:

networks:
  reverse-proxy:
    external: true
1 Answers

I am trying to understand what you are attempting to do here. Do you want to use Traefik as a proxy for Pihole DNS resolution attempts? I don't think that works out well, because you are using Traefik as a reverse proxy for your services.

Traefik handles incoming connections from the outside and sends back the corresponding answers. In case Pihole on its own decides to do a lookup it never goes through Traefik, as far as I know. You got to configure a separate service for secured lookups, like stubby or cloudflared. I recommend cloudflared (it does encrypted lookups via DoH), as there is an official guide in their documentation.

Apart from that, the DNS field inside the docker compose file is for the docker container environment. But that's not where you configure the DNS address for Pihole lookups, you have to do that inside the Pihole application settings.

Related