How to Set up the Caddyfile so that the only domain can access my endpoint

1. Caddy version (caddy version):

caddy:2.4.3

2. How I run Caddy:

docker

a. System environment:

ubuntu 18.04

b. Command:

sudo docker-compose up -d

c. Service/unit/compose file:

version: "3.7"

services:
  caddy:
    image: caddy:2.4.3
    container_name: caddy
    restart: always
    network_mode: "host"
    volumes:
      - /opt/src/caddy/Caddyfile:/etc/caddy/Caddyfile
      - /opt/src/caddy/data/:/data/
      - ./log:/var/log

d. My complete Caddyfile or JSON config:

https://domianA.net {
    reverse_proxy /api/* 127.0.0.1:10001 {
        header_up Host "domianB.net"
        header_down Access-Control-Allow-Origin "domainB.net"
        header_down Access-Control-Allow-Methods "POST"
        header_down Access-Control-Allow-Headers *
    }
    @findprovs {
        path /api/v0/dht/findprovs
        method POST
        header_regexp Referer (domainB.net)
    }

    @not_findprovs {
        path /api/v0/dht/findprovs
        method POST
        header_regexp Referer (domainB.net)
    }

    @dag {
        path /api/v0/dag/get
        method POST
       header_regexp Referer (domainB.net)
    }

    @not_dag {
        path /api/v0/dag/get
        method POST
        header_regexp Referer (domainB.net)
    }
    reverse_proxy /path/* 127.0.0.1:8080

3. The problem I’m having:

For example, domainA is an endpoint I configured with caddy, I want to set only and only domainB can access my domainA

Is there any problem with my Caddyfile, please help me correct, thank you very much

I don’t know much about this, I want a Caddyfile with a template like this

4. Error messages and/or full log output:

NA

5. What I already tried:

NA

6. Links to relevant resources:

NA

Please upgrade to v2.4.6 at minimum.

You defined a bunch of request matchers, but you don’t seem to be using them anywhere.

Matchers are basically an if condition, but you need to pair it with a handler to make it actually control something.

These are the same matchers, they aren’t in the inverse of eachother at all.

But also the inverse of that matcher would be “match literally every request except this one” which is probably not what you want.

Well, the Referer header is something the browser sets. What are you trying to prevent? If some bad actor tries to make a request with curl to your server, than can just set the Referer header themselves by hand and get through.

I’m not sure what this really achieves. It would probably make more sense to just require authentication on your API (with API tokens or something) which your website would provide to logged in users or something so the JS code can hit the API. I guess.

3 Likes

Thank you very much for your reply, I tried to change my Caddyfile, help with some comments?

domainA {
    reverse_proxy /api/* 127.0.0.1:1111 {
        header_down Access-Control-Allow-Origin *
        header_down Access-Control-Allow-Methods "POST"
        header_down Access-Control-Allow-Headers *
    }
    log {
        output file /var/log/gateway.log {
            roll_size 1gb
            roll_keep 5
            roll_keep_for 72h
        }
        format json {
            time_format "iso8601"
        }
     }

    @findprovs {
        path /api/v0/dht/findprovs
        method POST
        header_regexp Referer (domainB)
    }

    @not_findprovs {
        path /api/v0/dht/findprovs
        method POST
        header_regexp Referer (domainB)
    }

    @dag {
        path /api/v0/dag/get
        method POST
       header_regexp Referer (domainB)
    }

    @not_dag {
        path /api/v0/dag/get
        method POST
        header_regexp Referer (domainB)
    }

    reverse_proxy @findprovs 127.0.01:port
    respond @not_findprovs "Access denied" 403

    reverse_proxy @dag 127.0.01:port
    respond @not_dag "Access denied" 403
}

Hi :slight_smile:

  1. Your reverse_proxy upstream (127.0.01 vs 127.0.0.1) is a bit odd (typo?), but will work just fine because of different IP representations (IP zero suppression and zero compression in this case).
    While it does work, I’d recommend changing it to 127.0.0.1 anyway.

  2. 2 of those 4 @namedMatcher are still equal. Prefixing the name of a @namedMatcher with not (@not_namedMatcher) will only change the name and nothing else.
    If you want @not_findprovs to not match the paths of @findprovs you would need to prefix the path with not:

      @findprovs {
          path /api/v0/dht/findprovs
          method POST
          header_regexp Referer (domainB)
      }
    
      @not_findprovs {
    -     path /api/v0/dht/findprovs
    +     not path /api/v0/dht/findprovs
          method POST
          header_regexp Referer (domainB)
      }
    

    But please see Request matchers (Caddyfile) — Caddy Documentation
    And as @francislavoie already wrote:

  3. @matt did an amazingly extensive explanation about directive order in Caddyfiles here:
    Composing in the Caddyfile
    I can assure you this will help you understand how matchers and ordering works!
    So please consider reading it and use some handle {}s and maybe post your new Caddyfile again, if you have any remaining questions :innocent:

  4. And relying on the referrer (Referer header) for any kind of security is an awful idea. Trivially easy to overcome as a “bad actor” and some browser may not even send that header at all, which would render them incompatible with your site.

2 Likes

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