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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
|
% lacme(1)
% [Guilhem Moulin](mailto:guilhem@fripost.org)
% December 2015
Name
====
lacme - [ACME] client written with process isolation and minimal
privileges in mind
Synopsis
========
`lacme` [`--config=FILENAME`] [`--socket=PATH`] [*OPTION* …] *COMMAND* [*ARGUMENT* …]
Description
===========
`lacme` is a small [ACME] client written with process isolation and
minimal privileges in mind. It is divided into four components, each
with its own executable:
1. A [`lacme-accountd`(1)] process to manage the account key and issue
SHA-256 signatures needed for each [ACME] command. (This process
binds to a UNIX-domain socket to reply to signature requests from
the [ACME] client.)
One can use the UNIX-domain socket forwarding facility of OpenSSH
6.7 and later to run [`lacme-accountd`(1)] and `lacme` on different
hosts. Alternatively, the [`lacme-accountd`(1)] process can be
spawned by the “master” `lacme` process below; in that case, the
two processes communicate through a socket pair.
2. A “master” `lacme` process, which runs as root and is the only
component with access to the private key material of the server
keys. It is used to fork the [ACME] client (and optionally the
[ACME] webserver) after dropping root privileges.
For certificate issuances (`new-cert` command), it also generates
Certificate Signing Requests, then verifies the validity of the
issued certificate, and optionally reloads or restarts services when
the *notify* option is set.
3. An actual [ACME] client (specified with the *command* option of the
[`[client]` section](#client-section) of the configuration file),
which builds [ACME] commands and dialogues with the remote [ACME]
server.
Since [ACME] commands need to be signed with the account key, the
“master” `lacme` process passes the [`lacme-accountd`(1)]
UNIX-domain socket to the [ACME] client: data signatures are
requested by writing the data to be signed to the socket.
4. For certificate issuances (`new-cert` command), an optional
webserver (specified with the *command* option of the [`[webserver]`
section](#webserver-section) of the configuration file), which is
spawned by the “master” `lacme` process when no service is listening
on the HTTP port. (The only challenge type currently supported by
`lacme` is `http-01`, which requires a webserver to answer
challenges.) That webserver only processes `GET` and `HEAD` requests
under the `/.well-known/acme-challenge/` URI.
By default some [`iptables`(8)] rules are automatically installed to
open the HTTP port, and removed afterwards.
Commands
========
`lacme` [`--agreement-uri=`*URI*] `new-reg` [*CONTACT* …]
: Register the account key managed by [`lacme-accountd`(1)]. A list
of *CONTACT* information (such as `maito:` URIs) can be specified in
order for the server to contact the client for issues related to
this registration (such as notifications about server-initiated
revocations).
`--agreement-uri=` can be used to specify a *URI* referring to a
subscriber agreement or terms of service provided by the server;
adding this options indicates the client's agreement with the
referenced terms. Note that the server might require the client to
agree to subscriber agreement before performing any further actions.
If the account key is already registered, `lacme` prints the URI of
the existing registration and aborts.
`lacme` [`--agreement-uri=`*URI*] `reg=`*URI* [*CONTACT* …]
: Dump or edit the registration *URI* (relative to the [ACME] server
URI, which is specified with the *server* option of the [`[client]`
section](#client-section) of the configuration file).
When specified, the list of *CONTACT* information and the agreement
*URI* are sent to the server to replace the existing values.
`lacme` [`--config-certs=`*FILE*] `new-cert` [*SECTION* …]
: Read the certificate configuration *FILE* (see the **[certificate
configuration file](#certificate-configuration-file)** section below
for the configuration options), and request new Certificate Issuance
for each of its sections (or the given list of *SECTION*s).
`lacme` `revoke-cert` *FILE* [*FILE* …]
: Request that the given certificate(s) *FILE*(s) be revoked. For
this command, [`lacme-accountd`(1)] can be pointed to either the
account key or the server's private key.
Generic options
===============
`--config=`*filename*
: Use *filename* as configuration file. See the **[configuration
file](#configuration-file)** section below for the configuration
options.
`--socket=`*path*
: Use *path* as the [`lacme-accountd`(1)] UNIX-domain socket to
connect to for signature requests from the [ACME] client. `lacme`
aborts if `path` is readable or writable by other users, or if its
parent directory is writable by other users.
This command-line option overrides the *socket* option of the
[`[client]` section](#client-section) of the configuration file.
Moreover this option is ignored when the configuration file has an
[`[accountd]` section](#accountd-section); in that case `lacme`
spawns [`lacme-accountd`(1)], and the two processes communicate
through a socket pair.
`-h`, `--help`
: Display a brief help and exit.
`-q`, `--quiet`
: Be quiet.
`--debug`
: Turn on debug mode.
Configuration file
==================
If `--config=` is not given, `lacme` uses the first existing
configuration file among *./lacme.conf*,
*$XDG_CONFIG_HOME/lacme/lacme.conf* (or *~/.config/lacme/lacme.conf* if
the `XDG_CONFIG_HOME` environment variable is not set), and
*/etc/lacme/lacme.conf*.
Valid options are:
Default section
---------------
*config-certs*
: For certificate issuances (`new-cert` command), specify the
space-separated list of certificate configuration files or
directories to use (see the **[certificate configuration
file](#certificate-configuration-file)** section below for the
configuration options).
Paths not starting with `/` are relative to the directory name of
the **[configuration filename](#configuration-file)**. The list of
files and directories is processed in order, with the later items
taking precedence. Files in a directory are processed in
lexicographic order, only considering the ones with suffix `.conf`.
Default: `lacme-certs.conf lacme-certs.d/`.
`[client]` section
------------------
This section is used for configuring the [ACME] client (which takes care
of [ACME] commands and dialogues with the remote [ACME] server).
*socket*
: See `--socket=`.
Default: *$XDG_RUNTIME_DIR/S.lacme* if the `XDG_RUNTIME_DIR`
environment variable is set.
*user*
: The username to drop privileges to (setting both effective and real
uid). Preserve root privileges if the value is empty (not
recommended).
Default: `nobody`.
*group*
: The groupname to drop privileges to (setting both effective and real
gid, and also setting the list of supplementary gids to that single
group). Preserve root privileges if the value is empty (not
recommended).
Default: `nogroup`.
*command*
: Path to the [ACME] client executable.
Default: `/usr/lib/lacme/client`.
*server*
: Root URI of the [ACME] server.
Default: `https://acme-v01.api.letsencrypt.org/`.
*timeout*
: Timeout in seconds after which the client stops polling the [ACME]
server and considers the request failed.
Default: `10`.
*SSL_verify*
: Whether to verify the server certificate chain.
Default: `Yes`.
*SSL_version*
: Specify the version of the SSL protocol used to transmit data.
*SSL_cipher_list*
: Specify the cipher list for the connection, see [`ciphers`(1ssl)]
for more information.
`[webserver]` section
---------------------
This section is used for configuring the [ACME] webserver.
*listen*
: Specify the local address to listen on, in the form
`ADDRESS[:PORT]`. If `ADDRESS` is enclosed with brackets ‘[’/‘]’
then it denotes an IPv6; an empty `ADDRESS` means `0.0.0.0`.
Default: `:80`.
*challenge-directory*
: If a webserver is already running, specify a non-existent directory
under which the webserver is configured to serve `GET` requests for
challenge files under `/.well-known/acme-challenge/` (for each
virtual hosts requiring authorization) as static files.
Default: `/var/www/acme-challenge`.
*user*
: The username to drop privileges to (setting both effective and real
uid). Preserve root privileges if the value is empty (not
recommended).
Default: `www-data`.
*group*
: The groupname to drop privileges to (setting both effective and real
gid, and also setting the list of supplementary gids to that single
group). Preserve root privileges if the value is empty (not
recommended).
Default: `www-data`.
*command*
: Path to the [ACME] webserver executable.
Default: `/usr/lib/lacme/webserver`.
*iptables*
: Whether to automatically install [`iptables`(8)] rules to open the
`ADDRESS[:PORT]` specified with *listen*. Theses rules are
automatically removed once `lacme` exits.
Default: `Yes`.
`[accountd]` section
---------------------
This section is used for configuring the [`lacme-accountd`(1)] process.
If the section (including its header) is absent or commented out,
`lacme` connects to an existing UNIX-domain socket bound by a running
[`lacme-accountd`(1)] process.
*user*
: The username to drop privileges to (setting both effective and real
uid). Preserve root privileges if the value is empty.
*group*
: The groupname to drop privileges to (setting both effective and real
gid, and also setting the list of supplementary gids to that single
group). Preserve root privileges if the value is empty.
*command*
: Path to the [`lacme-accountd`(1)] executable.
Default: `/usr/bin/lacme-accountd`.
*config*
: Path to the [`lacme-accountd`(1)] configuration file.
Default: `/etc/lacme/lacme-accountd.conf`.
*privkey*
: The (private) account key to use for signing requests. See
[`lacme-accountd`(1)] for details.
*quiet*
: Be quiet. Possible values: `Yes`/`No`.
Certificate configuration file
==============================
For certificate issuances (`new-cert` command), a separate file is used
to configure paths to the certificate and key, as well as the subject,
subjectAltName, etc. to generate Certificate Signing Requests.
Each section denotes a separate certificate issuance.
Valid options are:
*certificate*
: Where to store the issued certificate (in PEM format).
At least one of *certificate* or *certificate-chain* is required.
*certificate-chain*
: Where to store the issued certificate, concatenated with the content
of the file specified specified with the *CAfile* option (in PEM
format).
At least one of *certificate* or *certificate-chain* is required.
*certificate-key*
: Path the service's private key. This option is required. The
following command can be used to generate a new 4096-bits RSA key in
PEM format with mode 0600:
openssl genrsa 4096 | install -m0600 /dev/stdin /path/to/srv.key
*min-days*
: For an existing certificate, the minimum number of days before its
expiration date the section is considered for re-issuance.
Default: `10`.
*CAfile*
: Path to the issuer's certificate. This is used for
*certificate-chain* and to verify the validity of each issued
certificate.
Specifying an empty value skip certificate validation.
Default: `/usr/share/lacme/lets-encrypt-x3-cross-signed.pem`.
*hash*
: Message digest algorithm to sign the Certificate Signing Request
with.
*keyUsage*
: Comma-separated list of Key Usages, see [`x509v3_config`(5ssl)].
*subject*
: Subject field of the Certificate Signing Request, in the form
`/type0=value0/type1=value1/type2=…`. This option is required.
*subjectAltName*
: Comma-separated list of Subject Alternative Names, in the form
`type0:value1,type1:value1,type2:…`
The only `type` currently supported is `DNS`, to specify an
alternative domain name.
*chown*
: An optional `username[:groupname]` to chown the issued *certificate*
and *certificate-chain* to.
*chmod*
: An optional octal mode to chmod the issued *certificate* and
*certificate-chain* to.
*notify*
: Command to pass the the system's command shell (`/bin/sh -c`)
after successful installation of the *certificate* and/or
*certificate-chain*.
Examples
========
~$ sudo lacme new-reg mailto:noreply@example.com
~$ sudo lacme reg=/acme/reg/123456 --agreement-uri=https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf
~$ sudo lacme new-cert
~$ sudo lacme revoke-cert /path/to/server/certificate.pem
See also
========
[`lacme-accountd`(1)]
[ACME]: https://tools.ietf.org/html/draft-ietf-acme-acme-02
[`lacme-accountd`(1)]: lacme-accountd.1.html
[`iptables`(8)]: http://linux.die.net/man/8/iptables
[`ciphers`(1ssl)]: https://www.openssl.org/docs/manmaster/apps/ciphers.html
[`x509v3_config`(5ssl)]: https://www.openssl.org/docs/manmaster/apps/x509v3_config.html
|