traefik / traefik

The Cloud Native Application Proxy
https://traefik.io
MIT License
51.05k stars 5.08k forks source link

GnuTLS error #8038

Closed viggy96 closed 3 years ago

viggy96 commented 3 years ago

Do you want to request a feature or report a bug?

Bug

What did you do?

Use wget on webpage. However, using curl works just fine. And all served webpages work fine in the browser as well. This issue affects all client side applications that depend on GnuTLS.

What did you expect to see?

wget saving index.html.

What did you see instead?

--2021-04-06 10:50:43--  https://jellyfin.viggy96.me/
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving jellyfin.viggy96.me (jellyfin.viggy96.me)... 10.0.0.1
Connecting to jellyfin.viggy96.me (jellyfin.viggy96.me)|10.0.0.1|:443... connected.
GnuTLS: A TLS fatal alert has been received.
GnuTLS: received alert [47]: Illegal parameter
Unable to establish SSL connection.

Output of traefik version: 2.4.8

What is your environment & configuration (arguments, toml, provider, platform, ...)?

traefik.yaml

api:
   dashboard: true
   debug: true

 log:
   level: INFO

 accessLog: {}

 entryPoints:
   web:
     address: ":80"
     http:
       redirections:
         entryPoint:
           to: websecure
           scheme: https
   websecure:
     address: ":443"

 providers:
   docker:
     endpoint: "unix:///var/run/docker.sock"
     exposedByDefault: false
   file:
     filename: "/etc/traefik/config.yaml"
     watch: true

 certificatesResolvers:
   letsencrypt:
     acme:
       email: "admin@viggy96.me"
       storage: "/etc/traefik/acme.json"
       tlsChallenge: {}

config.yaml

http:
  middlewares:
    default-headers:
      headers:
        frameDeny: true
        sslRedirect: true
        browserXssFilter: true
        contentTypeNosniff: true
        customFrameOptionsValue: "SAMEORIGIN"
        stsSeconds: 15552000
        forceSTSHeader: true
        stsIncludeSubdomains: true
        stsPreload: true

    local-only:
      ipWhiteList:
        sourceRange:
        - "192.168.0.0/16"
        - "172.16.0.0/12"
        - "10.0.0.0/8"

    private:
      chain:
        middlewares:
          - default-headers
          - local-only

    secure:
      chain:
        middlewares:
          - default-headers

tls:
  options:
    default:
      preferServerCipherSuites: true
      minVersion: VersionTLS12
      sniStrict: true
      curvePreferences:
        - "CurveP521"
        - "CurveP384"
      cipherSuites:
        - "TLS_AES_256_GCM_SHA384"
        - "TLS_CHACHA20_POLY1305_SHA256"
          #- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
          #- "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
        - "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
        - "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
viggy96 commented 3 years ago

I have this issue with several applications, not just Jellyfin, which is mentioned above. Nextcloud for example exhibits the same issue.

viggy96 commented 3 years ago

Jellyfin has the following config in its docker-compose.yaml file:

jellyfin:
     image: jellyfin/jellyfin:latest
     restart: always
     environment:
       - UID=33
       - GID=33
       - TZ=America/New_York
     devices:
       - /dev/dri
     volumes:
       - /tmp/jellyfin:/transcodes
       - /tank/container_data/jellyfin_config:/config
       - /tank/container_data/jellyfin_cache:/cache
       - /tank/cloud/videos/:/media/video
       - /tank/cloud/music:/media/music
     expose:
       - 8096
     ports:
       - 1900:1900/udp
     labels:
       - "traefik.enable=true"
       - "traefik.http.services.jellyfin.loadbalancer.server.port=8096"
       - "traefik.http.routers.jellyfin.rule=Host(`jellyfin.viggy96.me`)"
       - "traefik.http.routers.jellyfin.middlewares=secure@file"
       - "traefik.http.routers.jellyfin.tls=true"
       - "traefik.http.routers.jellyfin.tls.certresolver=letsencrypt"
jakubhajek commented 3 years ago

Hello @viggy96

Thanks for using Traefik Proxy and reporting the issue.

I've just tried to reproduce the issue and in order to the, I've built wget with the latest stable GnuTLS 3.6.15 and all other dependencies to have the wget binary linked with the expected libraries.

root@c1:/tmp/wget-1.21# /tmp/usr/bin/wget --version
GNU Wget 1.21 built on linux-gnu.

-cares +digest -gpgme +https +ipv6 +iri +large-file -metalink +nls
+ntlm +opie -psl +ssl/gnutls

Wgetrc:
    /tmp/usr/etc/wgetrc (system)
Locale:
    /tmp/usr/share/locale
Compile:
    gcc -DHAVE_CONFIG_H -DSYSTEM_WGETRC="/tmp/usr/etc/wgetrc"
    -DLOCALEDIR="/tmp/usr/share/locale" -I. -I../lib -I../lib
    -I/tmp/usr/include -DNDEBUG -DNO_SSLv2 -D_FILE_OFFSET_BITS=64 -g
    -Wall
Link:
    gcc -DNDEBUG -DNO_SSLv2 -D_FILE_OFFSET_BITS=64 -g -Wall -lnettle
    /tmp/usr/lib/libgnutls.so -L/tmp/usr/lib -lp11-kit -lidn2
    /tmp/usr/lib/libnettle.so -lhogweed /tmp/usr/lib/libgmp.so
    -Wl,-rpath -Wl,/tmp/usr/lib ftp-opie.o gnutls.o http-ntlm.o
    ../lib/libgnu.a /tmp/usr/lib/libunistring.so -Wl,-rpath
    -Wl,/tmp/usr/lib

Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
<http://www.gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Originally written by Hrvoje Niksic <hniksic@xemacs.org>.
Please send bug reports and questions to <bug-wget@gnu.org>.

I used my custom wget to get your website, here is the result:

root@c1:/tmp/wget-1.21# /tmp/usr/bin/wget --server-response --spider https://jellyfin.viggy96.me/
Spider mode enabled. Check if remote file exists.
--2021-04-07 14:01:04--  https://jellyfin.viggy96.me/
Resolving jellyfin.viggy96.me (jellyfin.viggy96.me)... 107.15.234.47
Connecting to jellyfin.viggy96.me (jellyfin.viggy96.me)|107.15.234.47|:443... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 302 Found
  Date: Wed, 07 Apr 2021 12:01:03 GMT
  Location: /web/index.html
  Server: Kestrel
  Strict-Transport-Security: max-age=15552000; includeSubDomains; preload
  X-Content-Type-Options: nosniff
  X-Frame-Options: SAMEORIGIN
  X-Xss-Protection: 1; mode=block
Location: /web/index.html [following]
Spider mode enabled. Check if remote file exists.
--2021-04-07 14:01:04--  https://jellyfin.viggy96.me/web/index.html
Connecting to jellyfin.viggy96.me (jellyfin.viggy96.me)|107.15.234.47|:443... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 200 OK
  Accept-Ranges: bytes
  Content-Length: 6868
  Content-Type: text/html
  Date: Wed, 07 Apr 2021 12:01:04 GMT
  Etag: "1d71eaa95f720d4"
  Last-Modified: Sun, 21 Mar 2021 23:33:24 GMT
  Server: Kestrel
  Strict-Transport-Security: max-age=15552000; includeSubDomains; preload
  X-Content-Type-Options: nosniff
  X-Frame-Options: SAMEORIGIN
  X-Response-Time-Ms: 0
  X-Xss-Protection: 1; mode=block
Length: 6868 (6.7K) [text/html]
Remote file exists and could contain further links,
but recursion is disabled -- not retrieving.

What exact wget version do you use?

viggy96 commented 3 years ago

wget version 1.21.1 GnuTLS version 3.7.1

I'm using Manjaro

jakubhajek commented 3 years ago

--2021-04-06 10:50:43-- https://jellyfin.viggy96.me/ Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt' Resolving jellyfin.viggy96.me (jellyfin.viggy96.me)... 10.0.0.1 Connecting to jellyfin.viggy96.me (jellyfin.viggy96.me)|10.0.0.1|:443... connected.

Can you please make sure that the request hits the Traefik instances? I noticed from the log above the IP address 10.0.0.1 - seems that it is a local network. As I mentioned in the previous answer I was able to reach your website correctly using WGET.

mrpaulblack commented 3 years ago

Hi, I am running the same GnuTLS and wget version as viggy96 on manjaro and I am running into the same problem with my public traefik instance (this requesst hit the traefik instance for sure):

$ wget https://www.paulgo.io
--2021-04-07 23:37:20--  https://www.paulgo.io/
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving www.paulgo.io (www.paulgo.io)... 51.195.103.237
Connecting to www.paulgo.io (www.paulgo.io)|51.195.103.237|:443... connected.
GnuTLS: A TLS fatal alert has been received.
GnuTLS: received alert [47]: Illegal parameter
Unable to establish SSL connection.
viggy96 commented 3 years ago

@jakubhajek The request is hitting the traefik instance, I just have a entry in my /etc/hosts file to force my desktop to use the 10GbE port that is directly connected to my server. I see the wget request in the traefik access log. So its definitely hitting the traefik instance.

I tried wget on my laptop with Ubuntu WSL, and it works fine. This might be some quirk of the GnuTLS/wget packages in the Arch/Manjaro repositories.

jakubhajek commented 3 years ago

Hello @viggy96 @MrPaulBlack, I was able to replicate the issue using the same version of Wget and GnuTLS on Manjaro. Let me investigate that issue deeper.

jakubhajek commented 3 years ago

Hello @viggy96 and @MrPaulBlack

We did a deep investigation of that issue together with my teammates and we would love to say that the issue is related to the TLS Handshake in TLS 1.3 and its implementation on a client-side.

The first connection initiated by a client sends the Clienthello as the first message. The message is also sent if the server responded with HelloRetryRequest and in that case, the client must send the same ClientHello with the same "session_id". In that fact the "session id" has to send the same, otherwise, the connection will be terminated.  During our tests, we have noticed exactly that behavior that "session-id" was changed and due to that the connection was terminated. As a client, we used Wget built with GnuTLS 3.7.1.

Thank you,