-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Description
Hello,
I've gone through the Caddy docs and not sure if this is expected behaviour. I have the following fairly simple setup, and Caddy is configured to do on_demand_tls and I have configured an ask endpoint which I control.
AWS NLB -> Caddy -> App
When I query the NLB using the FQDN (either it's default or a custom set one) I see the request is made to my ask endpoint just fine.
However, when a request is made to one of the public IPs of the NLB, the request made to the ask endpoint is actually the address of Caddy itself! Example log from my ask endpoint:
[03/May/2024:06:26:16 +0000] "GET /caddy?domain=10.0.0.62 HTTP/1.1" 404 - "-" "Go-http-client/2.0"
10.0.0.62 = the internal IP of my Caddy.
I have proved this by simply curling my NLB public IPs e.g. (curl https://1.2.3.4) and watching the ask endpoint logs.
I don't understand why this happens - I would imagine if there is no SNI, there should be no "ask" at all? Or at least, it should be asking for the IP queried, not the internal Caddy IP. Ideally, this shouldn't happen and Caddy should just reject the request.
The reason why this is an issue is, anyone on the internet can do a port scan of the NLB and force Caddy to make a request to my ask endpoint. This shouldn't be the case, and Caddy should only respond to FQDN's, in which it can ask the ask endpoint.
Here is a redacted Caddyfile:
{
http_port 80
https_port 443
admin 127.0.0.1:8080
servers :80 {
name http
protocols h1 h2
}
servers :443 {
name https
protocols h1 h2
}
servers :8443 {
name https-static
protocols h1 h2
}
log {
output stdout
level DEBUG
format json {
time_format rfc3339
}
}
on_demand_tls {
ask https://app-backend.blah/caddy
}
storage s3 {
host "s3.ap-southeast-2.amazonaws.com"
bucket "XXXXXXXXXXXXXXXXXXXXXXXX"
use_iam_provider true
prefix "tls-certificates"
insecure false
}
}
http:// {
header {
Server "XXXXXXXXXX (http to https)"
}
redir / https://{host}{uri}
log http-https-redirect {
output stdout
format json {
time_format rfc3339
}
}
}
:443 {
header {
Server "XXXXXXXXXXXXXX"
x-X-host {host}
}
reverse_proxy {
dynamic srv {
name _https._tcp.XXXXXXXXXXXXXXXXXXXX
refresh 1m
}
header_down -Server
header_up Host app-frontend.XXXXXXXXXXXXXXXX
header_up X-Real-IP {remote}
header_up X-Forwarded-Server {host}
header_up X-Forwarded-Port {port}
header_up x-ca-requested-host {host}
header_up webapp {http.request.header.Cookie}
transport http {
tls
tls_server_name app-frontend.XXXXXXXXXXXXXXXX
tls_insecure_skip_verify
}
}
tls XXXXXXXXXXXXXXXXX {
on_demand
}
log main {
output stdout
format json {
time_format rfc3339
}
}
}
:8443 {
header {
Server "XXXXXXXXXX (static site)"
}
route /* {
s3proxy {
bucket XXXXXXXXXXXXXX
region ap-southeast-2
index index.html
root /
endpoint s3.ap-southeast-2.amazonaws.com
errors /index.html
}
}
tls /etc/caddy/static-site.crt /etc/caddy/static-site.key
log static-s3 {
output stdout
format json {
time_format rfc3339
}
}
}