skip to Main Content

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"                                                                                                                                              
      - "[email protected]"                                                                                                                                                  
      - "--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

2

Answers


  1. 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.

    Login or Signup to reply.
  2. I had the same issue. The problem is that Traefik blocks the dot ALPN extension per default.

    docker compose logs after kdig request showed:

    tls: client requested unsupported application protocols ([dot])
    

    You can test this with openssl, too:

    $ openssl s_client -alpn dot -connect mydnshere:853   
    ...
    No ALPN negotiated
    

    You can configure ALPN extensions for traefik with Docker as follows.

    Additions to compose.yaml (rename service / router names accordingly):

    services:
      traefik:
        image: "traefik:v2.9"
    
        command: 
          # Provider Config
          - "--providers.file.filename=/etc/traefik/config.toml"
    
        volumes:
          - ./config.toml:/etc/traefik/config.toml
    
      blocky:
        image: spx01/blocky
    
        labels:
          - "traefik.tcp.routers.blocky-dns.rule=HostSNI(`my.fqn.com`)"
          - "traefik.tcp.routers.blocky-dns.tls.options=dot@file"
    

    Add config.toml

    [tls.options]
      [tls.options.dot]
        alpnProtocols = ["dot"]
    

    Here is some background about ALPN dot: https://gitlab.isc.org/isc-projects/bind9/-/issues/2794

    Update Removed the ALPN filter in the tcp router configuration as some clients do not advertise dot in ALPN (for example Android).

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search