summaryrefslogtreecommitdiff
path: root/README.org
blob: 98501b3e2646d9842ce75e068c7940380592f3b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#+title: Email Key Rotation
#+language: en
#+author: Vivien Kraus
#+email: vivien@planete-kraus.eu

I present to you this humble package that can help you rotate your
DKIM keys and SRS secrets.

DKIM rotation can be done in various different ways, but this package
assumes that you have at least a couple of selectors, such as
=selectorA= and =selectorB=. When the current selector is =selectorB=,
the DNS entry for =selectorA= is the previous expired public key, and
the DNS entry for =selectorB= is the current public key. In this case,
after rotation, the DNS entry for =selectorB= does not change, but
that of =selectorA= becomes the new public key, and the email server
starts signing outbound emails with =selectorA= instead of
=selectorB=, provided that you restart it.

This package can:
- rotate DKIM keys;
- rotate SRS secrets for opensmtpd;
- “materialize” the keys.

When materialized, the DKIM key is saved as an openssl private key (so
that it can be used by your DKIM signing SMTP server), the current
selector is written to a file on its only line, the SRS secrets are
written to an OpenSMTPD configuration file, and, if configured, the
Gandi LiveDNS zone is updated.

This package uses the =openssl= program to generate keys and
secrets. You can customize this by parameterizing
=current-openssl-binary= in /(email-key-rotation openssl)/, either to
a program name to invoke, or to a procedure that accepts 1 argument
(the command-line for openssl, without the program name).

This package manages different secrets: both[fn::current and expired]
DKIM keys, both SRS secrets, and the Gandi LiveDNS API key. Files
containing these secrets are always written with mode =0600=, but not
much else is considered for security.

* Initialize the configuration
You initialize the configuration by calling =initialize= in
/(email-key-rotation)/. The arguments are:
- the list of selectors, for instance ='(selectorA selectorB)=;
- the file name for the private opensmtpd configuration file, or =#f=
  if you do not want to configure SRS;
- the name of the file that will contain the current DKIM selector, or
  =#f= if you do not want to configure DKIM;
- the name of the file that will contain the current DKIM private key,
  or =#f= if you do not want to configure DKIM;
- the Gandi LiveDNS API key, or =#f= if you do not wish to publish DNS
  records on Gandi LiveDNS;
- the Gandi domain name.

This function returns a configuration object that you may save to disk
with =materialize=, in /(email-key-rotation)/. This function takes the
configuration object as the first argument, and an optional output
port to save the configuration object itself. If the port is not set,
then it is saved to the current Guile output port. If the port is set,
*and* is set to a file port, then it will be made only readable by the
current owner.

* Rotate the configuration
Every once in a while, say, every week, you would load the current
configuration object, and rotate it with =rotate=, in
/(email-key-rotation)/. The return value is a new configuration object
that you can materialize.

The configuration object is saved to disk as XML. You may convert it
with =xml->sxml= in /(sxml simple)/, and then convert it to a
configuration object with =sxml->configuration= in
/(email-key-rotation)/, or use the shortcut =xml->configuration= in
/(email-key-rotation)/. The latter accept only one optional argument,
the port to read XML from. It defaults to the Guile current input
port.

* About the code
The code requires =guile-json=, and at run-time, the =openssl= binary.

You can run tests by loading /(email-key-rotation run-tests)/:

#+begin_src shell
  guile -L ./guile guile/email-key-rotation/run-tests.scm
#+end_src

** Licensing terms
This is email-key-rotation, a program to help rotate DKIM and SRS
secrets.

Copyright (C) 2024  Vivien Kraus

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public
License along with this program.  If not, see
<https://www.gnu.org/licenses/>.

** Clarifications to redistribute the package
I am not a lawyer, but it seems to me that:

- publishing (with this package) or retrieving DNS records (that have
  been written by this package) is not considered “Remote Network
  Interaction”;
- transmitting e-mails over SMTP when one or both of the SMTP servers
  are configured with the help of this package is not considered
  “Remote Network Interaction”.