HTTPS external traffic to request HTTP internal traffic

Hi all, this is probably a very basic question, but I couldn't find a clear answer after I've tried a few things.

Context

I am basically trying to migrate from nginx to traefik as my reverse proxy. I've set up the first service and it works well, when I access the http scheme. However, when I access with https, traefik returns 404 page not found. For what I've read this might be because traefik is sending https traffic to the https scheme on the docker container, but this service only supports http.

Questions

  • How can I indicate traefik https (websecure) to request the docker container on the http scheme while using its own certificates?

Set up

traefik/docker-compose.yaml

version: '3'
services:
  reverse-proxy:
    container_name: traefik
    image: traefik:latest
    restart: unless-stopped
    environment:
      - TZ=Asia/Singapore
    network_mode: host
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./data/traefik.yml:/etc/traefik/traefik.yml
      - ./ssl:/ssl
      - ./logs:/logs

(note: /ssl contains my certificates that I generate externally)

/traefik/data/traefik.yml

accessLog:
  filePath: "/logs/access.log"

api:
  dashboard: true
  insecure: true

entryPoints:
  traefik:
    address: ":9880"
  web:
    address: ":998"
  websecure:
    address: ":999"

global:
  sendAnonymousUsage: false

http:
  serversTransport:
    insecureSkipVerify: false

log:
  filePath: "/logs/traefik.log"

providers:
  docker:
    exposedByDefault: false
    useBindPortIp: true

tls:
  certificates:
    - certFile: /ssl/fullchain.pem
      keyFile: /ssl/privkey.pem

Sample service: bazarr/docker-compose.yaml

version: "2.1"

services:
  bazarr:
    image: lscr.io/linuxserver/bazarr
    container_name: bazarr
    restart: unless-stopped
    ports:
      - 9867:6767
    environment:
      - TZ=Asia/Singapore
      - PUID=1000
      - PGID=1000
    volumes:
      - ./config:/config
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.bazarr-internal.rule=Host(`bazarr.mydomain.com`)"

Issue

Accessing http://bazarr.mydomain.com:998 works fine. Accessing https://bazarr.mydomain.com:999 throws 404. bazarr does not have SSL configured, I want to leverage traefik to do this. The certificates also didn't seem to load properly, so maybe it could be related.

Additional Context (nginx config)

For context, this is how my nginx config looks like for this service (i.e. what I am trying to replicate):

server {
    server_name bazarr.mydomain.com;

    listen              80 ssl http2;
    listen              [::]:80 ssl http2;
    listen              443 ssl http2;
    listen              [::]:443 ssl http2;

    ssl_certificate     /etc/ssl/private/fullchain.pem;
    ssl_certificate_key /etc/ssl/private/privkey.pem;

    location / {
        proxy_pass http://bazarr.mydomain.com:9867;

        proxy_ssl_server_name on;
        proxy_http_version                 1.1;
        proxy_cache_bypass                 $http_upgrade;
        proxy_set_header Host              $host:$server_port;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host  $http_host;
        proxy_set_header X-Forwarded-Port  $server_port;
        proxy_set_header Origin '';
        proxy_set_header Upgrade           $http_upgrade;
        proxy_set_header Connection        "upgrade";
        proxy_headers_hash_max_size 512;
        proxy_headers_hash_bucket_size 128;
        proxy_connect_timeout              60s;
        proxy_send_timeout                 60s;
        proxy_read_timeout                 60s;
    }
}

Configure your custom TLS certs in a dynamic config file (docs), load using provider.file in static config traefik.yml.

Enable basic TLS on entrypoint (docs) or on router (docs), just set it to true (command/label) or {} (yml).

Then Traefik will by default "terminate TLS" and forward requests in plain http to the service.

2 Likes

Thanks @bluepuma77 - your pointers were quite helpful. Adding http: tls: {} to the entryPoints config did the trick to get the https call the service http endpoint.

However, the certificate loaded is still traefik's default one instead of the one I am specifying. This is likely because the first point is still missing, but I am trying to take a slightly different route. I was thinking of just using default certificates for the whole domain. However, I can't make it work.

When I add:

entryPoints:
  https:
    address: ":999"
    http:
      tls: {}

I can see the services using https entryPoint using tls with options default. However, I haven't managed to assign the certificates file to it. My tries have been:

tls:
  stores:
    default:
      defaultCertificate:
        certFile: /ssl/fullchain.pem
        keyFile: /ssl/privkey.pem
tls:
  certificates:
    - certFile: /ssl/fullchain.pem
      keyFile: /ssl/privkey.pem

Note: I am certain the files exist on /ssl/ and I have seen this post confirming I need fullchain.pem. All code above is on my /etc/traefik/traefik.yml file.

1 Like

As stated before, tls.certificates can not be in static config traefik.yml, which contains entrypoints and providers. It needs to be dynamic config, loaded from a separate file.

1 Like

Thank you! I went back to read about static vs dynamic config and I was able to fix it. Thanks again for the pointer.

For anyone reading this in the future and looking for the fix. The suggestions here are what you need to follow.

There are multiple ways to approach those instructions. This is how I solved it:

  1. Create one config for static and another file for dynamic configuration and add them to docker-compose.yaml
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./data/traefik.yml:/etc/traefik/traefik.yml  # Static configuration.
      - ./data/config:/etc/traefik/config  # Dynamic configuration.
      - ./ssl:/ssl
      - ./logs:/logs
  1. On the static config (/etc/traefik/traefik.yaml) under entryPoints on https, add the tls option:
entryPoints:
  https:
    address: ":999"
    http:
      tls: {}
  1. On the static config, under providers add an additional provider for loading the dynamic config files. In my case, I decided to place this under "/etc/traefik/config" but you can select a different path.
providers:
  file:
    directory: "/etc/traefik/config"
    watch: true
  1. On the dynamic config file (any YAML file under "/etc/traefik/config"), add the TLS configuration:
tls:
  certificates:
    - certFile: /ssl/fullchain.pem
      keyFile: /ssl/privkey.pem
  1. On the docker service (docker-compose.yaml), which is the provider I use for my services, I am using the following labels:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.service-name.rule=Host(`subdomain.domain.com`)"
      - "traefik.http.routers.service-name.entrypoints=https"

If I understand correctly, this adds the service to the entryPoints https which has https enabled with the default tls and the default tls has been configured on the dynamic config to the /ssl/fullchain.pem and /ssl/privkey.pem which is what you may have obtained from your own certificate provider.

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.