Help us shape the future of Go! Take the 2026 Go Developer Survey

goacmedns

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 9, 2025 License: MIT Imports: 10 Imported by: 7

README

goacmedns

A Go library to handle acme-dns client communication and persistent account storage.

CI Status Lint Status Go Report Card

You may also be interested in a Python equivalent pyacmedns.

Installation

Once you have installed Go 1.21+ you can install goacmedns with go install:

go install github.com/nrdcg/goacmedns/cmd/goacmedns@latest

Usage

The following is a short example of using the library to update a TXT record served by an acme-dns instance.

package main

import (
	"context"
	"errors"
	"log"

	"github.com/nrdcg/goacmedns"
	"github.com/nrdcg/goacmedns/storage"
)

const (
	domain = "your.example.org"
)

var (
	whitelistedNetworks = []string{"192.168.11.0/24", "[::1]/128"}
)

func main() {
	// Initialize the client. Point it towards your acme-dns instance.
	client, err := goacmedns.NewClient("https://auth.acme-dns.io")

	ctx := context.Background()

	// Initialize the storage.
	// If the file does not exist, it will be automatically created.
	st := storage.NewFile("/tmp/storage.json", 0600)

	// Check if credentials were previously saved for your domain.
	account, err := st.Fetch(ctx, domain)
	if err != nil {
		if !errors.Is(err, storage.ErrDomainNotFound) {
			log.Fatal(err)
		}

		// The account did not exist.
		// Let's create a new one The whitelisted networks parameter is optional and can be nil.
		newAcct, err := client.RegisterAccount(ctx, whitelistedNetworks)
		if err != nil {
			log.Fatal(err)
		}

		// Save it
		err = st.Put(ctx, domain, newAcct)
		if err != nil {
			log.Fatalf("Failed to put account in storage: %v", err)
		}

		err = st.Save(ctx)
		if err != nil {
			log.Fatalf("Failed to save storage: %v", err)
		}

		account = newAcct
	}

	// Update the acme-dns TXT record.
	err = client.UpdateTXTRecord(ctx, account, "___validation_token_recieved_from_the_ca___")
	if err != nil {
		log.Fatal(err)
	}
}

Pre-Registration

When using goacmedns with an ACME client hook it may be desirable to do the initial ACME-DNS account creation and CNAME delegation ahead of time.

The goacmedns command line utility provides an easy way to do this:

go install github.com/nrdcg/goacmedns/cmd/goacmedns@latest

goacmedns -api http://10.0.0.1:4443 -domain example.com -allowFrom 192.168.100.1/24,1.2.3.4/32,2002:c0a8:2a00::0/40 -storage /tmp/example.storage.json

This will register an account for example.com that is only usable from the specified CIDR -allowFrom networks with the ACME-DNS server at http://10.0.0.1:4443, saving the account details in /tmp/example.storage.json and printing the required CNAME record for the example.com DNS zone to stdout.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Account

type Account struct {
	FullDomain string `json:"fulldomain"`
	SubDomain  string `json:"subdomain"`
	Username   string `json:"username"`
	Password   string `json:"password"`
	// ServerURL contains the URL of the acme-dns server the Account was registered with
	// (may be empty for Account instances registered before this field was added).
	ServerURL string `json:"server_url"`
}

Account is a struct that holds the registration response from an ACME-DNS server. It represents an API username/key that can be used to update TXT records for the account's subdomain.

type Client

type Client struct {
	// contains filtered or unexported fields
}

func NewClient

func NewClient(baseURL string, opts ...Option) (*Client, error)

func (*Client) RegisterAccount

func (c *Client) RegisterAccount(ctx context.Context, allowFrom []string) (Account, error)

func (*Client) UpdateTXTRecord

func (c *Client) UpdateTXTRecord(ctx context.Context, account Account, value string) error

type ClientError

type ClientError struct {
	// Message is a string describing the client operation that failed
	Message string
	// HTTPStatus is the HTTP status code the ACME DNS server returned
	HTTPStatus int
	// Body is the response body the ACME DNS server returned
	Body []byte
}

ClientError represents an error from the ACME-DNS server. It holds a `Message` describing the operation the client was doing, a `HTTPStatus` code returned by the server, and the `Body` of the HTTP Response from the server.

func (ClientError) Error

func (e ClientError) Error() string

Error collects all the ClientError fields into a single string.

type Option added in v0.2.0

type Option func(c *Client)

func WithHTTPClient added in v0.2.0

func WithHTTPClient(client *http.Client) Option

type Register added in v0.2.0

type Register struct {
	AllowFrom []string `json:"allowfrom"`
}

type Storage

type Storage interface {
	// Save will persist the `Account` data that has been `Put` so far
	Save(ctx context.Context) error
	// Put will add an `Account` for the given domain to the storage. It may not
	// be persisted until `Save` is called.
	Put(ctx context.Context, domain string, account Account) error
	// Fetch will retrieve an `Account` for the given domain from the storage. If
	// the provided domain does not have an `Account` saved in the storage
	// `ErrDomainNotFound` will be returned
	Fetch(ctx context.Context, domain string) (Account, error)
	// FetchAll retrieves all the `Account` objects from the storage and
	// returns a map that has domain names as its keys and `Account` objects
	// as values.
	FetchAll(ctx context.Context) (map[string]Account, error)
}

Storage is an interface describing the required functions for an ACME DNS Account storage mechanism.

type Update added in v0.2.0

type Update struct {
	SubDomain string `json:"subdomain"`
	Txt       string `json:"txt"`
}

Directories

Path Synopsis
cmd
goacmedns command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL