Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Naive, self-contained dns-01 gateway service

License

NotificationsYou must be signed in to change notification settings

Sp1l/ACME-dns01-gateway

Repository files navigation

Intentially naive "pip-less" web-service shim to add/remove_acme-challenge TXT DNS resource records to your DNS service. Minimalrequirements, all part of a standard Python install.

Built to accompany Apache'smod_md and run in a FreeBSD jail (or yourcontainer flavour-du-jour). Thus it uses "setup" and "teardown" for the action.There's no reason this couldn't be made to work with any other client viaa curl script.

Uses a "bring-your-own" DNS modification python script. An exampleimplementation script (no pip requirements) can be found in this repo'sproviders/openprovider.py file.

Why?

I don't like to have credentials to my complete DNS zone in my web-server jail.This setup separates the account credentials and will only add/remove_acme-challenge records.

This setup also allows creating a single service/server that can manage thedns-01 challenge creation and removal for many web-servers.

Threat model

An attacker adding a spurious_acme-challenge notification, that's bad enoughbut they'll have to do very fancy stuff to Man-in-the-Middle the connections toyour webserver, especially so if you're domain is DNSSEC protected.

An attacker with full control over your DNS records? That'spants-on-firebad! They'll have no issue MitM-ing all your traffic.

Usage

  1. Clone this repo.
  2. Create DNS API implementation
  3. Create configuration
  4. Runacmegw_server.py, it will sit there and listen.

Usedaemon on FreeBSD to run it in background from anrc.d script.(Asystemd unit on Linux?)

Configuration

The webservice and the DNS API can be configured using (in decreasingprecedence):

  1. Command-line arguments (long and short): unless long option listed in thetable below, it is the lower-case of the variable.
  2. Environment variables: only upper-case, verbatim (NOTE: watch out withquoting)
  3. A.env file: formatvariable = value, variable will be converted toupper-case. Last entry in the file takes precedence.
Variableargenv.envDefaultDescription
DOTENV-e./.envPath to .env file
LISTEN-l*:8000IP:port, port or IP to listen on
LISTEN_PORT8000port to listen on
LISTEN_IP*IP-address to listen on
DNSAPI_USERNAMEUsername for DNS API
DNSAPI_PASSWORDPassword DNS API
DNSAPI_MODULE-mErrorPython module to load for DNSAPI
DNSAPI_CLASS-cErrorClass inDNSAPI_MODULE to use as DNSAPI
DNSAPI_DOMAINS1ErrorList of (Sub-)Domains manageable via API
ALL_PROXY2NoneForward proxy to use for providers
SSL_CERTcert.pemPath to SSL certificate file
SSL_KEYkey.pemPath to SSL key file
BASIC_AUTH3NoneEnable Basic authentication on API
ALLOWED_HOSTS1,3NoneList of remote IP's/networks allowed to use API
ALLOWED_PROXIES1,4NoneList of remote IP's/networks allowed to set XFF header
PROXY_XFF3X-Forwarded-ForXFF header to use

Note1: Lists are comma-separated
Note2: Uses standard proxy environment variables (ALL_PROXY,HTTPS_PROXY). If these are not set in environment, useALL_PROXY from.env asHTTP_PROXY andHTTPS_PROXY value.
Note3: One ofBASIC_AUTH orALLOWED_HOSTS must be set, both maybe set. See "API Authentication"
Note4: Only relevant ifALLOWED_HOSTS is set.

.env file parsing

  1. Lines staring with "#", with optional leading whitespace, will be ignored.
  2. Trailing comments arenot ignored!VAR = value # comment will assignvalue # comment toVAR.
  3. Whitespace around the "=" sign will be removed, as will leading and trailingwhitespace of the variable and the value.
  4. Either single- (') or double- (") quotes work.
  5. Variables are case-insensitive (values arenot!).

API Authentication

TheBASIC_AUTH parameter andALLOWED_HOSTS interact following setting ofBASIC_AUTH:

  1. Not configured, empty, "none" or "disabled": Basic authentication disabled.
  2. "sufficient": Either a matching username and password, or a matching host is sufficient for auth (if configured).
  3. "required": A matching username and password is required, in addition to matching host (if configured).

Apachemod_md configuration

Seemod_md documentation

MDChallengeDns01Version2MDChallengeDns01 /path/to/wrapper.sh

Example/path/to/wrapper.sh. Make sure it is executable!

!/bin/shprintf'{"argument": "%s", "domain_name": "%s", "challenge_content": "%s"}' \"$1""$2""$3" \| curl http://dns01gw.example.org:8017/ -X POST --data @-

NOTE: Working with JSON in shell scripts is a real pain with quoting andespecially with spaces. This part of the reason this is implemented in Python.

ACME DNS-01 API

Payload must be valid json and conform to themod_md naming of the arguments.

{"argument":"setup|add|teardown|remove","domain_name":"fully.qualified.example.com","challenge_content":"abcdef123456790" }

Nothing more, nothing less.

DNS Provider script

The server will dynamically import your DNS API script as specified by theDNSAPI_MODULE andDNSAPI_CLASS configuration.

Your `DNSAPI_CLASSmust implement the following method:

classMyDNSProvider():defacme_challenge(self,action:str,fqdn:str,token:str):"""Add or remove the _acme-challenge dns-01 validation token        Args:            action (str): 'setup' or 'teardown'            fqdn (str): The Fully Qualified Domain Name, includes `_acme-challenge` prefix            token (str): Content for the `_acme-challenge` TXT RR        """

Check out theproviders\openprovider.py example.

Resources

Python examples for various DNS providers can be found in e.g.certbot's repo, in thecertbot-dns-*directories.Shell-script examples can be found in e.g.acme.sh's repodnsapi dir.

About

Naive, self-contained dns-01 gateway service

Topics

Resources

License

Stars

Watchers

Forks


[8]ページ先頭

©2009-2025 Movatter.jp