Caddy block requests on port 80 from non browser clients

1. The problem I’m having:

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/api should 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.

http://example.localhost {
  redir https://{host}{uri} permanent
}

https://example.localhost {
  root * /usr/share/caddy
  file_server
}

@mary.ctrl Caddy enables HTTP->HTTPS redirects automatically, as part of Automatic HTTPS — Caddy Documentation, no need to do it yourself. In other words, this is enough:

example.localhost {
	root /srv
	file_server
}

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.

2 Likes

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

1 Like

You are right, Postman does show in the console the redirect.

I was looking in the wrong place, so all this thread is actually a “non issue”. :sweat_smile:

1 Like

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