Improving the SSL rating

Hello,

I am trying to get rid of some cipher suites but still, the server presents the default certificate and permits SSLv3 (+ other deprecated protocols) despite the config below:

traefik.toml:

[...]
[http.middlewares]
  [http.middlewares.https-redirect.redirectscheme]
    scheme = "https"
[...]
[tls]
  [tls.options]
    [tls.options.default]
#    minVersion = "VersionTLS12"
      sniStrict = true
      cipherSuites = [
#      "TLS_RSA_WITH_RC4_128_SHA",
#      "TLS_RSA_WITH_3DES_EDE_CBC_SHA", # TLS 1.[0-2], SSL v3
#      "TLS_RSA_WITH_AES_128_CBC_SHA",  # TLS 1.[0-2], SSL v3
#      "TLS_RSA_WITH_AES_256_CBC_SHA",  # TLS 1.[0-2], SSL v3
#      "TLS_RSA_WITH_AES_128_CBC_SHA256",
#      "TLS_RSA_WITH_AES_128_GCM_SHA256", # TLS 1.2
#      "TLS_RSA_WITH_AES_256_GCM_SHA384", # TLS 1.2
#      "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA",
#      "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
#      "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
#      "TLS_ECDHE_RSA_WITH_RC4_128_SHA",
#      "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",# TLS 1.[0-2]
#      "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", # TLS 1.[0-2]
#      "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", # TLS 1.[0-2]
        "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
        "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
        "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", # TLS 1.2
        "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
        "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", # TLS 1.2
        "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
        "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
        "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",

# TLS 1.3 cipher suites.
        "TLS_AES_128_GCM_SHA256",
        "TLS_AES_256_GCM_SHA384",
        "TLS_CHACHA20_POLY1305_SHA256",

# TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator that the client is doing version fallback. See RFC 7507.
        "TLS_FALLBACK_SCSV"

docker-compose.yml:

version: '3.6'

services:
  traefik:
    container_name: traefik
    image: traefik:v2.0-alpine
    restart: always
    ports:
      - "80:80"
      - "443:443"
#      - "9020:9020"
    networks:
      - "web"
    labels:
      - "traefik.enable=false"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "./traefik.toml:/traefik.toml:ro"
      - "./acme.json:/acme.json"
      - "./traefik.log:/traefik.log"
      - "./traefik_log.txt:/traefik_log.txt"
      - "/etc/localtime:/etc/localtime:ro"

  webserver_X:
    container_name: webserver_X
    image: golang-webserver
    restart: always
    networks:
      - "web"
    labels:
      - "traefik.http.routers.webserver_X-insecure.rule=Host(`X`) || Host(`www.X`)"
      - "traefik.http.routers.webserver_X.rule=Host(`X`) || Host(`www.X`)"
      - "traefik.http.routers.webserver_X.tls=true"
      - "traefik.http.routers.webserver_X.tls.options=default"
      - "traefik.http.middlewares.webserver_X.Headers.FrameDeny=true"
      - "traefik.http.middlewares.webserver_X.Headers.sslredirect=true"
      - "traefik.http.routers.webserver_X.middlewares=webserver_X"
      - "traefik.http.routers.webserver_X-insecure.middlewares=webserver_X"
    volumes:
      - "./html/X/:/html:ro"

networks:
  web:
    external: true

Any idea please as well as improving the security measures?

Thank you!

Hey @Amodio,

I created a small example which archives A on SSL Labs Test and doesnt serve the ciphers anymore. Maybe you can test that out?

traefik.toml

[global]
  checkNewVersion = true
  sendAnonymousUsage = true

[entryPoints]
  [entryPoints.http]
    address = ":80"

  [entryPoints.https]
    address = ":443"

[log]
  level = "DEBUG"

[api]

[providers.docker]
  exposedByDefault = false

[tls]
  [tls.options]
    [tls.options.default]
      sniStrict = true
      cipherSuites = [
        "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256",
        "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
        "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", # TLS 1.2
        "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
        "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", # TLS 1.2
        "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
        "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
        "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
        "TLS_AES_128_GCM_SHA256",
        "TLS_AES_256_GCM_SHA384",
        "TLS_CHACHA20_POLY1305_SHA256",
        "TLS_FALLBACK_SCSV"
      ]

[acme]
  email = "some@email.com"
[acme.httpChallenge]
  entryPoint = "http"
    [[acme.domains]]
      main = "my.domain.com"

[providers.file]
[http.middlewares]
  [http.middlewares.https-redirect.redirectscheme]
    scheme = "https"

docker-compose.yml


services:
  reverse-proxy:
    image: traefik:v2.0.0-alpha8-alpine
    container_name: traefik
    command: --configfile traefik.toml
    ports:
      # The HTTP port
      - "80:80"
      # The HTTPS port
      - "443:443"
      # The Web UI (enabled by --api)
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik.toml:/etc/traefik/traefik.toml

  whoami:
    image: containous/whoami
    labels:
      - traefik.enable=true
      - traefik.http.routers.whoami.rule=Host(`my.domain.com`)
      - traefik.http.routers.whoami.tls=true
      - traefik.http.routers.whoami-redir.rule=Host(`my.domain.com`)
      - traefik.http.routers.whoami-redir.middlewares=https-redirect@file

1 Like

I finally(!!) went to A+ on SSL Labs Test and from E to A on https://securityheaders.com with:
traefik.toml

[providers.file]
  [http.middlewares]
    [http.middlewares.https-redirect.redirectscheme]
      scheme = "https"
    [http.middlewares.security-headers.headers]
      # CORS
      AccessControlAllowMethods = ["GET", "OPTIONS", "PUT"]
      AccessControlAllowOrigin = "origin-list-or-null"
      AccessControlMaxAge = 100
      #AddVaryHeader = true
      BrowserXssFilter = true
      ContentTypeNosniff = true
      ForceSTSHeader = true
      FrameDeny = true
      SSLRedirect = true
      STSIncludeSubdomains = true
      STSPreload = true
      ContentSecurityPolicy = "default-src 'self' 'unsafe-inline'"
      CustomFrameOptionsValue = "SAMEORIGIN"
      ReferrerPolicy = "same-origin"
      FeaturePolicy = "vibrate 'self'"
      STSSeconds = 315360000
[...]
[tls]
  [tls.options]
    [tls.options.default]
#    minVersion = "VersionTLS12"
      sniStrict = true
      cipherSuites = [
        "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
        "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
        "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
        "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305",
        "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305",
        "TLS_AES_128_GCM_SHA256",
        "TLS_AES_256_GCM_SHA384",
        "TLS_CHACHA20_POLY1305_SHA256",
        "TLS_FALLBACK_SCSV" # Client is doing version fallback. See RFC 7507.
    ]

docker-compose.yml

  webserver_X:
    container_name: webserver_X
    image: golang-webserver
    restart: always
    networks:
      - "web"
    labels:
      - "traefik.http.routers.webserver_X.rule=Host(`X.fr`) || Host(`www.X.fr`)"
      - "traefik.http.routers.webserver_X.tls=true"
      - "traefik.http.routers.webserver_X.tls.options=default"
      - "traefik.http.routers.webserver_X.middlewares=https-redirect@file,security-headers@file"
      - "traefik.http.routers.webserver_X-insecure.rule=Host(`X.fr`) || Host(`www.X.fr`)"
      - "traefik.http.routers.webserver_X-insecure.middlewares=https-redirect@file,security-headers@file"
    volumes:
      - "./html/X/:/html:ro"

Result is capped to A on this last test because the Feature-Policy header isn't handled by Traefik, yet.

I have also subscribed my website on https://hstspreload.org to add it in the HSTS Preloading Chrome list (by the Chromium Project).

2 Likes

I recommend to add TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 cipher to support EDGE browser.

I've taken your ideas an incorporated it in my stack to push it to A+ Trajano base Docker swarm stacks

Hi =) I tried out your options and the're amazing =) thanks for them =). I just have issues with acme certificates and strct sni checking: Its not working as traefik says: "no certoificate for this domain found" . How thit you solve that?

Kind regards