Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FQDNs with trailing period/dot resulting in SSL Error #9157

Closed
2 tasks done
firstdorsal opened this issue Jul 2, 2022 · 5 comments
Closed
2 tasks done

FQDNs with trailing period/dot resulting in SSL Error #9157

firstdorsal opened this issue Jul 2, 2022 · 5 comments

Comments

@firstdorsal
Copy link

Welcome!

  • Yes, I've searched similar issues on GitHub and didn't find any.
  • Yes, I've searched similar issues on the Traefik community forum and didn't find any.

What did you do?

I tried setting up a router with a rule matching a trailing dot/period:

traefik.enable: "true"
traefik.http.routers.shields.tls.certresolver: "default"
traefik.http.routers.shields.tls.domains[0].main: "y.gy"
traefik.http.routers.shields.tls.domains[0].sans: "*.y.gy"
traefik.http.routers.shields.rule: "Host(`ico.y.gy.`)"
traefik.http.routers.shields.tls: "true"
traefik.http.routers.shields.entrypoints: "websecure"
traefik.http.services.shields.loadbalancer.server.port: "80"
traefik.docker.network: rp

What did you see instead?

image

paul@blackbox ~> openssl s_client ico.y.gy.:443
CONNECTED(00000003)
Can't use SSL_get_servername
depth=0 CN = TRAEFIK DEFAULT CERT
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = TRAEFIK DEFAULT CERT
verify return:1
---
Certificate chain
 0 s:CN = TRAEFIK DEFAULT CERT
   i:CN = TRAEFIK DEFAULT CERT
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIDXjCCAkagAwIBAgIRALoMUJKEKAuUliXzfwSmi40wDQYJKoZIhvcNAQELBQAw
HzEdMBsGA1UEAxMUVFJBRUZJSyBERUZBVUxUIENFUlQwHhcNMjIwNzAyMTYzMzQ4
WhcNMjMwNzAyMTYzMzQ4WjAfMR0wGwYDVQQDExRUUkFFRklLIERFRkFVTFQgQ0VS
VDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMymN+99XuHO96Lt/Q3K
xWJy7Y8NFQSs/rVgWPsIvf44wtSPurf2/sYzduu+xfb+kY27LEtXOGJM+pbYsEti
fbKg7maFf/mssdj4fQrFR75UsibRnXcPDsgUPCs98lyYB1nEALf5xvlFsdMjFfEt
KAAFcW8tgTjQq52vjB3XuRw9XOWU4JVeyIkixGs6FrGDjiYEqBaE8rslCqlmcQ9+
6/WnapGDMKKCfPXZe8XOxSDFD3oszLOuyKFw4u7K2ahFzDG1eamg5kPm61+4jLqy
6ah6KszuvvOaV37RX5cY2oS4G4XWY+6v8/xM8TmJa/EXxJlcuP3uKiiwQblNTAAm
NNMCAwEAAaOBlDCBkTAOBgNVHQ8BAf8EBAMCA7gwEwYDVR0lBAwwCgYIKwYBBQUH
AwEwDAYDVR0TAQH/BAIwADBcBgNVHREEVTBTglEzNTYyMjM3YzBkNTBmNWI2OWQ3
NmIwMTM4YzVlYWVkOS40OGRmYTA0MzhjMzc2NmU5ZGY2ZDJlYWQ1Njc0NmU3Yy50
cmFlZmlrLmRlZmF1bHQwDQYJKoZIhvcNAQELBQADggEBAH+Cy2dpy1nzK/nMjOLy
l5wdeDWqqQ7RcAHVtlGdPYrTVAS3shnr/8CrLX+Y1SLRsHW1yhAbq/LfY0SuXlTC
oazWkXYw17ezx5yAu4KIYDGwiuwXNaUC9jPcCY7XVLzR1nmlepqW/bIApRKs6oPO
ZyAdJbJ8PI/fOgGt2ATB37bC9KlbkTDSxbLhHvC1GeBHUFF0ykPAmaS2NzMjZJR6
0iApxlzVQMFT6f4i7JOpDaAaRKhhMjx2AiSL+EIrK6jDx5HOn8Fp7QzjgwcWXRc7
IDyN6nVEmHxzqxClrr7cG30xogvCwuk07z+g8y9YEzb0WYx736DVJTcCc5jlytvx
6nE=
-----END CERTIFICATE-----
subject=CN = TRAEFIK DEFAULT CERT

issuer=CN = TRAEFIK DEFAULT CERT

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 1406 bytes and written 357 bytes
Verification error: self signed certificate
---
New, TLSv1.3, Cipher is TLS_AES_128_GCM_SHA256
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 18 (self signed certificate)
---
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_128_GCM_SHA256
    Session-ID: 8B0E606CEEFF21AE09801EFFD9CE36410BDB9C52B9AC03DD1B88744AC606E4BB
    Session-ID-ctx: 
    Resumption PSK: 59E1201620AF1D8169F8EB42D1708F458773F80C8C0EB85FE1863E3489E35AC8
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 604800 (seconds)
    TLS session ticket:
    0000 - 11 b2 6e 0d b4 a6 2e 8c-e1 08 7f b7 b2 a6 e8 06   ..n.............
    0010 - fb 75 c1 a3 17 63 a9 2e-af 3d d3 ef 0d fc 99 53   .u...c...=.....S
    0020 - a1 aa ed a7 dd 7b 45 9a-eb fa 0b f8 79 1b 34 66   .....{E.....y.4f
    0030 - 8f ac a5 58 c8 4a 54 ee-28 7e 1d 43 63 f2 a0 48   ...X.JT.(~.Cc..H
    0040 - 9e de 77 f6 98 7d a9 ae-68 a9 46 b5 0f 2b 5a 84   ..w..}..h.F..+Z.
    0050 - 81 64 63 51 bc ae e6 c5-bc 43 4f 44 23 8f d6 41   .dcQ.....COD#..A
    0060 - 6b 17 aa 64 1e 3e e4 75-45 8a 28 ee 76 88 25 98   k..d.>.uE.(.v.%.
    0070 - a1                                                .

    Start Time: 1656779631
    Timeout   : 7200 (sec)
    Verify return code: 18 (self signed certificate)
    Extended master secret: no
    Max Early Data: 0
---
read R BLOCK

HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
Connection: close

400 Bad Requestclosed

What version of Traefik are you using?

traefik:v2.7.0

What is your environment & configuration?

See: #4622 and #4011

I know that it is possible to set another default cert but I suppose this should also just work by hostname matching.

If applicable, please paste the log output in DEBUG level

time="2022-07-02T16:28:24Z" level=warning msg="FQDN detected, please remove the trailing dot: ico.y.gy." routerName=shields@docker rule="Host(ico.y.gy.)" providerName=default.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory"

@jakubhajek
Copy link
Contributor

Hi @firstdorsal

Thanks for using Traefik and opening the issue here.

We have discussed that topic internally and seems that it works as expected. As you have already noticed there is a warning in the log file saying that the trailing dot in the Host matching rule should be removed. Once the dot will be removed Traefik will automatically obtain a valid certificate for the given domain and present it accordingly.

In your case, because there is no certificate for the given domain, Traefik presented the default certificate - this is also expected behavior.

@firstdorsal
Copy link
Author

firstdorsal commented Jul 8, 2022

Like said here #4622 (comment) it should be possible (according to RFC) to use an absolute domain name. This works fine with nginx but not with traefik :/

It had been fixed(#4763) but is now not working anymore.

@jakubhajek
Copy link
Contributor

Thanks for your comment, we will have to look at that issue and consider how we can address that aspect.

@rtribotte
Copy link
Member

rtribotte commented Jul 11, 2022

Hello @firstdorsal,

Like said here #4622 (comment) it should be possible (according to RFC) to use an absolute domain name. This works fine with nginx but not with traefik :/

The certificate lookup (during the client hello) is based on the TLS SNI and not the Host header.

It had been fixed(#4763) but is now not working anymore.

The host matcher is able to match against a trailing dot FQDN.
It seems that the issue you are facing is due to the certificate lookup that cannot find a valid certificate for the FQDN ico.y.gy. and the TLS handshake fails.

time="2022-07-02T16:28:24Z" level=warning msg="FQDN detected, please remove the trailing dot: ico.y.gy." routerName=shields@docker rule="Host(ico.y.gy.)" providerName=default.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory"

This debug log indicates that the FQDN form is not allowed, which means that the certificate resolver will not resolve a certificate for the domain with the trailing dot.

This is why no certificate in the TLS store is matching the FQDN ico.y.gy., and causes the TLS handshake to fail.

@rtribotte
Copy link
Member

It had been fixed(#4763) but is now not working anymore.

Just to be sure, did you experienced a change in the behavior of the host matcher? And if so, between which versions of Traefik?

In any case, I was wrong in my previous message:

In your case, the openssl command is establishing the TLS connection with the default servername (which seems to be the peer IP), which leads to a handshake done with the default certificate.

The correct command should be: openssl s_client -connect 127.0.0.1:443 -servername ico.y.gy..
However this will fail as well, and you should see this kind of error in the Traefik logs: DEBU[2022-07-11T17:20:55+02:00] http: TLS handshake error from 127.0.0.1:62080: local error: tls: unexpected message.

And here is the explanation why: after taking a closer look, it is not possible to use an FQDN as the server name during a TLS handshake, as mentioned in RFC6066:

"HostName" contains the fully qualified DNS hostname of the server,
as understood by the client. The hostname is represented as a byte
string using ASCII encoding without a trailing dot. This allows the
support of internationalized domain names through the use of A-labels
defined in [RFC5890]. DNS hostnames are case-insensitive. The
algorithm to compare hostnames is described in [RFC5890], Section
2.3.2.4.

And as this is enforced in the golang stdlib, which Traefik relies on to establish a TLS connection, this kind of failure during the TLS handshake is to be expected if a FQDN servername is used.

But, to conclude, FQDNs are therefore not possible to use with TLS.

@traefik traefik locked and limited conversation to collaborators Aug 11, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants