Skip to main content

A simple python wrapper for using the Caddy API

Project description

fastcaddy

Usage

Installation

Install from pypi

$ pip install fastcaddy

Installing Caddy

This project is to help you use the caddy API, rather than a Caddyfile, to use caddy. To use the API, you need to install a plugin for your domain management service. We use Cloudflare, so we’ll document that here. For other domain services, see the Caddy docs for other plugins.

Cloudflare setup

from fastcore.utils import *

You’ll need a token from Cloudflare with access to modify the necessary settings. Here’s the steps to create a token with the minimal privileges. You’ll need to install the cloudflare pip package, then import:

from cloudflare import Cloudflare

Then you’ll need create a Cloudflare API token for your user, which we’ll then use to create the less privileged token.

cf_token = os.environ['CLOUDFLARE_API_TOKEN']

We can now check that works OK:

cf = Cloudflare(api_token=cf_token)
zones = cf.zones.list()
len(zones.result)
8

Replace this with your domain name:

domain = 'answer.ai'
zones = cf.zones.list(name=domain)
assert len(zones.result)==1
zone_id = zones.result[0].id

Here’s the methods available for modifying DNS records:

  • client.dns.records.create(*, zone_id, **params) -> Optional
  • client.dns.records.update(dns_record_id, *, zone_id, **params) -> Optional
  • client.dns.records.list(*, zone_id, **params) -> SyncV4PagePaginationArray[Record]
  • client.dns.records.delete(dns_record_id, *, zone_id) -> Optional
  • client.dns.records.edit(dns_record_id, *, zone_id, **params) -> Optional
  • client.dns.records.export(*, zone_id) -> str
  • client.dns.records.get(dns_record_id, *, zone_id) -> Optional
  • client.dns.records.import\_(*, zone_id, **params) -> Optional
  • client.dns.records.scan(*, zone_id, **params) -> Optional

…and here’s the methods for tokens:

from cloudflare.types.user import (CIDRList, Policy, Token, TokenCreateResponse, TokenUpdateResponse, TokenListResponse,
                                   TokenDeleteResponse, TokenGetResponse, TokenVerifyResponse)
  • client.user.tokens.create(**params) -> Optional
  • client.user.tokens.update(token_id, **params) -> object
  • client.user.tokens.list(**params) -> SyncV4PagePaginationArray[object]
  • client.user.tokens.delete(token_id) -> Optional
  • client.user.tokens.get(token_id) -> object
  • client.user.tokens.verify() -> Optional
from cloudflare.types.user.tokens import PermissionGroupListResponse
  • client.user.tokens.permission_groups.list() -> SyncSinglePage[object]
from cloudflare.types.user.tokens import Value
  • client.user.tokens.value.update(token_id, **params) -> str

We need these two permissions in our token:

permission_groups = cf.user.tokens.permission_groups.list()

dns_write = next(group for group in permission_groups if group['name'] == 'DNS Write')
zone_read = next(group for group in permission_groups if group['name'] == 'Zone Read')

Now we can create it:

new_token = cf.user.tokens.create(
    name='caddy_dns',
    policies=[{
        "effect": "allow",
        "resources": { f"com.cloudflare.api.account.zone.{zone_id}": "*" },
        "permission_groups": [
            {"id": zone_read['id'], "name": "Zone Read"},
            {"id": dns_write['id'], "name": "DNS Write"}
        ]
    }]
)

print(new_token.value)

Make a copy of this value, which we’ll need for setting up caddy.

Installing caddy

To install caddy, we’ll use a tool called xcaddy. This is written in go. So first install go:

  • Mac: brew install go
  • Linux: sudo apt install golang

Note that if you are not on the latest Ubuntu, you’ll need to setup the backport repo before installing go:

sudo add-apt-repository -y ppa:longsleep/golang-backports
sudo apt update

Now we can install xcaddy:

go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest

Alternatively, you can download the latest xcaddy directly, e.g:

# Change the OS and arch as needed, or remove them to view all options
wget -qO- https://latest.fast.ai/latest/caddyserver/xcaddy/linux_amd64.tar.gz

Then we use that to compile caddy with our desired domain plugin (cloudflare, in this case):

mkdir -p ~/go/bin
cd ~/go/bin
./xcaddy build --with github.com/caddy-dns/cloudflare

This gives us a ~/go/bin/caddy binary we can run:

./caddy version
./caddy run

Securely run caddy on start

If you’re using a server or running caddy a lot, you’ll want it to run on start. And if you’re making it publicly accessible, you’ll want it to be secure. This isn’t needed otherwise – you can just ~/go/bin/caddy run to run it manually (you may want to add ~/go/bin to your PATH env var).

To set this up, run from this repo root:

./setup_service.sh

If all went well, you should see output like this:

 caddy.service - Caddy
     Loaded: loaded (/etc/systemd/system/caddy.service; enabled; preset: enabled)
     Active: active (running) since Sat 2024-11-09 05:06:47 UTC; 2 days ago
       Docs: https://caddyserver.com/docs/
   Main PID: 138140 (caddy)
      Tasks: 29 (limit: 154166)
     Memory: 19.3M (peak: 28.8M)
        CPU: 3min 37.216s
     CGroup: /system.slice/caddy.service
             └─138140 /usr/bin/caddy run --environ

How to use

We will now show how to set up caddy as a reverse proxy for hosts added dynamically. We’ll grab our token from the previous step (assuming here that it’s stored in an env var):

cf_token = os.environ.get('CADDY_CF_TOKEN', 'XXX')

We can now setup the basic routes needed for caddy:

setup_caddy(cf_token)

To view the configuration created, use gcfg:

gcfg()
{ 'apps': { 'http': { 'servers': { 'srv0': { 'listen': [':80', ':443'],
                                             'routes': []}}},
            'tls': { 'automation': { 'policies': [{'issuers': [{'challenges': {'dns': {'provider': {'api_token': 'XXX', 'name': 'cloudflare'}}}, 'module': 'acme'}]}]}}}}

You can also view a sub-path of the configuration:

gcfg('/apps/http/servers')
{'srv0': {'listen': [':80', ':443'], 'routes': []}}

To add a reverse proxy, use add_reverse_proxy:

host = 'jph.answer.ai'
add_reverse_proxy(host, 'localhost:5001')

This is automatically added with an id matching the host, which you can view with gid:

gid('jph.answer.ai')
{ '@id': 'jph.answer.ai',
  'handle': [{'handler': 'reverse_proxy', 'upstreams': [{'dial': 'localhost:5001'}]}],
  'match': [{'host': ['jph.answer.ai']}],
  'terminal': True}

If you call this again with the same host, it will be replaced:

add_reverse_proxy(host, 'localhost:8000')
gid('jph.answer.ai').handle[0]
{'handler': 'reverse_proxy', 'upstreams': [{'dial': 'localhost:8000'}]}

To remove a host, delete its id:

del_id(host)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastcaddy-0.0.3.tar.gz (12.3 kB view details)

Uploaded Source

Built Distribution

fastcaddy-0.0.3-py3-none-any.whl (11.3 kB view details)

Uploaded Python 3

File details

Details for the file fastcaddy-0.0.3.tar.gz.

File metadata

  • Download URL: fastcaddy-0.0.3.tar.gz
  • Upload date:
  • Size: 12.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for fastcaddy-0.0.3.tar.gz
Algorithm Hash digest
SHA256 874d82c29d576a97d5996de971ea333b2ac43d1ba04f429d46c77dac155e7eb9
MD5 27c71cdfd8ea9f9861aad1c1f26fa36d
BLAKE2b-256 828add24a1f8e75136215fc59932915a70da690ef36d73b92ab09ecf1708fdf0

See more details on using hashes here.

File details

Details for the file fastcaddy-0.0.3-py3-none-any.whl.

File metadata

  • Download URL: fastcaddy-0.0.3-py3-none-any.whl
  • Upload date:
  • Size: 11.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for fastcaddy-0.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 ac0cda0f1238e131e4a4862736372e318be9a0607881dd1b4732082b4647c57a
MD5 697815b78ab78e97e9e6cc166b98aa69
BLAKE2b-256 966c3012f5e73f7b5763a94bad919fe7abb9093896425ba6cd716b9019b0d1ed

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page