I’ve setup a reverse proxy for an application that exposes a static webpage and an API.
When accessing the website from a browser, the reverse proxy works as expected.
When polling the API through Postman or CURL I am able to reach the endpoint through port 80 directly which should instead be denied.
Actual behaviour
From browser opening myhost.it automatically redirects me to https://myhost.it as expected.
From Postman\CLI calling for example GET https://myhost.it/api works as expected. But also GET http://myhost.it/api works. Of course Postman\CLI aren’t a browser and don’t acknowledge a redirect, however I expected caddy to not forward the call.
Desired behaviour
From Postman\CLI calling for example GET http://myhost.it/apishould abort.
What I’ve tried
I imagine I need to implement an abort on the path /api but seems to me that matchers can’t work with ports only so I can’t understand how to deny requests on port 80 for the path /api
2. Error messages and/or full log output:
There are no error messages. The issue is in the Caddyfile configuration.
3. Caddy version:
Likely not relevant but lucaslorentz/caddy-docker-proxy:2.8.10
4. How I installed and ran Caddy:
Docker, see above.
a. System environment:
Docker, see above.
b. Command:
…
c. Service/unit/compose file:
…
d. My complete Caddy config:
myhost.it {
reverse_proxy 10.20.14.7:80 <--- automatically resolved by the docker container from lucaslorentz, actual config {{ upstreams 80 }}
}
I just started using Caddy myself, so I’m not 100% sure if my assumption is correct. But I assume the browser automatically upgrades to HTTPS, while curl or Postman send the request as defined (HTTP).
I reckon you can adjust your Caddyfile to either only listen on port 443 (HTTPS) or implement the redirect yourself.
Postman probably just followed the HTTP->HTTPS redirect. Are you sure that’s a problem? Do you really want to block HTTP access entirely (no redirects)? That would make it annoying for users coming from browsers that don’t default to trying HTTPS first.
I would need the rule to be applied only on the path /api, so that the web part intended for browsers won’t cause issues as you described.
I don’t have any evidence of that, if I set the origin to http://... the request goes through straight. Headers don’t show any info of a redirect nor do Caddy logs (but maybe I am looking at the wrong things).
The same behaviour can be observed with curl.
Overall the root issue is that if a client wrongly uses HTTP credentials and stuff would be transmitted unencrypted. So I need to force a drop/abort on the matcher path /api and protocol HTTP (80).
Caddy simply does not serve HTTP, by default. Caddy is HTTPS by default. And HTTP->HTTPS redirects are enabled unless you explicit turn it off. The redirect happen quietly unless you enable access logs for the HTTP server, which you can do like this:
:80 {
log
}
To see that Caddy is redirecting, just do this:
$ curl -v http://myhost.it
* Trying 127.0.0.1:80...
* Connected to myhost.it (127.0.0.1) port 80 (#0)
> GET / HTTP/1.1
> Host: myhost.it
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 308 Permanent Redirect
< Connection: close
< Location: https://myhost.it/
< Server: Caddy
< Date: Thu, 08 Aug 2024 08:57:30 GMT
< Content-Length: 0
<
* Closing connection 0
*
The Location header is the redirect. You can follow the redirect with curl -vL