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

Wrong SSL Certificate when HTTP-testing IPv6 host behind a Reverse Proxy #3545

Closed
2 tasks done
SkwalExe opened this issue Aug 8, 2023 · 9 comments
Closed
2 tasks done
Labels
bug Something isn't working

Comments

@SkwalExe
Copy link

SkwalExe commented Aug 8, 2023

⚠️ Please verify that this bug has NOT been raised before.

  • I checked and didn't find similar issue

🛡️ Security Policy

Description

Sorry for my bad english

I want to have a HTTP monitor that uses IPV6 only, so I set the URL like this:

image

and to avoid that the web server rejects the request because we are sending it to the ip directly I set the Host Header manually

image

👟 Reproduction steps

  • put the ipv6 address in the url, and set the Host header manually
  • your DNS A record for the manually set Host header must point to a reverse proxy and the AAAA record must point to the actual web server

👀 Expected behavior

The request should be sent over IPv6 to the address in the URL field

😓 Actual Behavior

Uptime Kuma makes a DNS request for the A record of the manually set Host header then sends the request over ipv4 to the reverse proxy

I can see this with Wireshark, in the reverse proxy logs and also, the SSL certificate is that of the reverse proxy and not that of the actual web server.

🐻 Uptime-Kuma Version

1.23.0-beta.1

💻 Operating System and Arch

Ubuntu 22.04 x64

🌐 Browser

Browser doesn't matter

🐋 Docker Version

Not using docker

🟩 NodeJS Version

v16.20.0

📝 Relevant log output

No response


Having a "Force IPv6" option or different HTTP monitors for ipv4/6 would be a great idea so that people who want to monitor ipv6 only hosts don't have to do this weird trick

image

@SkwalExe SkwalExe added the bug Something isn't working label Aug 8, 2023
@chakflying
Copy link
Collaborator

Cannot reproduce. When monitor url is set to an IPv6 address from www.google.com, it does not make a DNS request, as expected. Instead, I see a TCP request to the IPv6 address directly.

Maybe you can show us a reproducible example using www.google.com. They obviously have both A and AAAA record on the same hostname.

  • Windows 11 x64
  • node v18.16.0

@SkwalExe
Copy link
Author

SkwalExe commented Aug 8, 2023

To reproduce :

  • Reverse proxy : 82.66.235.227
  • Web server : [2a01:e0a:c99:6170:3092:51ff:fea8:89d3]
  • Desired "Host" header value : cloud.skwal.net

You're right. I just noticed that the request going to the reverse proxy is not actually caused by the HTTP response check. I could also confirm that uptime kuma was sending the HTTP requests over IPv6 by checking the web server's logs. I think it is caused by the "Certificate expiry" feature :

image

First of all, I am sure that the certificate shown by clicking on 90 days is the one of the reverse proxy, while it should be the one of the web server. You can compare the SHA1 fingerprint.

image

# Getting the reverse proxy's certificate's SHA1 fingerprint
$ openssl s_client -connect 82.66.235.227:443 < /dev/null 2>/dev/null | openssl x509 -fingerprint -sha1 -noout -in /dev/stdin
sha1 Fingerprint=F4:1C:69:54:31:72:07:8A:34:B1:9C:C5:5F:6B:D6:9A:0B:61:33:E8

# Matches with the fingerprint shown in uptime kuma
# Getting the web server's certificate's SHA1 fingerprint
$ openssl s_client -connect [2a01:e0a:c99:6170:3092:51ff:fea8:89d3]:443 < /dev/null 2>/dev/null | openssl x509 -fingerprint -sha1 -noout -in /dev/stdin
sha1 Fingerprint=09:34:18:34:A4:DA:CC:85:8E:86:E5:E3:C2:CA:B8:EC:F0:04:98:38

# This should be the fingerprint of the certificate shown in uptime kuma

To get the certificate associated with the "Host" header, uptime kuma must send a DNS request for the domain in the header. This explains why I though that the request was sent to the reverse proxy.

So now we have a different issue : the certificate shown is the one of the "Host" header while it should be the one returned by sending a request to the IPv6 address.

Should I open a new issue?

Also, sorry for my bad english.

@chakflying
Copy link
Collaborator

chakflying commented Aug 8, 2023

image

Have you tried Creating a new monitor to test this? Note that currently the Certificate Info does not update when the latest heartbeat result is "Down". This can lead to stale info about the certificate.

@SkwalExe
Copy link
Author

SkwalExe commented Aug 8, 2023

Sorry, I didn't mention it but, the reverse proxy always return a certificate for skwal.net AND *.skwal.net, since it must process request for all my servers.

I will try to create a new monitor and see if I still have the problem

@SkwalExe
Copy link
Author

SkwalExe commented Aug 8, 2023

I created a new monitor that shows "up", but its still the wrong certificate... Are you using the latest beta.1 ?

Here is the monitor configuration, maybe I have made an error somewhere.

image

image

@SkwalExe
Copy link
Author

SkwalExe commented Aug 8, 2023

@chakflying I reproduced the configuration on another computer, on another nework and I got the same results as before. Maybe you cannot reproduce the issue because you aren't running the same configuration as me. I can see requests coming from extern uptime kuma instances in my reverse proxy's logs and the user agent show that the version 1.21.3 while I have the issue on the latest beta .1 version (as I said in the first message). Also the fact that I can see requests in my REVERSE PROXY's logs means that the issue is not reproduced correctly OR uptime kuma doesn't request the IPv6 address directly and still uses some kind of IPv4.

image

I don't know if I see YOUR requests or someone else is trying to reproduce the issue. I can see 4 uptime kuma instances sending requests right now to the reverse proxy.

@chakflying
Copy link
Collaborator

chakflying commented Aug 8, 2023

You are giving me a layered cake here. Lets break this down. When I query DNS on your domain cloud.skwal.net, I get these results:

A: 82.66.235.227 (your proxy)
AAAA: 2a01:e0a:c99:6170:3092:51ff:fea8:89d3 (your web server!)

So if a client chooses to use IPv6, the client will bypass your proxy.

Now when you send request to your server directly:

curl -H "Host: cloud.skwal.net" -k --verbose https://[2a01:e0a:c99:6170:3092:51ff:fea8:89d3]/

The server respond with a 302 redirect with location https://cloud.skwal.net/login. By default the monitor follows redirects, so when this redirect is followed, your reverse proxy is reached, and the corresponding certificate is displayed.

The difference in results between us is likely because of node v18 vs v16. Starting from node v17, the DNS lookup of node would respect the priority from the resolver, whereas before it would always prefer IPv4.

@SkwalExe
Copy link
Author

SkwalExe commented Aug 8, 2023

Hmmm... So I shouldn't see the RP's certificate if I set the URL to https://[2a01:e0a:c99:6170:3092:51ff:fea8:89d3]/login since there will not be any redirects.

$ curl -H "Host: cloud.skwal.net" -I -k https://[2a01:e0a:c99:6170:3092:51ff:fea8:89d3]/login
HTTP/2 200 
server: nginx/1.18.0 (Ubuntu)
date: Tue, 08 Aug 2023 19:35:33 GMT
content-type: text/html; charset=UTF-8
content-length: 14466
cache-control: no-cache, no-store, must-revalidate
content-security-policy: default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self' wss://cloud.skwal.net;media-src 'self';frame-src 'self';frame-ancestors 'self';form-action 'self'
expires: Thu, 19 Nov 1981 08:52:00 GMT
feature-policy: autoplay 'self';camera 'none';fullscreen 'self';geolocation 'none';microphone 'none';payment 'none'
pragma: no-cache
referrer-policy: no-referrer
set-cookie: oc_sessionPassphrase=y3ZOZyJa8hjppw6X6GyjoEbdPddB0WgyXIT2XeUbMOsW2mTHw%2Bm%2B7P0Jg7hIsdRgRW2go4MAjOr77QC1KvunmDJPHjMP5GXf8zuMR7yUpRdJslkkQBzMxFArY%2BbQ0cSs; path=/; secure; HttpOnly; SameSite=Lax
set-cookie: __Host-nc_sameSiteCookielax=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=lax
set-cookie: __Host-nc_sameSiteCookiestrict=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=strict
set-cookie: oc4ybrfuukyf=858e62e3f2ebb2b1a20cbbe1d4025731; path=/; secure; HttpOnly; SameSite=Lax
strict-transport-security: max-age=31536000;
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-permitted-cross-domain-policies: none
x-powered-by: PHP/8.1.21
x-request-id: PCsz9frtyIqMK8zvqsm6
x-robots-tag: noindex, nofollow
x-xss-protection: 1; mode=block

Let me try...

@SkwalExe
Copy link
Author

SkwalExe commented Aug 8, 2023

This fixed the issue. I am really impressed that you could figure this out. Thanks a lot for your help!

image

Shouldn't this "issue" be documented somewhere, like a short message on the readme/wiki? I will close and rename the issue in order to make the troubleshooting process of people encountering the same problem easier.

Also, a "force IPv6" option should be added to prevent the need of manipulating the Headers manually when testing a server over IPv6. Maybe I'll do a pull request one day.

@SkwalExe SkwalExe closed this as completed Aug 8, 2023
@SkwalExe SkwalExe changed the title IPv6 address in URL field not used when Host header is manually set Wrong SSL Certificate when HTTP-testing IPv6 host behind a Reverse Proxy Aug 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants