On_demand_tls with Auth

1. The problem I’m having:

I’m trying to integrate the on_demand_tls ask check with AWS Lambda function URLs called from Caddy hosted on an EC2 instance. A function’s URL is public and cannot be made private; I cannot limit access to my VPC/EC2 instance only.

Is there a way to pass additional authentication headers/credentials along the on_demand_tls ask request? curl, for example, provides a built-in AWS SigV4 mechanism for requests (AWS SigV4 requests with curl | how.wtf). I’d rather not expose the check endpoint to the world (since this could allow an attacker to scrape/inspect all registered domains among other things unless rate-limited, etc.).

Alternatives I’m considering

  • I could host the web server to perform the domain checks on the Caddy instances directly, however I would prefer that the instances remain as agnostic as possible (especially considering possibly needed updates to the web server performing the checks).
  • Not sure if possible, but I could try to add an additional query parameter (with an API key) that gets validated before the domain check. I’d prefer a “proper” IAM signed request though (below), especially since my execution environment (EC2) already has permissions to execute a function.
  • Again not sure if possible from within Caddy, but EC2’s execution role can have lambda:InvokeFunction permission. If it is possible to change the ask request to invoke a function rather than make an HTTP request, it would be preferable to sending an HTTP request.
  • Perhaps somehow inspect the request headers in the Lambda to determine its origin IP and decide based on that. Seems a bit cumbersome, I’d much rather prefer some auth token/credential mechanism.

Examples:

{
    on_demand_tls {
        ask      http://localhost:5555/check # original
        ask      http://localhost:5555/check?key=1234abcd # query param with API key
        ask      http://localhost:5555/check Authentication:"Token" # Auth header
        ask      http://localhost:5555/check AWSSigV4 $aws_access_key_id:$aws_secret_access_key # AWS Credentials for SigV4 request
        ask      AWS:Lambda:InvokeFunction MyFunction # direct lambda invocation
    }
}

2. Error messages and/or full log output:

No errors.

3. Caddy version:

v2.7.6

4. How I installed and ran Caddy:

a. System environment:

Amazon Linux 2, systemd

b. Command:

sudo su

yum -y update
yum -y install yum-plugin-copr
yum -y copr enable @caddy/caddy epel-7-$(arch)
yum -y install caddy
systemctl enable --now caddy-api

c. Service/unit/compose file:

N/A

d. My complete Caddy config:

{
    on_demand_tls {
        ask      http://localhost:5555/check
    }
}

https:// {
    tls {
        on_demand
    }
    reverse_proxy localhost:9000
}

5. Links to relevant resources:

This should work. Caddy should just append the domain query param, and existing query params should be preserved.

We don’t have support for adding headers right now.

We’re working on making ask pluggable, so you could use your own Caddy plugin to do whatever authentication you want (or validate the domains a different way entirely), but that’s not quite ready yet.

Yeah you could do that too if you know the IPs of your Caddy servers ahead of time.

1 Like

Thanks for the quick reply.

Nice, that works then. I wasn’t quite sure from the docs that this is the behavior.

Can’t wait!

1 Like

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