TLS handshake error and no certificate available

This issue talks about this. And this one, too.
So it should work as we are expecting :-/

Here is a request from the Caddy log for curl --resolve dev3.edkimo.com:443:127.0.0.1 https://dev3.edkimo.com/api

2021/03/10 02:14:58.683 DEBUG http.handlers.reverse_proxy upstream roundtrip  {"upstream": "10.0.1.2:29194", "request": {"remote_addr": "127.0.0.1:56590", "proto": "HTTP/2.0", "method": "GET", "host": "dev3.foo.com", "uri": "/", "headers": {"User-Agent": ["curl/7.64.0"], "Accept": ["*/*"], "X-Forwarded-For": ["127.0.0.1"], "X-Forwarded-Proto": ["https"]}, "tls": {"resumed": false, "version": 772, "cipher_suite": 4865, "proto": "h2", "proto_mutual": true, "server_name": "dev3.foo.com"}}, "duration": 0.002078413, "headers": {"X-Xss-Protection": ["1; mode=block"], "X-Download-Options": ["noopen"], "Cache-Control": ["no-cache"], "Accept-Ranges": ["bytes"], "Keep-Alive": ["timeout=5"], "Strict-Transport-Security": ["max-age=15768000"], "X-Frame-Options": ["DENY"], "Content-Length": ["27"], "Date": ["Wed, 10 Mar 2021 02:14:58 GMT"], "Connection": ["keep-alive"], "Content-Type": ["text/html; charset=utf-8"], "X-Content-Type-Options": ["nosniff"]}, "status": 200}
2021/03/10 02:14:58.683 INFO  http.log.access.log0  handled request {"request": {"remote_addr": "127.0.0.1:56590", "proto": "HTTP/2.0", "method": "GET", "host": "dev3.foo.com", "uri": "/api", "headers": {"User-Agent": ["curl/7.64.0"], "Accept": ["*/*"]}, "tls": {"resumed": false, "version": 772, "cipher_suite": 4865, "proto": "h2", "proto_mutual": true, "server_name": "dev3.foo.com"}}, "common_log": "127.0.0.1 - - [10/Mar/2021:03:14:58 +0100] \"GET /api HTTP/2.0\" 200 27", "duration": 0.002575604, "size": 27, "status": 200, "resp_headers": {"Content-Type": ["text/html; charset=utf-8"], "X-Content-Type-Options": ["nosniff"], "Content-Length": ["27"], "Date": ["Wed, 10 Mar 2021 02:14:58 GMT"], "X-Xss-Protection": ["1; mode=block"], "X-Download-Options": ["noopen"], "Accept-Ranges": ["bytes"], "Server": ["Caddy"], "Strict-Transport-Security": ["max-age=15768000"], "X-Frame-Options": ["DENY"], "Cache-Control": ["no-cache"]}}
1.6153424986834333e+09  info  http.log.access.log0  handled request {"request": {"remote_addr": "127.0.0.1:56590", "proto": "HTTP/2.0", "method": "GET", "host": "dev3.foo.com", "uri": "/api", "headers": {"User-Agent": ["curl/7.64.0"], "Accept": ["*/*"]}, "tls": {"resumed": false, "version": 772, "cipher_suite": 4865, "proto": "h2", "proto_mutual": true, "server_name": "dev3.foo.com"}}, "common_log": "127.0.0.1 - - [10/Mar/2021:03:14:58 +0100] \"GET /api HTTP/2.0\" 200 27", "duration": 0.002575604, "size": 27, "status": 200, "resp_headers": {"Content-Type": ["text/html; charset=utf-8"], "X-Content-Type-Options": ["nosniff"], "Content-Length": ["27"], "Date": ["Wed, 10 Mar 2021 02:14:58 GMT"], "X-Xss-Protection": ["1; mode=block"], "X-Download-Options": ["noopen"], "Accept-Ranges": ["bytes"], "Server": ["Caddy"], "Strict-Transport-Security": ["max-age=15768000"], "X-Frame-Options": ["DENY"], "Cache-Control": ["no-cache"]}}

Nah, these talk about URI modification. Your issue isn’t URI modification (there is zero URI modification happening with your config), it’s with the matcher. As above, the issue is that the backend isn’t “catching” the literal URI /api, and it’s falling through to the frontend proxy handler.

I wish :slight_smile:

To make sure the trailing slash isn’t a problem I’ve been trying with this now:

handle_path /api* {
  reverse_proxy {
    to 10.0.1.2:29194
    #to srv+http://backend-staging.service.fsn1.consul
  }
}

reverse_proxy {
  to srv+http://frontend-staging.service.fsn1.consul
}

(If it was going to the frontend we would see a 404)

Oh, now you’re using handle_path.

That directive explicitly strips the prefix. Using handle_path is the same as using:

handle /api* {
  uri strip_prefix /api
  reverse_proxy <upstream>
}

Which is probably not your desired behaviour. You want requests to /api to be sent upstream to backend and to include the original URI unmodified (i.e. including /api). Check out the common config pattern I wrote above, I’m 99% sure it’s what you want.

1 Like

Urgh. I guess misunderstood. Did I mention it’s time for bed here?
And this indeed seems to do the trick

  reverse_proxy /api* {
    to srv+http://backend-staging.service.fsn1.consul
  }

sigh and yay!

So the only mystery left is the admin :slight_smile:

1 Like

Yep but I just feel like I should reiterate this part of what I wrote earlier:

And yep, admin 404 is still indeed a mystery. I might tag in another helper - @francislavoie, got any ideas for troubleshooting that one? I’m not sure where to even start given that the output in the OP indicates the admin endpoint is listening, but it’s 404ing localhost:2019.

Agreed. Thank you so much for the help.

When you say “open admin”, what do you mean?

The admin API only has certain paths served. For example, curl localhost:2019/config/ (trailing slash is important) will get your your JSON config. The 404 at the root is expected. The available endpoints are documented here:

2 Likes

Since it’s called “admin” I was under the impression there is something more than just some REST endpoints. I guess that was just false expectations on my end then.

Nevertheless I think it would be nice if the root maybe would act e.g. as a health endpoint - instead of returning just a 404.

Thanks for clearing this up!

This topic was automatically closed after 30 days. New replies are no longer allowed.