README.md
a07fa4f9
 # [`nfsn-utils`][]
 
 Interact with [NearlyFreeSpeech.NET][]'s [API][] from the command line.
 
 [`nfsn-utils`]: https://git.rcrnstn.net/rcrnstn/nfsn-utils
 [NearlyFreeSpeech.NET]: https://www.nearlyfreespeech.net
 [API]: https://en.wikipedia.org/wiki/API
246ed2ed
 
9067dadd
 ## Goals
 
 `nfsn-utils` has three main goals:
 
 1.  **Be portable** (even to things like [routers][]).
 
     POSIX shell is used as glue for standard utilities. See
     [dependencies](#dependencies).
 
 2.  **Be modular** where it makes sense.
 
     [`nfsn-send`](#nfsn-send) is a general purpose [NearlyFreeSpeech.NET][]
     [API][] wrapper. [`nfsn-dns-update`](#nfsn-dns-update) is a general purpose
     [NearlyFreeSpeech.NET][] DNS update utility.
 
 3.  **Be opinionated with sane defaults** where it makes sense.
 
     The smaller utilities assume things like that you want to use [standard
     email addresses][].
 
 4.  **Be easily auditable**.
 
     The scripts are well abstracted and no more than about 100 lines of code.
 
 [routers]: https://openwrt.org
 [standard email addresses]: https://www.ietf.org/rfc/rfc2142.txt
 
 ## Prerequisites
 
 ### API key
 
 As described in the [NearlyFreeSpeech.NET][] [documentation][], one needs to
 submit a [free assistance request][] to obtain an API key.
 
 Place the credentials in the environment variables `NFSN_LOGIN` and
 `NFSN_API_KEY` or in the file `./.nfsn-api` or `$HOME/.nfsn-api` (location
 overridable by the `NFSN_CREDENTIALS_PATH` environment variable). This file
 should be a JSON file consisting of an object with the keys `login` and
 `api-key`. (The file format and default location is compatible with
 [WebService::NFSN][] and [python-nfsn][].)
 
 [documentation]: https://members.nearlyfreespeech.net/wiki/API/Introduction
 [free assistance request]: https://members.nearlyfreespeech.net/support/assist?tag=apikey
 [WebService::NFSN]: https://metacpan.org/pod/WebService::NFSN#INTERFACE
 [python-nfsn]: https://github.com/ktdreyer/python-nfsn#authentication
 
 ### Dependencies
 
 -  Unix-like environment (in particular, `/dev/urandom`).
 -  [POSIX utilities][] with `date` supporting `+%s` (such as GNU `date`).
 -  `sha1sum` (for instance, the one in `coreutils`).
 -  [curl][].
 -  [jq][].
 -  `certbot` (only needed for `nfsn-dns-certbot*`).
 
 [POSIX utilities]: http://pubs.opengroup.org/onlinepubs/9699919799/idx/utilities.html
 [curl]: https://curl.haxx.se
 [jq]: https://github.com/stedolan/jq
 
 ## Included programs
 
 Dependency graph:
 
 ![included programs](doc/included-programs.dot.png)
 
 ### `nfsn-send`
 
 Wraps the Requests, Responses and Authentication described in the
 [NearlyFreeSpeech.NET][] [documentation][].
 
 ### `nfsn-dns-update`
 
 Updates several DNS records and outputs what data was actually changed.
 
 ### `nfsn-dns-a`
 
 Updates DNS [A][] records, used to map hostnames to an IPv4 address.
 
 [A]: https://en.wikipedia.org/wiki/List_of_DNS_record_types#A
 
 ### `nfsn-dns-spf`
 
 Updates DNS [SPF][] records, used for email authorization (specifying who is
 allowed to send mail from a domain).
 
 [SPF]: https://en.wikipedia.org/wiki/Sender_Policy_Framework
 
 ### `nfsn-dns-dkim`
 
 Updates DNS [DKIM][] records, used for email authentication (using digital
 signatures).
 
 [DKIM]: https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail
 
 ### `nfsn-dns-dmarc`
 
 Updates DNS [DMARC][] records, extending [SPF][] and [DKIM][] by specifying
 failure policy and reporting.
 
 See also the [dmarc.org FAQ][].
 
 [DMARC]: https://en.wikipedia.org/wiki/DMARC
 [dmarc.org FAQ]: https://dmarc.org/wiki/FAQ#Sender_Questions
 
 ### `nfsn-dns-certbot*`
 
 `nfsn-dns-certbot` calls [certbot][] (the [Electronic Frontier Foundation][]'s
 (EFF) [Let's Encrypt][] client, for getting HTTPS certificates) in [manual
 mode][] to make it use `nfsn-utils` to update DNS records in order to fullfill
 the [`dns-01` challenge][]. It does this by registering
 `nfsn-dns-certbot-{auth,cleanup}` as [hooks][].
 
 By default, the `auth` hook sleeps for 30 seconds to let the DNS records
 propagate. This can be overridden with the environment variable
 `NFSN_DNS_CERTBOT_AUTH_SLEEP`.
 
 Given that `nfsn-dns-certbot` has successfully run once, running `certbot
 renew` will suffice to renew the certificates.
 
 [certbot]: https://certbot.eff.org
 [Electronic Frontier Foundation]: https://www.eff.org
 [Let's Encrypt]: https://letsencrypt.org
 [manual mode]: https://certbot.eff.org/docs/using.html#manual
 [`dns-01` challenge]: https://tools.ietf.org/html/draft-ietf-acme-acme-03#section-7.4
 [hooks]: https://certbot.eff.org/docs/using.html#hooks
 
246ed2ed
 ## License
 
 Licensed under the [ISC License][] unless otherwise noted, see the
 [`LICENSE`][] file.
 
 [ISC License]: https://choosealicense.com/licenses/isc
 [`LICENSE`]: LICENSE