├── .gitignore
├── .gitlab-ci.env
├── .gitlab-ci.yaml
├── LICENSE
├── README.rst
├── config
├── acmebot.example.json
└── acmebot.example.yaml
├── logrotate.d
└── acmebot
├── pyproject.toml
└── src
└── acmebot
├── __init__.py
└── acmebot.py
/.gitignore:
--------------------------------------------------------------------------------
1 | etc/*
2 | var/*
3 |
4 | .venv*
5 |
6 | .mypy_cache
7 | __pycache__
8 | *.egg-info
9 |
10 | *.pem
11 | *.zip
12 | *.orig
13 | *.sublime-*
14 | **/.DS_Store
15 |
--------------------------------------------------------------------------------
/.gitlab-ci.env:
--------------------------------------------------------------------------------
1 | # environment variables for CI/CD
2 |
3 | PACKAGE_NAME=$(echo ${CI_PROJECT_NAME} | sed s/-/_/)
4 |
--------------------------------------------------------------------------------
/.gitlab-ci.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | image: python:3.9
3 |
4 |
5 | stages:
6 | - test
7 | - package
8 | - deploy
9 |
10 |
11 | # flake8:
12 | # stage: lint
13 | # before_script:
14 | # - source .gitlab-ci.env
15 | # - pip install -e ".[dev]"
16 | # script:
17 | # - flake8 ${PACKAGE_NAME}
18 |
19 |
20 | # mypy:
21 | # stage: lint
22 | # before_script:
23 | # - source .gitlab-ci.env
24 | # - pip install -e ".[dev]"
25 | # script:
26 | # - mypy ${PACKAGE_NAME}
27 |
28 |
29 | test_3.9:
30 | stage: test
31 | image: python:3.9
32 | before_script:
33 | - source .gitlab-ci.env
34 | - pip install -e ".[test]"
35 | - chmod a+x test.py
36 | script:
37 | - ./test.py
38 | rules:
39 | - exists:
40 | - test.py
41 |
42 |
43 | test_3.10:
44 | stage: test
45 | image: python:3.10
46 | before_script:
47 | - source .gitlab-ci.env
48 | - pip install -e ".[test]"
49 | - chmod a+x test.py
50 | script:
51 | - ./test.py
52 | rules:
53 | - exists:
54 | - test.py
55 |
56 |
57 | test_3.11:
58 | stage: test
59 | image: python:3.11
60 | before_script:
61 | - source .gitlab-ci.env
62 | - pip install -e ".[test]"
63 | - chmod a+x test.py
64 | script:
65 | - ./test.py
66 | rules:
67 | - exists:
68 | - test.py
69 |
70 |
71 | package:
72 | stage: package
73 | image: docker.linss.com/docker-images/python-build:main
74 | script:
75 | - python -m build --no-isolation --outdir dist
76 | artifacts:
77 | paths:
78 | - dist
79 | rules:
80 | - if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9-\.]+)?$/'
81 |
82 |
83 | deploy:
84 | stage: deploy
85 | before_script:
86 | - source .gitlab-ci.env
87 | - pip install --upgrade wheel twine
88 | script:
89 | - python -m twine upload --username __token__ --password ${PYPI_API_TOKEN} --non-interactive --disable-progress-bar --repository-url ${PYPI_REPOSITORY_URL} dist/*
90 | rules:
91 | - if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9-\.]+)?$/'
92 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 | {one line to give the program's name and a brief idea of what it does.}
635 | Copyright (C) {year} {name of author}
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | {project} Copyright (C) {year} {fullname}
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | .. _bindtool: https://github.com/plinss/bindtool
2 |
3 | *******
4 | acmebot
5 | *******
6 |
7 | ACME protocol automatic certitificate manager.
8 |
9 | This tool acquires and maintains certificates from a certificate authority using the ACME protocol, similar to EFF's Certbot.
10 | While developed and tested using Let's Encrypt, the tool should work with any certificate authority using the ACME protocol.
11 |
12 |
13 | Features
14 | ========
15 |
16 | This tool is not intended as a replacement for Certbot and does not attempt to replicate all of Certbot's functionality,
17 | notably it does not modify configuration files of other services,
18 | or provide a server to perform stand-alone domain validation.
19 | It does however, do a few things that Certbot does not,
20 | simplifying certificate management in more advanced environments.
21 | In addition to automatically issuing and maintaining certificates,
22 | the tool can also maintain associated HPKP headers and TLSA (DANE) records.
23 |
24 |
25 | Master/Follower Mode
26 | --------------------
27 |
28 | This tool separates the authorization (domain validation) and certificate issuance processes allowing one machine to maintain authorizations (the master),
29 | while another machine issues certificates (the follower).
30 | This is useful for situations where an isolated server is providing a service, such as XMPP,
31 | behind a firewall and does not have the ability to perform authorizations over http or configure DNS records,
32 | but still needs to obtain and periodically renew one or more certificates.
33 |
34 |
35 | Sharing of Private Keys Between Certificates
36 | --------------------------------------------
37 |
38 | This tool allows multiple certificates to be defined using the same public/private key pair.
39 |
40 | When deploying Hypertext Puplic Key Pinning (HPKP), you can optionally use the same pins to secure subdomains.
41 | This increases security of the site because a visitor to a root domain will have previously obtained pins for subdomains,
42 | reducing the possibility of a man-in-the-middle attacker installing a false pin on first visit.
43 |
44 | This practice obviously requires the use of the same public/private key pair for the domain and all subdomains.
45 | However, it may not be desirable to use the same certificate for all subdomains, for example,
46 | exposing the full list of subdomains in the alternative names of the root domain's certificate,
47 | or reissuing the root domain's certificate every time a subdomain is added or removed.
48 |
49 |
50 | Hypertext Public Key Pin (HPKP) Support
51 | ---------------------------------------
52 |
53 | This tool automatically generates and maintains HPKP header information suitable to be directly included in server configuraton files.
54 | Support for Apache and Nginx are provided by default, other servers may be added by the user.
55 |
56 |
57 | Automatic Management of Backup Private Keys
58 | -------------------------------------------
59 |
60 | Using HPKP requires a second public key to provide a backup when private keys are changed.
61 | This tool automatically generates backup keys and switches to the pre-generated backup key when rolling over private keys.
62 | Rolling over private keys can be done automatically and is scheduled independently of certificate expiration.
63 | Private key rollover is prevented in cases where insufficient time has passed to distribute backup HPKP pins.
64 |
65 |
66 | Parallel RSA and ECDSA Certificates
67 | -----------------------------------
68 |
69 | This tool can generate both RSA and ECDSA certificates.
70 | By default it will generate and maintain both types of certificates in parallel.
71 |
72 |
73 | Certificate Transparency / Signed Certificate Timestamp Support
74 | ---------------------------------------------------------------
75 |
76 | This tool can automatically register your certificates with multiple certificate transparency logs and retrieve Signed Certificate Timestamps (SCTs) for each.
77 | The retrieved SCTs are suitable to be deilvered via a TLS extension,
78 | SCT TLS extension modules are available for `Apache `_ and `Nginx `_.
79 |
80 |
81 | OCSP Response File Support
82 | --------------------------
83 |
84 | This tool automatically obtains and maintains OCSP response files for each configured certificate.
85 | These files may be used to serve stapled OCSP responses from your server without relying on the server's OCSP stapling mechanisms.
86 | Some servers, such as Nginx, obtain stapled OCSP responses lazily and cache the response in memory.
87 | When using the OCSP Must-Staple extension this can result in your server being unreachable until the OCSP response is refreshed,
88 | during OCSP responder outages, this can be a significant interval.
89 | Using OCSP responses from disk will alleviate this issue.
90 | Only OCSP responses with a "good" status will be stored.
91 |
92 |
93 | Encrypted Private Keys
94 | ----------------------
95 |
96 | Primary and backup private keys can optionally be encrypted using a passphrase and cipher of your choice.
97 |
98 |
99 | Mixed Use of DNS and HTTP Authorization
100 | ---------------------------------------
101 |
102 | By default this tool performs dns-01 authorizartions for domain validation.
103 | It is possible to configure overrides for specific domains names to use http-01 authorization instead.
104 | This is useful for situations where a domain outside your immediate control has provided an alias to your web site.
105 |
106 |
107 | Automatic Local or Remote DNS Updates
108 | -------------------------------------
109 |
110 | This tool can automatically add and remove DNS records for dns-01 authorizations as well as TLSA records.
111 | Updates to a local server can be made via an external zone file processor, such as `bindtool`_,
112 | or to a remote DNS server via RFC 2136 dynamic DNS updates using ``nsupdate``.
113 | The choice between local and remote DNS updates can be made on a zone by zone basis.
114 |
115 |
116 | Configurable Output File Names
117 | ------------------------------
118 |
119 | Server administrators often develop their own file naming conventions or need to match naming conventions of other tools.
120 | The names and output directories of all certificate, key, and related files are fully configurable.
121 | The defaults are intended for standard Debian installations.
122 |
123 |
124 | Configurable Deployment Hooks
125 | -----------------------------
126 |
127 | Each operation that writes key, certificate, or related files have optional hooks that can call user-specified programs to
128 | assist in deploying resources to remote servers or coordinating with other tooling.
129 |
130 |
131 | Certificate Installation Verification
132 | -------------------------------------
133 |
134 | This tool can automatically connect to configured servers and verify that the generated certificates are properly served via TLS.
135 | Additional checks are made for OSCP staples and optionally HPKP headers can be verified as well.
136 |
137 |
138 | ACME Protocol V2 Support
139 | ------------------------
140 |
141 | This tool supports services ACME V2 APIs.
142 |
143 |
144 | Installation
145 | ============
146 |
147 | Requires Python 3.8+ and OpenSSL support.
148 |
149 | On Debian Stretch and later::
150 |
151 | sudo apt-get install python3-pip libssl-dev libffi-dev
152 | sudo pip3 install acmebot
153 |
154 | You may want to create a virtual environment and install acmebot there.
155 | Copy either the ``acmebot.example.json`` file or the ``acmebot.example.yaml`` file to ``acmebot.json`` (or ``acmebot.yaml``) and edit the configuration options.
156 | The configuration file can be placed in the current directory that the tool is run from,
157 | the /etc/acmebot directory,
158 | or the same directory that the acmebot tool is installed in.
159 |
160 | By default, debug level output will be written to a log file.
161 | A configuration file for logrotate is provided in the logrotate.d directory,
162 | you may want to copy, or create a link to this file in /etc/logrotate.d.
163 |
164 | Note that when using dns-01 authorizations via a local DNS server,
165 | this tool needs to be able to add, remove, and update DNS records.
166 | This can be achieved by installing it on your master DNS server and using `bindtool`_ to manage the zone file,
167 | or you can use a custom shell script to update the DNS records.
168 |
169 | When using dns-01 authorizations via a remote server,
170 | an update key allowing the creation and deletion of TXT and optionally TLSA record types is required.
171 |
172 | Optional: some services require a full certificate chain including the root (OSCP stapling on Nginx, for example).
173 | In order to generate these files,
174 | place a copy of the root certificates from your certificate authority of choice in the same directory as the configuration file with the file names ``root_cert.rsa.pem`` and ``root_cert.ecdsa.pem`` for RSA and ECDSA certificate roots respectively.
175 | Note that the root certificates are the those used to sign RSA and ECDSA client certificates,
176 | and may not necessarily be of the same type,
177 | e.g. Let's Encrypt currently signs ECDSA certificates with an RSA root.
178 | If your certificate authority uses RSA certificate to sign ECDSA certificates types, place that RSA root certificate in ``root_cert.ecdsa.pem``.
179 | The root certificate for Let's Encrypt can be obtained `here `_.
180 |
181 |
182 | Upgrade
183 | =======
184 |
185 | Starting with version 2.0.0 of this tool, the Let's Encrypt ACME V2 API is used by default.
186 | When upgrading to version 2.0.0+, or otherwise changing API endpoints,
187 | the client key is regenerated and a new registration is performed.
188 | If running in master/follower mode, be sure to run the tool on the master first,
189 | then copy the new client key and registration files to the followers before running on the followers.
190 | Existing private keys and certificates may continue to be used.
191 |
192 |
193 | Quick Start
194 | ===========
195 |
196 |
197 | Basic Configuration
198 | -------------------
199 |
200 | While the example configuration file may appear complicated,
201 | it is meant to show all possible configuration options and their defaults,
202 | rather than demonstrate a basic simple configuration.
203 |
204 | The only items that must be present in the configuration file to create and maintain a certificate are your account email address,
205 | and the file name for the certificate.
206 | By default, the common name of the certificate will be the same as the certificate file name.
207 |
208 | For example::
209 |
210 | {
211 | "account": {
212 | "email": "admin@example.com"
213 | },
214 | "certificates": {
215 | "example.com": {
216 | "alt_names": {
217 | "example.com": ["@", "www"]
218 | }
219 | }
220 | }
221 | }
222 |
223 | will create a certificate named ``example.com``,
224 | with the common name of ``example.com``,
225 | and the subject alternative names of ``example.com`` and ``www.example.com``.
226 |
227 | As many certificates as desired may be configured.
228 | The number of alternative names is limited by the certificate authority (Let's Encrypt currently allows 100).
229 | Alternative names are specified on a DNS zone basis,
230 | multiple zones may be specified per certificate.
231 | The host name ``"@"`` is used for the name of the zone itself.
232 |
233 |
234 | Authorization Setup
235 | -------------------
236 |
237 | By default, the tool will attempt dns-01 domain authorizations for every alternative name specified,
238 | using local DNS updates.
239 | See the later sections on configuring `local <#configuring-local-dns-updates>`_ or `remote <#configuring-remote-dns-updates>`_ DNS updates.
240 |
241 | To use http-01 authorizations instead,
242 | configure the ``http_challenges`` section of the configuration file specifying a challenge directory for each fully qualified host name.
243 |
244 | For example::
245 |
246 | {
247 | ...
248 | "http_challenges": {
249 | "example.com": "/var/www/htdocs/.well-known/acme-challenge",
250 | "www.example.com": "/var/www/htdocs/.well-known/acme-challenge"
251 | }
252 | }
253 |
254 | See the `HTTP Challenges <#http-challenges>`_ section for more information.
255 |
256 |
257 | First Run
258 | ---------
259 |
260 | Once the configuration file is in place,
261 | simply execute the tool.
262 | For the first run you may wish to select detailed output to see exactly what the tool is doing::
263 |
264 | acmebot --detail
265 |
266 | If all goes well,
267 | the tool will generate a public/private key pair used for client authentication to the certificate authority,
268 | register an account with the certificate authority,
269 | prompt to accept the certificate authority's terms of service,
270 | obtain authorizations for each configured domain name,
271 | generate primary private keys as needed for the configured certificates,
272 | issue certificates,
273 | generate backup private keys,
274 | generate custom Diffie-Hellman parameters,
275 | retrieve Signed Certificate Timestamps from certificate transparency logs,
276 | retrieve an OCSP response from the certificate authority,
277 | and install the certificates and private keys into /etc/ssl/certs and /etc/ssl/private.
278 |
279 | If desired, you can test the tool using Let's Encrypt's staging server.
280 | To do this, specify the staging server's directory URL in the ``acme_directory_url`` setting.
281 | See `Staging Environment `_ for details.
282 | When switching from the staging to production servers,
283 | you should delete the client key and registration files (/var/local/acmebot/\*.json) to ensure a fresh registration in the production environment.
284 |
285 |
286 | File Location
287 | =============
288 |
289 | After a successful certificate issuance,
290 | up to twenty one files will be created per certificate.
291 |
292 | The locations for these files can be controlled via the ``directories`` section of the configuration file.
293 | The default locations are used here for brevity.
294 |
295 | Output files will be written as a single transaction,
296 | either all files will be written,
297 | or no files will be written.
298 | This is designed to prevent a mismatch between certificates and private keys should an error happen during file creation.
299 |
300 |
301 | Private Keys
302 | ------------
303 |
304 | Two private key files will be created in /etc/ssl/private for each key type.
305 | The primary: ``..key``; and a backup key: ``_backup..key``.
306 |
307 | The private key files will be written in PEM format and will be readable by owner and group.
308 |
309 |
310 | Certificate Files
311 | -----------------
312 |
313 | Two certificate files will be created for each key type,
314 | one in /etc/ssl/certs, named ``..pem``,
315 | containing the certificate,
316 | followed by any intermediate certificates sent by the certificate authority,
317 | followed by custom Diffie-Hellman and elliptic curve paramaters;
318 | the second file will be created in /etc/ssl/private, named ``_full..key``,
319 | and will contain the private key,
320 | followed by the certificate,
321 | followed by any intermediate certificates sent by the certificate authority,
322 | followed by custom Diffie-Hellman and elliptic curve paramaters.
323 |
324 | The ``_full..key`` file is useful for services that require both the private key and certificate to be in the same file,
325 | such as ZNC.
326 |
327 |
328 | Intermediate Certificate Chain File
329 | -----------------------------------
330 |
331 | If the certificate authority uses intermediate certificates to sign your certificates,
332 | a file will be created in /etc/ssl/certs, named ``_chain..pem`` for each key type,
333 | containing the intermediate certificates sent by the certificate authority.
334 |
335 | This file will not be created if the ``chain`` directory is set to ``null``.
336 |
337 | Note that the certificate authority may use a different type of certificate as intermediates,
338 | e.g. an ECDSA client certificate may be signed by an RSA intermediate,
339 | and therefore the intermediate certificate key type may not match the file name (or certificate type).
340 |
341 |
342 | Full Chain Certificate File
343 | ---------------------------
344 |
345 | If the ``root_cert..pem`` file is present (see `Installation <#installation>`_),
346 | then an additional certificate file will be generated in /etc/ssl/certs,
347 | named ``+root..pem`` for each key type.
348 | This file will contain the certificate,
349 | followed by any intermediate certificates sent by the certificate authority,
350 | followed by the root certificate,
351 | followed by custom Diffie-Hellman and elliptic curve paramaters.
352 |
353 | If the ``root_cert..pem`` file is not found in the same directory as the configuration file,
354 | this certificate file will not be created.
355 |
356 | This file is useful for configuring OSCP stapling on Nginx servers.
357 |
358 |
359 | Diffie-Hellman Parameter File
360 | -----------------------------
361 |
362 | If custom Diffie-Hellman parameters or a custom elliptical curve are configured,
363 | a file will be created in /etc/ssl/params, named ``_param.pem``,
364 | containing the Diffie-Hellman parameters and elliptical curve paramaters.
365 |
366 | This file will not be created if the ``param`` directory is set to ``null``.
367 |
368 |
369 | Hypertext Public Key Pin (HPKP) Files
370 | -------------------------------------
371 |
372 | Two additional files will be created in /etc/ssl/hpkp, named ``.apache`` and ``.nginx``.
373 | These files contain HTTP header directives setting HPKP for both the primary and backup private keys for each key type.
374 |
375 | Each file is suitable to be included in the server configuration for either Apache or Nginx respectively.
376 |
377 | Thess files will not be created if the ``hpkp`` directory is set to ``null``.
378 |
379 |
380 | Signed Certificate Timestamp (SCT) Files
381 | ----------------------------------------
382 |
383 | One additional file will be created for each key type and configured certificate transparency log in ``/etc/ssl/scts///.sct``.
384 | These files contain SCT information in binary form suitable to be included in a TLS extension.
385 | By default, SCTs will be retrieved from the Google Icarus and Google Pilot certificate transparency logs.
386 | The Google Test Tube certificate transparency log can be used with the Let's Encrypt staging environment for testing.
387 |
388 |
389 | OCSP Response Files
390 | -------------------
391 | One OCSP response file will be created for each key type,
392 | in /etc/ssl/ocsp, named ``..ocsp``.
393 | These files contain OCSP responses in binary form suitable to be used as stapled OCSP responses.
394 |
395 |
396 | Archive Directory
397 | -----------------
398 |
399 | Whenever exsiting files are replaced by subsequent runs of the tool,
400 | for example during certificate renewal or private key rollover,
401 | all existing files are preserved in the archive directory, /etc/ssl/archive.
402 |
403 | Within the archive directory,
404 | a directory will be created with the name of the private key,
405 | containing a datestamped directory with the time of the file transaction (YYYY_MM_DD_HHMMSS).
406 | All existing files will be moved into the datestamped directory should they need to be recovered.
407 |
408 |
409 | Server Configuration
410 | ====================
411 |
412 | Because certificate files will be periodically replaced as certificates need to be renewed,
413 | it is best to have your server configurations simply refer to the certificate and key files in the locations they are created.
414 | This will prevent server configurations from having to be updated as certificate files are replaced.
415 |
416 | If the server requires the certificate or key file to be in a particular location or have a different file name,
417 | it is best to simply create a soft link to the certificate or key file rather than rename or copy the files.
418 |
419 | Another good practice it to isolate the configuration for each certificate into a snippet file,
420 | for example using Apache,
421 | create the file /etc/apache2/snippets/ssl/example.com containing::
422 |
423 | SSLCertificateFile /etc/ssl/certs/example.com.rsa.pem
424 | SSLCertificateKeyFile /etc/ssl/private/example.com.rsa.key
425 | CTStaticSCTs /etc/ssl/certs/example.com.rsa.pem /etc/ssl/scts/example.com/rsa # requires mod_ssl_ct to be installed
426 |
427 | SSLCertificateFile /etc/ssl/certs/example.com.ecdsa.pem
428 | SSLCertificateKeyFile /etc/ssl/private/example.com.ecdsa.key
429 | CTStaticSCTs /etc/ssl/certs/example.com.ecdsa.pem /etc/ssl/scts/example.com/ecdsa # requires mod_ssl_ct to be installed
430 |
431 | Header always set Strict-Transport-Security "max-age=63072000"
432 | Include /etc/ssl/hpkp/example.com.apache
433 |
434 | and then in each host configuration using that certificate, simply add::
435 |
436 | Include snippets/ssl/example.com
437 |
438 | For Nginx the /etc/nginx/snippets/ssl/example.com file would contain::
439 |
440 | ssl_ct on; # requires nginx-ct module to be installed
441 |
442 | ssl_certificate /etc/ssl/certs/example.com.rsa.pem;
443 | ssl_certificate_key /etc/ssl/private/example.com.rsa.key;
444 | ssl_ct_static_scts /etc/ssl/scts/example.com/rsa; # requires nginx-ct module to be installed
445 | ssl_stapling_file /etc/ssl/ocsp/example.com.rsa.ocsp;
446 |
447 | ssl_certificate /etc/ssl/certs/example.com.ecdsa.pem; # requires nginx 1.11.0+ to use multiple certificates
448 | ssl_certificate_key /etc/ssl/private/example.com.ecdsa.key;
449 | ssl_ct_static_scts /etc/ssl/scts/example.com/ecdsa; # requires nginx-ct module to be installed
450 | ssl_stapling_file /etc/ssl/ocsp/example.com.ecdsa.ocsp; # requires nginx 1.13.3+ to use with multiple certificates
451 |
452 | ssl_trusted_certificate /etc/ssl/certs/example.com+root.rsa.pem; # not required if using ssl_stapling_file
453 |
454 | ssl_dhparam /etc/ssl/params/example.com_param.pem;
455 | ssl_ecdh_curve secp384r1;
456 |
457 | add_header Strict-Transport-Security "max-age=63072000" always;
458 | include /etc/ssl/hpkp/example.com.nginx;
459 |
460 | and can be used via::
461 |
462 | include snippets/ssl/example.com;
463 |
464 |
465 | Configuration
466 | =============
467 |
468 | The configuration file ``acmebot.json`` or ``acmebot.yaml`` may be placed in the current working directory,
469 | in /etc/acmebot,
470 | or in the same directory as the acmebot tool is installed in.
471 | A different configuration file name may be specified on the command line.
472 | If the specified file name is not an absolute path,
473 | it will be searched for in the same locations,
474 | e.g. ``acmebot --config config.json`` will load ``./config.json``, ``/etc/acmebot/config.json``, or ``/config.json``.
475 | If the file extension is omitted, the tool will search for a file with the extensions: ``.json``, ``.yaml``, and ``.yml`` in each location.
476 | If the speficied file is an absolute path,
477 | only that location will be searched.
478 |
479 | Additional configuration files may be placed in a subdirectory named ``conf.d`` in the same directory as the configuration file.
480 | All files with the extensions: ``.json``, ``.yaml``, or ``.yml`` in that subdirectory will be loaded and merged into the configuration,
481 | overriding any settings in the main configuration file.
482 | For example,
483 | the configurtaion for each certificate may be placed in a separate file,
484 | while the common settings remain in the main configuration file.
485 |
486 | The configuration file must adhere to standard JSON or YAML formats.
487 | The examples given in this document are in JSON format, however, the equivalent structures may be expressed in YAML.
488 |
489 | The files ``acmebot.example.json`` and ``acmebot.example.yaml`` provide a template of all configuration options and their default values.
490 | Entries inside angle brackets ``""`` must be replaced (without the angle brackets),
491 | all other values may be removed unless you want to override the default values.
492 |
493 |
494 | Account
495 | -------
496 |
497 | Enter the email address you wish to associate with your account on the certificate authority.
498 | This email address may be useful in recovering your account should you lose access to your client key.
499 |
500 | Example::
501 |
502 | {
503 | "account": {
504 | "email": "admin@example.com"
505 | },
506 | ...
507 | }
508 |
509 |
510 | Settings
511 | --------
512 |
513 | Various settings for the tool.
514 | All of these need only be present when the desired value is different from the default.
515 |
516 | * ``follower_mode`` specifies if the tool should run in master or follower mode.
517 | The defalt value is ``false`` (master mode).
518 | The master will obtain authorizations and issue certificates,
519 | a follower will not attempt to obtain authorizations but can issue certificates.
520 | * ``log_level`` specifies the amount of information written into the log file.
521 | Possible values are ``null``, ``"normal"``, ``"verbose"``, ``"debug"``, and ``"detail"``.
522 | ``"verbose"``, ``"debug"``, and ``"detail"`` settings correlate to the ``--verbose``, ``--debug`` and ``--detail`` command-line options.
523 | * ``color_output`` specifies if the output should be colorized.
524 | Colorized output will be suppressed on non-tty devices.
525 | This option may be overridden via command line options.
526 | The default value is ``true``.
527 | * ``key_types`` specifies the types of private keys to generate by default.
528 | The default value is ``['rsa', 'ecdsa']``.
529 | * ``key_size`` specifies the size (in bits) for RSA private keys.
530 | The default value is ``4096``.
531 | RSA certificates can be turned off by setting this value to ``0`` or ``null``.
532 | * ``key_curve`` specifies the curve to use for ECDSA private keys.
533 | The default value is ``"secp384r1"``.
534 | Available curves are ``"secp256r1"``, ``"secp384r1"``, and ``"secp521r1"``.
535 | ECDSA certificates can be turned off by setting this value to ``null``.
536 | * ``key_cipher`` specifies the cipher algorithm used to encrypt private keys.
537 | The default value is ``"blowfish"``.
538 | Available ciphers are those accepted by your version of OpenSSL's EVP_get_cipherbyname().
539 | * ``key_passphrase`` specifies the passphrase used to encrypt private keys.
540 | The default value is ``null``.
541 | A value of ``null`` or ``false`` will result in private keys being written unencrypted.
542 | A value of ``true`` will cause the password to be read from the command line, the environment, a prompt, or stdin.
543 | A string value will be used as the passphrase without further input.
544 | * ``key_provided`` specifies that the private keys are provided from an external source and the tool should not modify them.
545 | The default value is ``false``.
546 | * ``dhparam_size`` specifies the size (in bits) for custom Diffie-Hellman parameters.
547 | The default value is ``2048``.
548 | Custom Diffie-Hellman parameters can be turned off by setting this value to ``0`` or ``null``.
549 | This value should be at least be equal to half the ``key_size``.
550 | * ``ecparam_curve`` speficies the curve or list of curves to use for ECDHE negotiation.
551 | This value may be a string or a list of strings.
552 | The default value is ``["secp521r1", "secp384r1", "secp256k1"]``.
553 | Custom EC parameters can be turned off by setting this value to ``null``.
554 | You can run ``openssl ecparam -list_curves`` to find a list of available curves.
555 | * ``file_user`` specifies the name of the user that will own certificate and private key files.
556 | The default value is ``"root"``.
557 | Note that this tool must run as root, or another user that has rights to set the file ownership to this user.
558 | * ``file_group`` speficies the name of the group that will own certificate and private key files.
559 | The default value is ``"ssl-cert"``.
560 | Note that this tool must run as root, or another user that has rights to set the file ownership to this group.
561 | * ``log_user`` specifies the name of the user that will own log files.
562 | The default value is ``"root"``.
563 | Note that this tool must run as root, or another user that has rights to set the file ownership to this user.
564 | * ``log_group`` speficies the name of the group that will own log files.
565 | The default value is ``"adm"``.
566 | Note that this tool must run as root, or another user that has rights to set the file ownership to this group.
567 | * ``warning_exit_code`` specifies if warnings will produce a non-zero exit code.
568 | The default value is ``false``.
569 | * ``hpkp_days`` specifies the number of days that HPKP pins should be cached for.
570 | The default value is ``60``.
571 | HPKP pin files can be turned off by setting this value to ``0`` or ``null``.
572 | * ``pin_subdomains`` specifies whether the ``includeSubdomains`` directive should be included in the HPKP headers.
573 | The default value is ``true``.
574 | * ``hpkp_report_uri`` specifies the uri to report HPKP failures to.
575 | The default value is ``null``.
576 | If not null, the ``report-uri`` directive will be included in the HPKP headers.
577 | * ``ocsp_must_staple`` specifies if the OCSP Must-Staple extension is added to certificates.
578 | The default value is ``false``.
579 | * ``ocsp_responder_urls`` specifies the list of OCSP responders to use if a certificate doesn't provide them.
580 | The default value is ``["http://ocsp.int-x3.letsencrypt.org"]``.
581 | * ``ct_submit_logs`` specifies the list of certificate transparency logs to submit certificates to.
582 | The default value is ``["google_icarus", "google_pilot"]``.
583 | The value ``["google_testtube"]`` can be used with the Let's Encrypt staging environment for testing.
584 | * ``renewal_days`` specifies the number of days before expiration when the tool will attempt to renew a certificate.
585 | The default value is ``30``.
586 | * ``expiration_days`` specifies the number of days that private keys should be used for.
587 | The dafault value is ``730`` (two years).
588 | When the backup key reaches this age,
589 | the tool will notify the user that a key rollover should be performed,
590 | or automatically rollover the private key if ``auto_rollover`` is set to ``true``.
591 | Automatic rollover and expiration notices can be disabled by setting this to ``0`` or ``null``.
592 | * ``auto_rollover`` specifies if the tool should automatically rollover private keys that have expired.
593 | The default value is ``false``.
594 | Note that when running in a master/follower configuration and sharing private keys between the master and follower,
595 | key rollovers must be performed on the master and manually transferred to the follower,
596 | therefore automatic rollovers should not be used unless running stand-alone.
597 | * ``max_dns_lookup_attempts`` specifies the number of times to check for deployed DNS records before attempting authorizations.
598 | The default value is ``60``.
599 | * ``dns_lookup_delay`` specifies the number of seconds to wait between DNS lookups.
600 | The default value is ``10``.
601 | * ``max_domains_per_order`` specifies the maximum number of domains allowed per authorization order.
602 | The default value is ``100``, which is the limit set by Let's Encrypt.
603 | * ``max_authorization_attempts`` specifies the number of times to check for completed authorizations.
604 | The default value is ``30``.
605 | * ``authorization_delay`` specifies the number of seconds to wait between authorization checks.
606 | The default value is ``10``.
607 | * ``cert_poll_time`` specifies the number of seconds to wait for a certificate to be issued.
608 | The default value is ``30``.
609 | * ``max_ocsp_verify_attempts`` specifies the number of times to check for OCSP staples during verification.
610 | Retries will only happen when the certificate has the OCSP Must-Staple extension.
611 | The default value is ``10``.
612 | * ``ocsp_verify_retry_delay`` specifies the number of seconds to wait between OCSP staple verification attempts.
613 | The default value is ``5``.
614 | * ``min_run_delay`` specifies the minimum number of seconds to wait if the ``--randomwait`` command line option is present.
615 | The default value is ``300``.
616 | * ``max_run_delay`` specifies the maximum number of seconds to wait if the ``--randomwait`` command line option is present.
617 | The default value is ``3600``.
618 | * ``acme_directory_url`` specifies the primary URL for the ACME service.
619 | The default value is ``"https://acme-v02.api.letsencrypt.org/directory"``, the Let's Encrypt production API.
620 | You can substitute the URL for Let's Encrypt's staging environment or another certificate authority.
621 | * ``acme_directory_verify_ssl`` specifies whether or not to verify the certificate of the ACME service.
622 | The default value is ``True``.
623 | Setting this to ``False`` is not recommneded, but may be necessary in environments using a private ACME server.
624 | * ``reload_zone_command`` specifies the command to execute to reload local DNS zone information.
625 | When using `bindtool`_ the ``"reload-zone.sh"`` script provides this service.
626 | If not using local DNS updates, you may set this to ``null`` to avoid warnings.
627 | * ``nsupdate_command`` specifies the command to perform DNS updates.
628 | The default value is ``"/usr/bin/nsupdate"``.
629 | * ``verify`` specifies the default ports to perform installation verification on.
630 | The default value is ``null``.
631 | * ``services`` specifies the default services to associate with certificates.
632 | The default value is ``null``.
633 |
634 | Example::
635 |
636 | {
637 | ...
638 | "settings": {
639 | "follower_mode": false,
640 | "log_level": "debug",
641 | "key_size": 4096,
642 | "key_curve": "secp384r1",
643 | "key_cipher": "blowfish",
644 | "key_passphrase": null,
645 | "key_provided": false,
646 | "dhparam_size": 2048,
647 | "ecparam_curve": ["secp521r1", "secp384r1", "secp256k1"],
648 | "file_user": "root",
649 | "file_group": "ssl-cert",
650 | "hpkp_days": 60,
651 | "pin_subdomains": true,
652 | "hpkp_report_uri": null,
653 | "ocsp_must_staple": false,
654 | "ocsp_responder_urls": ["http://ocsp.int-x3.letsencrypt.org"],
655 | "ct_submit_logs": ["google_icarus", "google_pilot"],
656 | "renewal_days": 30,
657 | "expiration_days": 730,
658 | "auto_rollover": false,
659 | "max_dns_lookup_attempts": 60,
660 | "dns_lookup_delay": 10,
661 | "max_authorization_attempts": 30,
662 | "authorization_delay": 10,
663 | "min_run_delay": 300,
664 | "max_run_delay": 3600,
665 | "acme_directory_url": "https://acme-v02.api.letsencrypt.org/directory",
666 | "reload_zone_command": "/etc/bind/reload-zone.sh",
667 | "nsupdate_command": "/usr/bin/nsupdate",
668 | "verify": [443]
669 | },
670 | ...
671 | }
672 |
673 |
674 | Directories
675 | -----------
676 |
677 | Directories used to store the input and output files of the tool.
678 | Relative paths will be considered relative to the directory of configuration file.
679 | All of these need only be present when the desired value is different from the default.
680 |
681 | * ``pid`` specifies the directory to store a process ID file.
682 | The default value is ``"/var/run"``.
683 | * ``log`` specifies the directory to store the log file.
684 | The default value is ``"/var/log/acmebot"``.
685 | * ``resource`` specifies the directory to store the client key and registration files for the ACME account.
686 | The default value is ``"/var/local/acmebot"``.
687 | * ``private_key`` specifies the directory to store primary private key files.
688 | The default value is ``"/etc/ssl/private"``.
689 | * ``backup_key`` specifies the directory to store backup private key files.
690 | The default value is ``"/etc/ssl/private"``.
691 | * ``previous_key`` specifies the directory to store previously used private key files after key rollover.
692 | The default value is ``null``.
693 | * ``full_key`` specifies the directory to store primary private key files that include the certificate chain.
694 | The default value is ``"/etc/ssl/private"``.
695 | Full key files may be omitted by setting this to ``null``.
696 | * ``certificate`` specifies the directory to store certificate files.
697 | The default value is ``"/etc/ssl/certs"``.
698 | * ``full_certificate`` specifies the directory to store full chain certificate files that include the root certificate.
699 | The default value is ``"/etc/ssl/certs"``.
700 | Full certificate files may be omitted by setting this to ``null``.
701 | * ``chain`` specifies the directory to store certificate intermediate chain files.
702 | The default value is ``"/etc/ssl/certs"``.
703 | Chain files may be omitted by setting this to ``null``.
704 | * ``param`` specifies the directory to store Diffie-Hellman parameter files.
705 | The default value is ``"/etc/ssl/params"``.
706 | Paramater files may be omitted by setting this to ``null``.
707 | * ``challenge`` specifies the directory to store ACME dns-01 challenge files.
708 | The default value is ``"/etc/ssl/challenge"``.
709 | * ``http_challenge`` specifies the directory to store ACME http-01 challenge files.
710 | The default value is ``null``.
711 | * ``hpkp`` specifies the directory to store HPKP header files.
712 | The default value is ``"/etc/ssl/hpkp"``.
713 | HPKP header files may be turned off by setting this to ``null``.
714 | * ``sct`` specifies the directory to store Signed Certificate Timestamp files.
715 | The default value is ``"/etc/ssl/scts//"``.
716 | SCT files may be turned off by setting this to ``null``.
717 | * ``ocsp`` specifies the directory to store OCSP response files.
718 | The default value is ``"/etc/ssl/ocsp"``.
719 | OCSP response files may be turned off by setting this to ``null``.
720 | * ``update_key`` specifies the directory to search for DNS update key files.
721 | The default value is ``"/etc/ssl/update_keys"``.
722 | * ``archive`` specifies the directory to store older versions of files that are replaced by this tool.
723 | The default value is ``"/etc/ssl/archive"``.
724 | * ``temp`` specifies the directory to write temporary files to.
725 | A value of ``null`` results in using the system defined temp directory.
726 | The temp directory must be on the same file system as the output file directories.
727 | The default value is ``null``.
728 |
729 | Example::
730 |
731 | {
732 | ...
733 | "directories": {
734 | "pid": "/var/run",
735 | "log": "/var/log/acmebot",
736 | "resource": "/var/local/acmebot",
737 | "private_key": "/etc/ssl/private",
738 | "backup_key": "/etc/ssl/private",
739 | "full_key": "/etc/ssl/private",
740 | "certificate": "/etc/ssl/certs",
741 | "full_certificate": "/etc/ssl/certs",
742 | "chain": "/etc/ssl/certs",
743 | "param": "/etc/ssl/params",
744 | "challenge": "/etc/ssl/challenges",
745 | "http_challenge": "/var/www/{zone}/{host}/.well-known/acme-challenge",
746 | "hpkp": "/etc/ssl/hpkp",
747 | "ocsp": "/etc/ssl/ocsp/",
748 | "sct": "/etc/ssl/scts/{name}/{key_type}",
749 | "update_key": "/etc/ssl/update_keys",
750 | "archive": "/etc/ssl/archive"
751 | },
752 | ...
753 | }
754 |
755 | Directory values are treated as Python format strings,
756 | fields available for directories are: ``name``, ``key_type``, ``suffix``, ``server``.
757 | The ``name`` field is the name of the private key or certificate.
758 | The ``"http_challenge"`` directory uses the fields: ``zone``, ``host``, and ``fqdn``,
759 | for the zone name, host name (without the zone), and the fully qualified domain name respectively.
760 | The ``host`` value will be ``"."`` if the fqdn is the same as the zone name.
761 |
762 |
763 | Services
764 | --------
765 |
766 | This specifies a list of services that are used by issued certificates and the commands necessary to restart or reload the service when a certificate is issued or changed.
767 | You may add or remove services as needed.
768 | The list of services is arbritrary and they are referenced from individual certificate definitions.
769 |
770 | Example::
771 |
772 | {
773 | ...
774 | "services": {
775 | "apache": "systemctl reload apache2",
776 | "coturn": "systemctl restart coturn",
777 | "dovecot": "systemctl restart dovecot",
778 | "etherpad": "systemctl restart etherpad",
779 | "mysql": "systemctl reload mysql",
780 | "nginx": "systemctl reload nginx",
781 | "postfix": "systemctl reload postfix",
782 | "postgresql": "systemctl reload postgresql",
783 | "prosody": "systemctl restart prosody",
784 | "slapd": "systemctl restart slapd",
785 | "synapse": "systemctl restart matrix-synapse",
786 | "znc": "systemctl restart znc"
787 | },
788 | ...
789 | }
790 |
791 | To specify one or more services used by a certificate,
792 | add a ``services`` section to the certificate definition listing the services using that certificate.
793 |
794 | For example::
795 |
796 | {
797 | "certificates": {
798 | "example.com": {
799 | "alt_names": {
800 | "example.com": ["@", "www"]
801 | },
802 | "services": ["nginx"]
803 | }
804 | }
805 | }
806 |
807 | This will cause the command ``"systemctl reload nginx"`` to be executed any time the certificate ``example.com`` is issued, renewed, or updated.
808 |
809 |
810 | Certificates
811 | ------------
812 |
813 | This section defines the set of certificates to issue and maintain.
814 | The name of each certificate is used as the name of the certificate files.
815 |
816 | * ``common_name`` specifies the common name for the certificate.
817 | If omitted, the name of the certificate will be used.
818 | * ``alt_names`` specifies the set of subject alternative names for the certificate.
819 | If specified, the common name of the certificate must be included as one of the alternative names.
820 | The alternative names are specified as a list of host names per DNS zone,
821 | so that associated DNS updates happen in the correct zone.
822 | The zone name may be used directly by specifying ``"@"`` for the host name.
823 | Multiple zones may be specified.
824 | The default value is the common name of the certificate in the zone of the first registered domain name according to the `Public Suffix List `_.
825 | For example, if the common name is "example.com", the default ``alt_names`` will be: ``{"example.com": ["@"] }``;
826 | if the common name is "foo.bar.example.com", the default ``alt_names`` will be: ``{ "example.com": ["foo.bar"] }``.
827 | * ``services`` specifies the list of services to be reloaded when the certificate is issued, renewed, or modified.
828 | This may be omitted.
829 | The default value is the value specified in the ``settings`` section.
830 | * ``dhparam_size`` specifies the number of bits to use for custom Diffie-Hellman paramaters for the certificate.
831 | The default value is the value specified in the ``settings`` section.
832 | Custom Diffie-Hellman paramaters may be ommitted from the certificate by setting this to ``0`` or ``null``.
833 | The value should be at least equal to half the number of bits used for the private key.
834 | * ``ecparam_curve`` specified the curve or curves used for elliptical curve paramaters.
835 | The default value is the value specified in the ``settings`` section.
836 | Custom elliptical curve paramaters may be ommitted from the certificate by setting this to ``null``.
837 | * ``key_types`` specifies the types of keys to create for this certificate.
838 | The default value is all available key types.
839 | Provide a list of key types to restrict the certificate to only those types.
840 | Available types are ``"rsa"`` and ``"ecdsa"``.
841 | * ``key_size`` specifies the number of bits to use for the certificate's RSA private key.
842 | The default value is the value specified in the ``settings`` section.
843 | RSA certificates can be turned off by setting this value to ``0`` or ``null``.
844 | * ``key_curve`` specifies the curve to use for ECDSA private keys.
845 | The default value is the value specified in the ``settings`` section.
846 | Available curves are ``"secp256r1"``, ``"secp384r1"``, and ``"secp521r1"``.
847 | ECDSA certificates can be turned off by setting this value to ``null``.
848 | * ``key_cipher`` specifies the cipher algorithm used to encrypt the private keys.
849 | The default value is the value specified in the ``settings`` section.
850 | Available ciphers those accepted by your version of OpenSSL's EVP_get_cipherbyname().
851 | * ``key_passphrase`` specifies the passphrase used to encrypt private keys.
852 | The default value is the value specified in the ``settings`` section.
853 | A value of ``null`` or ``false`` will result in private keys being written unencrypted.
854 | A value of ``true`` will cause the password to be read from the command line, the environment, a prompt, or stdin.
855 | A string value will be used as the passphrase without further input.
856 | * ``key_provided`` specifies that the private keys are provided from an external source and the tool should not modify them.
857 | The default value is the value specified in the ``settings`` section.
858 | This is useful when the same private keys are shared between multiple instances of the tool, e.g. for HPKP purposes.
859 | * ``expiration_days`` specifies the number of days that the backup private key should be considered valid.
860 | The default value is the value specified in the ``settings`` section.
861 | When the backup key reaches this age,
862 | the tool will notify the user that a key rollover should be performed,
863 | or automatically rollover the private key if ``auto_rollover`` is set to ``true``.
864 | Automatic rollover and expiration notices can be disabled by setting this to ``0`` or ``null``.
865 | * ``auto_rollover`` specifies if the tool should automatically rollover the private key when it expires.
866 | The default value is the value specified in the ``settings`` section.
867 | * ``hpkp_days`` specifies the number of days that HPKP pins should be cached by clients.
868 | The default value is the value specified in the ``settings`` section.
869 | HPKP pin files can be turned off by setting this value to ``0`` or ``null``.
870 | * ``pin_subdomains`` specifies whether the ``includeSubdomains`` directive should be included in the HPKP headers.
871 | The default value is the value specified in the ``settings`` section.
872 | * ``hpkp_report_uri`` specifies the uri to report HPKP errors to.
873 | The default value is the value specified in the ``settings`` section.
874 | If not null, the ``report-uri`` directive will be included in the HPKP headers.
875 | * ``ocsp_must_staple`` specifies if the OCSP Must-Staple extension is added to certificates.
876 | The default value is the value specified in the ``settings`` section.
877 | * ``ocsp_responder_urls`` specifies the list of OCSP responders to use if a certificate doesn't provide them.
878 | The default value is the value specified in the ``settings`` section.
879 | * ``ct_submit_logs`` specifies the list of certificate transparency logs to submit the certificate to.
880 | The default value is the value specified in the ``settings`` section.
881 | The value ``["google_testtube"]`` can be used with the Let's Encrypt staging environment for testing.
882 | * ``verify`` specifies the list of ports to perform certificate installation verification on.
883 | The default value is the value specified in the ``settings`` section.
884 |
885 | Example::
886 |
887 | {
888 | ...
889 | "certificates": {
890 | "example.com": {
891 | "common_name": "example.com",
892 | "alt_names": {
893 | "example.com": ["@", "www"]
894 | },
895 | "services": ["nginx"],
896 | "dhparam_size": 2048,
897 | "ecparam_curve": ["secp521r1", "secp384r1", "secp256k1"],
898 | "key_types": ["rsa", "ecdsa"],
899 | "key_size": 4096,
900 | "key_curve": "secp384r1",
901 | "key_cipher": "blowfish",
902 | "key_passphrase": null,
903 | "key_provided": false,
904 | "expiration_days": 730,
905 | "auto_rollover": false,
906 | "hpkp_days": 60,
907 | "pin_subdomains": true,
908 | "hpkp_report_uri": null,
909 | "ocsp_must_staple": false,
910 | "ocsp_responder_urls": ["http://ocsp.int-x3.letsencrypt.org"],
911 | "ct_submit_logs": ["google_icarus", "google_pilot"],
912 | "verify": [443]
913 | }
914 | }
915 | }
916 |
917 |
918 | Private Keys
919 | ------------
920 |
921 | This section defines the set of private keys generated and their associated certificates.
922 | Multiple certificates may share a single private key.
923 | This is useful when it is desired to use different certificates for certain subdomains,
924 | while specifying HPKP headers for a root domain that also apply to subdomains.
925 |
926 | The name of each private key is used as the file name for the private key files.
927 |
928 | Note that a certificate configured in the ``certificates`` section is equivalent to a private key configured in this section with a single certificate using the same name as the private key.
929 | As such, it is an error to specify a certificate using the same name in both the ``certificates`` and ``private_keys`` sections.
930 |
931 | The private key and certificate settings are identical to those specified in the ``certificates`` section,
932 | except settings relevant to the private key: ``key_size``, ``key_curve``, ``key_cipher``, ``key_passphrase``, ``key_provided``, ``expiration_days``, ``auto_rollover``, ``hpkp_days``, ``pin_subdomains``, and ``hpkp_report_uri`` are specified in the private key object rather than the certificate object.
933 | The ``key_types`` setting may be specified in the certificate, private key, or both.
934 |
935 | Example::
936 |
937 | {
938 | ...
939 | "private_keys": {
940 | "example.com": {
941 | "certificates": {
942 | "example.com": {
943 | "common_name": "example.com",
944 | "alt_names": {
945 | "example.com": ["@", "www"]
946 | },
947 | "services": ["nginx"],
948 | "key_types": ["rsa"],
949 | "dhparam_size": 2048,
950 | "ecparam_curve": ["secp521r1", "secp384r1", "secp256k1"],
951 | "ocsp_must_staple": true,
952 | "ct_submit_logs": ["google_icarus", "google_pilot"],
953 | "verify": [443]
954 | },
955 | "mail.example.com": {
956 | "alt_names": {
957 | "example.com": ["mail", "smtp"]
958 | },
959 | "services": ["dovecot", "postfix"],
960 | "key_types": ["rsa", "ecdsa"]
961 | }
962 | },
963 | "key_types": ["rsa", "ecdsa"],
964 | "key_size": 4096,
965 | "key_curve": "secp384r1",
966 | "key_cipher": "blowfish",
967 | "key_passphrase": null,
968 | "key_provided": false,
969 | "expiration_days": 730,
970 | "auto_rollover": false,
971 | "hpkp_days": 60,
972 | "pin_subdomains": true,
973 | "hpkp_report_uri": null
974 | }
975 | },
976 | ...
977 | }
978 |
979 | The above example will generate a single primary/backup private key set and two certificates, ``example.com`` and ``mail.example.com`` both using the same private keys.
980 | An ECDSA certicicate will only be generated for ``mail.example.com``.
981 |
982 |
983 | TLSA Records
984 | ------------
985 |
986 | When using remote DNS updates,
987 | it is possible to have the tool automatically maintain TLSA records for each certificate.
988 | Note that this requires configuring zone update keys for each zone containing a TLSA record.
989 |
990 | When using local DNS updates, the ``reload_zone`` command will be called after certificates are issued, renewed, or modified to allow TLSA records to be updated by a tool such as `bindtool`_.
991 | The ``reload_zone`` command will not be called in follower mode.
992 |
993 | To specify TLSA records, add a ``tlsa_records`` name/object pair to each certificate definition, either in the ``certificates`` or ``private_keys`` section.
994 | TLSA records are specified per DNS zone, similar to ``alt_names``,
995 | to specify which zone should be updated for each TLSA record.
996 |
997 | For each zone in the TLSA record object,
998 | specify a list of either host name strings or objects.
999 | Using a host name string is equivalent to::
1000 |
1001 | {
1002 | "host": ""
1003 | }
1004 |
1005 | The values for the objects are:
1006 |
1007 | * ``host`` specifies the host name for the TLSA record.
1008 | The default value is ``"@"``.
1009 | The host name ``"@"`` is used for the name of the zone itself.
1010 | * ``port`` specifies the port number for the TLSA record.
1011 | The default value is ``443``.
1012 | * ``usage`` is one of the following: ``"pkix-ta"``, ``"pkix-ee"``, ``"dane-ta"``, or ``"dane-ee"``.
1013 | The default value is ``"pkix-ee"``.
1014 | When specifying an end effector TLSA record (``"pkix-ee"`` or ``"dane-ee"``),
1015 | the hash generated will be of the certificate or public key itself.
1016 | When specifying a trust anchor TLSA record (``"pkix-ta"`` or ``"dane-ta"``),
1017 | records will be generated for each of the intermediate and root certificates.
1018 | * ``selector`` is one of the following: ``"cert"``, or ``"spki"``.
1019 | The default value is ``"spki"``.
1020 | When specifying a value of ``"spki"`` and an end effector usage,
1021 | records will be generated for both the primary and backup public keys.
1022 | * ``protocol`` specifies the protocol for the TLSA record.
1023 | The default value is ``"tcp"``.
1024 | * ``ttl`` specifies the TTL value for the TLSA records.
1025 | The default value is ``300``.
1026 |
1027 | Example::
1028 |
1029 | {
1030 | ...
1031 | "private_keys": {
1032 | "example.com": {
1033 | "certificates": {
1034 | "example.com": {
1035 | "alt_names": {
1036 | "example.com": ["@", "www"]
1037 | },
1038 | "services": ["nginx"],
1039 | "tlsa_records": {
1040 | "example.com": [
1041 | "@",
1042 | {
1043 | "host": "www",
1044 | "port": 443,
1045 | "usage": "pkix-ee",
1046 | "selector": "spki",
1047 | "protocol": "tcp",
1048 | "ttl": 300
1049 | }
1050 | ]
1051 | }
1052 | },
1053 | "mail.example.com": {
1054 | "alt_names": {
1055 | "example.com": ["mail", "smtp"]
1056 | },
1057 | "services": ["dovecot", "postfix"],
1058 | "tlsa_records": {
1059 | "example.com": [
1060 | {
1061 | "host": "mail",
1062 | "port": 993
1063 | },
1064 | {
1065 | "host": "smtp",
1066 | "port": 25,
1067 | "usage": "dane-ee"
1068 | },
1069 | {
1070 | "host": "smtp",
1071 | "port": 587
1072 | }
1073 | }
1074 | }
1075 | }
1076 | }
1077 | }
1078 | },
1079 | ...
1080 | }
1081 |
1082 |
1083 | Authorizations
1084 | --------------
1085 |
1086 | This section specifies a set of host name authorizations to obtain without issuing certificates.
1087 |
1088 | This is used when running in a master/follower configuration,
1089 | the master, having access to local or remote DNS updates or an HTTP server,
1090 | obtains authorizations,
1091 | while the follower issues the certificates.
1092 |
1093 | It is not necessary to specify host name authorizations for any host names used by configured certificates,
1094 | but it is not an error to have overlap.
1095 |
1096 | Authorizations are specified per DNS zone so that associated DNS updates happen in the correct zone.
1097 |
1098 | Simplar to ``alt-names``, a host name of ``"@"`` may be used to specify the zone name.
1099 |
1100 | Example::
1101 |
1102 | {
1103 | ...
1104 | "authorizations": {
1105 | "example.com": ["@", "www"]
1106 | },
1107 | ...
1108 | }
1109 |
1110 |
1111 | HTTP Challenges
1112 | ---------------
1113 |
1114 | By default, the tool will attempt dns-01 domain authorizations for every alternative name specified,
1115 | using local or remote DNS updates.
1116 |
1117 | To use http-01 authorizations instead,
1118 | configure the ``http_challenges`` section of the configuration file specifying a challenge directory for each fully qualified domain name,
1119 | or configure a ``http_challenge`` directory.
1120 |
1121 | It is possible to mix usage of dns-01 and http-01 domain authorizations on a host by host basis,
1122 | simply specify a http challenge directory only for those hosts requiring http-01 authentication.
1123 |
1124 | Example::
1125 |
1126 | {
1127 | ...
1128 | "http_challenges": {
1129 | "example.com": "/var/www/htdocs/.well-known/acme-challenge"
1130 | "www.example.com": "/var/www/htdocs/.well-known/acme-challenge"
1131 | },
1132 | ...
1133 | }
1134 |
1135 | The ``http_challenges`` must specify a directory on the local file system such that files placed there will be served via an already running http server for each given domain name.
1136 | In the above example,
1137 | files placed in ``/var/www/htdocs/.well-known/acme-challenge`` must be publicly available at:
1138 | ``http://example.com/.well-known/acme-challenge/file-name``
1139 | and
1140 | ``http://www.example.com/.well-known/acme-challenge/file-name``
1141 |
1142 | Alternatively, if your are primarily using http-01 authorizations and all challenge directories have a similar path,
1143 | you may configure a single ``http_challenge`` directory using a python format string with the fields ``zone``, ``host``, and ``fqdn``.
1144 |
1145 | Example::
1146 |
1147 | {
1148 | ...
1149 | "directories": {
1150 | "http_challenge": "/var/www/{zone}/{host}/.well-known/acme-challenge"
1151 | },
1152 | ...
1153 | }
1154 |
1155 | If an ``http_challenge`` directory is configured,
1156 | all domain authorizations will default to http-01.
1157 | To use dns-01 authorizations for selected domain names,
1158 | add an ``http_challenges`` entry configured with a ``null`` value.
1159 |
1160 |
1161 | Zone Update Keys
1162 | ----------------
1163 |
1164 | When using remote DNS updates,
1165 | it is necessary to specify a TSIG key used to sign the update requests.
1166 |
1167 | For each zone using remote DNS udpates,
1168 | specify either a string containing the file name of the TSIG key,
1169 | or an object with further options.
1170 |
1171 | The TSIG file name may an absolute path or a path relative to the ``update_key`` directory setting.
1172 | Both the ``.key`` file and the ``.private`` files must be present.
1173 |
1174 | Any zone referred to in a certificate, private key, or authorization that does not have a corresponding zone update key will use local DNS updates unless an HTTP challenge directory has been specified for every host in that zone.
1175 |
1176 | * ``file`` specifies the name of the TSIG key file.
1177 | * ``server`` specifies the name of the DNS server to send update requests to.
1178 | If omitted, the primary name server from the zone's SOA record will be used.
1179 | * ``port`` specifies the port to send update requests to.
1180 | The default value is ``53``.
1181 |
1182 | Example::
1183 |
1184 | {
1185 | ...
1186 | "zone_update_keys": {
1187 | "example1.com": "update.example1.com.key",
1188 | "example2.com": {
1189 | "file": "update.example2.com.key",
1190 | "server": "ns1.example2.com",
1191 | "port": 53
1192 | }
1193 | },
1194 | ...
1195 | }
1196 |
1197 |
1198 | Key Type Suffix
1199 | ---------------
1200 |
1201 | Each certificate and key file will have a suffix, just before the file extension,
1202 | indicating the type of key the file is for.
1203 |
1204 | The default suffix used for each key type can be overridden in the ``key_type_suffixes`` section.
1205 | If you are only using a single key type, or want to omit the suffix from one key type,
1206 | set it to an empty string.
1207 | Note that if using multiple key types the suffix must be unique or files will be overridden.
1208 |
1209 | Example::
1210 |
1211 | {
1212 | ...
1213 | "key_type_suffixes": {
1214 | "rsa": ".rsa",
1215 | "ecdsa": ".ecdsa"
1216 | },
1217 | ...
1218 | }
1219 |
1220 |
1221 | File Name Patterns
1222 | ------------------
1223 |
1224 | All output file names can be overridden using standard Python format strings.
1225 | Fields available for file names are: ``name``, ``key_type``, ``suffix``, ``server``.
1226 | The ``name`` field is the name of the private key or certificate.
1227 |
1228 | * ``log`` specifies the name of the log file.
1229 | * ``private_key`` specifies the name of primary private key files.
1230 | * ``backup_key`` specifies the name of backup private key files.
1231 | * ``full_key`` specifies the name of primary private key files that include the certificate chain.
1232 | * ``certificate`` specifies the name of certificate files.
1233 | * ``full_certificate`` specifies the name of certificate files that include the root certificate.
1234 | * ``chain`` specifies the name of intemediate certificate files.
1235 | * ``param`` specifies the name of Diffie-Hellman parameter files.
1236 | * ``challenge`` specifies the name of ACME challenge files used for local DNS updates.
1237 | * ``hpkp`` specifies the name of HPKP header files.
1238 | * ``ocsp`` specifies the name of OCSP response files.
1239 | * ``sct`` specifies the name of SCT files.
1240 |
1241 | Example::
1242 |
1243 | { ...
1244 | "file_names": {
1245 | "log": "acmebot.log",
1246 | "private_key": "{name}{suffix}.key",
1247 | "backup_key": "{name}_backup{suffix}.key",
1248 | "full_key": "{name}_full{suffix}.key",
1249 | "certificate": "{name}{suffix}.pem",
1250 | "full_certificate": "{name}+root{suffix}.pem",
1251 | "chain": "{name}_chain{suffix}.pem",
1252 | "param": "{name}_param.pem",
1253 | "challenge": "{name}",
1254 | "hpkp": "{name}.{server}",
1255 | "ocsp": "{name}{suffix}.ocsp",
1256 | "sct": "{ct_log_name}.sct"
1257 | },
1258 | ...
1259 | }
1260 |
1261 |
1262 | HPKP Headers
1263 | ------------
1264 |
1265 | This section defines the set of HPKP header files that will be generated and their contents.
1266 | Header files for additional servers can be added at will,
1267 | one file will be generated for each server.
1268 | Using standard Python format strings, the ``{header}`` field will be replaced with the HPKP header,
1269 | the ``{key_name}`` field will be replaced with the name of the private key,
1270 | and ``{server}`` will be replaced with the server name.
1271 | The default servers can be omitted by setting the header to ``null``.
1272 |
1273 | Example::
1274 |
1275 | {
1276 | ...
1277 | "hpkp_headers": {
1278 | "apache": "Header always set Public-Key-Pins \"{header}\"\n",
1279 | "nginx": "add_header Public-Key-Pins \"{header}\" always;\n"
1280 | },
1281 | ...
1282 | }
1283 |
1284 |
1285 | Certificate Transparency Logs
1286 | -----------------------------
1287 |
1288 | This section defines the set of certificate transparency logs available to submit certificates to and retrieve SCTs from.
1289 | Additional logs can be aded at will.
1290 | Each log definition requires the primary API URL of the log, and the log's ID in base64 format.
1291 | A list of currently active logs and their IDs can be found at `certificate-transparency.org `_.
1292 |
1293 | Example::
1294 |
1295 | {
1296 | ...,
1297 | "ct_logs": {
1298 | "google_pilot": {
1299 | "url": "https://ct.googleapis.com/pilot",
1300 | "id": "pLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BA="
1301 | },
1302 | "google_icarus": {
1303 | "url": "https://ct.googleapis.com/icarus",
1304 | "id": "KTxRllTIOWW6qlD8WAfUt2+/WHopctykwwz05UVH9Hg="
1305 | }
1306 | },
1307 | ...
1308 | }
1309 |
1310 |
1311 | Deployment Hooks
1312 | ----------------
1313 |
1314 | This section defines the set of hooks that can be called via the shell when given actions happen.
1315 | Paramaters to hooks are specified using Python format strings.
1316 | Fields available for each hook are described below.
1317 | Output from the hooks will be captured in the log.
1318 | Hooks returing a non-zero status code will generate warnings,
1319 | but will not otherwise affect the operation of this tool.
1320 |
1321 | * ``set_dns_challenge`` is called for each DNS challenge record that is set.
1322 | Available fields are ``domain``, ``zone``, and ``challenge``.
1323 | * ``clear_dns_challenge`` is called for each DNS challenge record that is removed.
1324 | Available fields are ``domain``, ``zone``, and ``challenge``.
1325 | * ``dns_zone_update`` is called when a DNS zone is updated via either local or remote updates.
1326 | Available field is ``zone``.
1327 | * ``set_http_challenge`` is called for each HTTP challenge file that is installed.
1328 | Available fields are ``domain``, and ``challenge_file``.
1329 | * ``clear_http_challenge`` is called for each HTTP challenge file that is removed.
1330 | Available fields are ``domain``, and ``challenge_file``.
1331 | * ``private_key_rollover`` is called when a private key is replaced by a backup private key.
1332 | Available fields are ``key_name``, ``key_type``, ``backup_key_file``, ``private_key_file``, ``previous_key_file``, and ``passphrase``.
1333 | * ``private_key_installed`` is called when a private key is installed.
1334 | Available fields are ``key_name``, ``key_type``, ``private_key_file``, and ``passphrase``.
1335 | * ``backup_key_installed`` is called when a backup private key is installed.
1336 | Available fields are ``key_name``, ``key_type``, ``backup_key_file``, and ``passphrase``.
1337 | * ``previous_key_installed`` is called when a previous private key is installed after key rollover.
1338 | Available fields are ``key_name``, ``key_type``, ``previous_key_file``, and ``passphrase``.
1339 | * ``hpkp_header_installed`` is called when a HPKP header file is installed.
1340 | Available fields are ``key_name``, ``server``, ``header``, and ``hpkp_file``.
1341 | * ``certificate_installed`` is called when a certificate file is installed.
1342 | Available fields are ``key_name``, ``key_type``, ``certificate_name``, and ``certificate_file``.
1343 | * ``full_certificate_installed`` is called when a certificate file that includes the root is installed.
1344 | Available fields are ``key_name``, ``key_type``, ``certificate_name``, and ``full_certificate_file``.
1345 | * ``chain_installed`` is called when a certificate intermediate chain file is installed.
1346 | Available fields are ``key_name``, ``key_type``, ``certificate_name``, and ``chain_file``.
1347 | * ``full_key_installed`` is called when a private key including the full certificate chain file is installed.
1348 | Available fields are ``key_name``, ``key_type``, ``certificate_name``, and ``full_key_file``.
1349 | * ``params_installed`` is called when a params file is installed.
1350 | Available fields are ``key_name``, ``certificate_name``, and ``params_file``.
1351 | * ``sct_installed`` is called when a SCT file is installed.
1352 | Available fields are ``key_name``, ``key_type``, ``certificate_name``, ``ct_log_name``, and ``sct_file``.
1353 | * ``ocsp_installed`` is called when an OSCP file is installed.
1354 | Available fields are ``key_name``, ``key_type``, ``certificate_name``, and ``ocsp_file``.
1355 |
1356 | Example::
1357 |
1358 | {
1359 | ...
1360 | "hooks": {
1361 | certificate_installed": "scp {certificate_file} remote-server:/etc/ssl/certs/"
1362 | },
1363 | ...
1364 | }
1365 |
1366 |
1367 | Certificate Installation Verification
1368 | -------------------------------------
1369 |
1370 | The tool may be configured to perform installation verification of certificates.
1371 | When verifying installation, the tool will connect to every subject alternative host name for each certificate on all avaialable IP addresses,
1372 | per each configured port,
1373 | perform a TLS handshake,
1374 | and compare the served certificate chain to the specified certificate.
1375 |
1376 | Each configured port may be an integer port number,
1377 | or an object specifying connection details.
1378 |
1379 | When using an object, the avaialable fields are:
1380 |
1381 | * ``port`` specifies the port number to connect to.
1382 | Required.
1383 | * ``starttls`` specifies the STARTTLS mechanism that should be used to initiate a TLS session.
1384 | Allowed values are: ``null``, ``smtp``, ``pop3``, ``imap``, ``sieve``, ``ftp``, ``ldap``, and ``xmpp``.
1385 | The default value is ``null``.
1386 | * ``protocol`` specifies the protocol used to obtain additional information to verify.
1387 | Currently this can retrieve Public-Key-Pins http headers to ensure that they are properly set.
1388 | Allowed values are: ``null``, and ``http``.
1389 | The default value is ``null``.
1390 | * ``hosts`` specifies a list of fully qualified domain names to test.
1391 | This allows testing only a subset of the alternative names specified for the certificate.
1392 | Each host name must be present as an alternative name for the certificate.
1393 | The default value is all alternative names.
1394 | * ``key_types`` specifies a list of key types to test.
1395 | This allows testing only a subset of the avaialable key types.
1396 | The default value is all avaialable key types.
1397 |
1398 | Example::
1399 |
1400 | {
1401 | ...
1402 | "verify": [
1403 | {
1404 | "port": 443,
1405 | "protocol": "http"
1406 | },
1407 | {
1408 | "port": 25,
1409 | "starttls": "smtp",
1410 | "hosts": "smtp.example.com",
1411 | "key_types": "rsa"
1412 | },
1413 | 993
1414 | ]
1415 | ...
1416 | }
1417 |
1418 |
1419 | Configuring Local DNS Updates
1420 | =============================
1421 |
1422 | In order to perform dns-01 authorizations,
1423 | and to keep TLSA records up to date,
1424 | the tool will need to be able to add, remove, and update various DNS records.
1425 |
1426 | For updating DNS on a local server,
1427 | this tool was designed to use a bind zone file pre-processor,
1428 | such as `bindtool`_,
1429 | but may be used with another tool instead.
1430 |
1431 | When using `bindtool`_, be sure to configure bindtool's ``acme_path`` to be equal to the value of the ``challenge`` directory, so that it can find the ACME challenge files.
1432 |
1433 | When the tool needs to update a DNS zone, it will call the configured ``reload_zone`` command with the name of the zone as its argument.
1434 | When _acme-challenge records need to be set, a file will be placed in the ``challenge`` directory with the name of the zone in question, e.g. ``/etc/ssl/challenges/example.com``.
1435 | The challenge file is a JSON format file containing a single object.
1436 | The name/value pairs of that object are the fully qualified domain names of the records needing to be set, and the values of the records, e.g.::
1437 |
1438 | {
1439 | "www.example.com": "gfj9Xq...Rg85nM"
1440 | }
1441 |
1442 | Which should result in the following DNS record created in the zone::
1443 |
1444 | _acme-challenge.www.example.com. 300 IN TXT "gfj9Xq...Rg85nM"
1445 |
1446 | Note that domain names containing wildcards must have the wildcard component removed in the corresponding TXT record, e.g.::
1447 |
1448 | {
1449 | "example.com": "jc87sd...kO89hG"
1450 | "*.example.com": "gfj9Xq...Rg85nM"
1451 | }
1452 |
1453 | Must result in the following DNS records created in the zone::
1454 |
1455 | _acme-challenge.example.com. 300 IN TXT "jc87sd...kO89hG"
1456 | _acme-challenge.example.com. 300 IN TXT "gfj9Xq...Rg85nM"
1457 |
1458 | If there is no file in the ``challenge`` directory with the same name as the zone, all _acme-challenge records should be removed.
1459 |
1460 | Any time the ``reload_zone`` is called, it should also update any TLSA records asscoiated with the zone based on the certificates or private keys present.
1461 |
1462 | All of these functions are provided automatically by `bindtool`_ via the use of ``{{acme:}}`` and ``{{tlsa:}}`` commands in the zone file.
1463 | For example, the zone file::
1464 |
1465 | {{soa:ns1.example.com:admin@example.com}}
1466 |
1467 | {{ip4=192.0.2.0}}
1468 |
1469 | @ NS ns1
1470 | @ NS ns2
1471 |
1472 | @ A {{ip4}}
1473 | www A {{ip4}}
1474 |
1475 | {{tlsa:443}}
1476 | {{tlsa:443:www}}
1477 |
1478 | {{acme:}}
1479 |
1480 | {{caa:letsencrypt.org}}
1481 |
1482 | Will define the zone ``example.com`` using the nameservers ``ns1.example.com`` and ``ns1.example.com``, providing the hosts ``example.com`` and ``www.example.com``, with TLSA records pinning the primary and backup keys.
1483 |
1484 |
1485 | Configuring Remote DNS Updates
1486 | ==============================
1487 |
1488 | If the tool is not run on a machine also hosting a DNS server, then http-01 authorizations or remote DNS updates must be used.
1489 |
1490 | The use remote DNS udpates via RFC 2136 dynamic updates,
1491 | configure a zone update key for each zone.
1492 | See the `Zone Update Keys <#zone-update-keys>`_ section for more information.
1493 |
1494 | It is also necesary to have the ``nsupdate`` tool installed and the ``nsupdate_command`` configured in the ``settings`` configuration section.
1495 |
1496 | Zone update keys may be generated via the ``dnssec-keygen`` tool.
1497 |
1498 | For example::
1499 |
1500 | dnssec-keygen -r /dev/urandom -a HMAC-MD5 -b 512 -n HOST update.example.com
1501 |
1502 | will generate two files, named Kupdate.example.com.+157+NNNNN.key and Kupdate.example.com.+157+NNNNN.private.
1503 | Specify the .key file as the zone update key.
1504 |
1505 | To configure bind to allow remote DNS updates, add an entry to named.conf.keys for the update key containg the key value from the private key file, e.g.::
1506 |
1507 | key update.example.com. {
1508 | algorithm hmac-md5;
1509 | secret "sSeWrBDen...9WESlnEwQ==";
1510 | };
1511 |
1512 | and then add an ``allow-update`` entry to the zone configuration, e.g.::
1513 |
1514 | zone "example.com" {
1515 | type master;
1516 | allow-update { key update.example.com.; };
1517 | ...
1518 | };
1519 |
1520 |
1521 | Running the Tool
1522 | ================
1523 |
1524 | On first run, the tool will generate a client key,
1525 | register that key with the certificate authority,
1526 | accept the certificate authority's terms and conditions,
1527 | perform all needed domain authorizations,
1528 | generate primary private keys,
1529 | issue certificates,
1530 | generate backup private keys,
1531 | generate custom Diffie-Hellman parameters,
1532 | install certificate and key files,
1533 | update TLSA records,
1534 | retrieve current Signed Certificate Timestamps (SCTs) from configured certificate transparency logs,
1535 | retrieve OCSP staples,
1536 | reload services associated to the certificates,
1537 | and perform configured certificate installation verification.
1538 |
1539 | Each subsequent run will ensure that all authorizations remain valid,
1540 | check if any backup private keys have passed their expiration date,
1541 | check if any certificate's expiration dates are within the renewal window,
1542 | or have changes to the configured common name, or subject alternative names,
1543 | or no longer match their associated private key files.
1544 |
1545 | If a backup private key has passed its expiration date,
1546 | the tool will rollover the private key or emit a warning recommending that the private key be rolled over,
1547 | see the `Private Key Rollover <#private-key-rollover>`_ section for more information.
1548 |
1549 | If a certificate needs to be renewed or has been modified,
1550 | the certificate will be re-issued and reinstalled.
1551 |
1552 | When certificates are issued or re-issued,
1553 | local DNS updates will be attempted (to update TLSA records) and associated services will be reloaded.
1554 |
1555 | When using remote DNS updates,
1556 | all configured TLSA records will be verified and updated as needed on each run.
1557 |
1558 | Configured certificate transparency logs will be queried and SCT files will be updated as necessary.
1559 |
1560 | All certificates and private keys will normally be processed on each run,
1561 | to restrict processing to specific private keys (and their certificates),
1562 | you can list the names of the private keys to process on the command line.
1563 |
1564 |
1565 | Daily Run Via cron
1566 | ------------------
1567 |
1568 | In order to ensure that certificates in use do not expire,
1569 | it is recommended that the tool be run at least once per day via a cron job.
1570 |
1571 | By default, the tool only generates output when actions are taken making it cron friendly.
1572 | Normal output can be supressed via the ``--quiet`` command line option.
1573 |
1574 | To prevent multiple instances running at the same time,
1575 | a random wait can be introduced via the ``--randomwait`` command line option.
1576 | The minimum and maximum wait times can be controlled via the ``min_run_delay`` and ``max_run_delay`` settings.
1577 |
1578 | Example cron entry, in file /etc/cron.d/acmebot::
1579 |
1580 | MAILTO=admin@example.com
1581 |
1582 | 20 0 * * * root /usr/local/bin/acmebot --randomwait
1583 |
1584 | This will run the tool as root every day at 20 minutes past midnight plus a random delay of five minutes to an hour.
1585 | Any output will be mailed to admin@example.com.
1586 |
1587 | If using OCSP response files, it may be desirable to refresh OCSP responses at a shorter interval.
1588 | (Currently Let's Encrypt updates OCSP responses every three days.)
1589 | To refresh OCSP responses every six hours, add the line:
1590 |
1591 | 20 6,12,18 * * * root /usr/local/bin/acmebot --ocsp --randomwait
1592 |
1593 |
1594 | Output Options
1595 | --------------
1596 |
1597 | Normally the tool will only generate output to stdout when certificates are issued or private keys need to be rolled over.
1598 | More detailed output can be obtained by using any of the ``--verbose``, ``--debug``, or ``--detail`` options on the command line.
1599 |
1600 | Normal output may be supressed by using the ``--quiet`` option.
1601 |
1602 | Error and warning output will be sent to stderr and cannot be supressed.
1603 |
1604 | The output can be colorized by type by adding the ``--color`` option,
1605 | or colorized output can be suppressed via the ``--no-color`` option.
1606 |
1607 |
1608 | Private Key Rollover
1609 | --------------------
1610 |
1611 | During normal operations the private keys for certificates will not be modified,
1612 | this allows renewing or modifying certificates without the need to update associated pinning information,
1613 | such as HPKP headers or TLSA records using spki selectors.
1614 |
1615 | However, it is a good security practice to replace the private keys at regular intervals,
1616 | or immediately if it is believed that the primary private key may have been compromised.
1617 | This tool maintains a backup private key for each primary private key and generates pinning information including the backup key as appropriate to allow smooth transitions to the backup key.
1618 |
1619 | When the backup private key reaches the age specified via the ``expiration_days`` setting,
1620 | the tool will notify you that it is time to rollover the private key,
1621 | unless the ``auto_rollover`` setting has been set to ``true``,
1622 | in which case it will automatically perform the rollover.
1623 |
1624 | The rollover process will archive the current primary private key,
1625 | re-issue certificates using the existing backup key as the new primary key,
1626 | generate a new backup private key,
1627 | generate new custom Diffie-Hellman parameters,
1628 | and reset HPKP headers and TLSA records as appropriate.
1629 |
1630 | If the ``previous_key`` directory is specified,
1631 | the current primary private key will be stored in that directory as a previous private key.
1632 | While previous private key files are present,
1633 | their key signatures will be added to HPKP pins and TLSA records.
1634 | This can assist in key rollover when keys are pinned for subdomains and private keys are shared between multiple servers.
1635 | Once the new primary and backup keys have been distributed to the other servers,
1636 | the previous private key file may be safely removed.
1637 |
1638 | To manually rollover private keys, simply run the tool with the ``--rollover`` option.
1639 | You can specify the names of individual private keys on the command line to rollover,
1640 | otherwise all private keys will be rolled over.
1641 |
1642 | Note that the tool will refuse to rollover a private key if the current backup key is younger than the HPKP duration.
1643 | A private key rollover during this interval may cause a web site to become inaccessable to clients that have previously cached HPKP headers but not yet retrieved the current backup key pin.
1644 | If it is necessary to rollover the private key anyway,
1645 | for example if it is believed that the backup key has been compromised as well,
1646 | add the ``--force`` option on the command line to force the private key rollover.
1647 |
1648 |
1649 | Forced Certificate Renewal
1650 | --------------------------
1651 |
1652 | Normally certificates will be automatically renewed when the tool is run within the certificate renewal window,
1653 | e.g. within ``renewal_days`` of the certificate's expiration date.
1654 | To cause certificates to be renewed before this time,
1655 | run the tool with the ``--renew`` option on the command line.
1656 |
1657 |
1658 | Revoking Certificates
1659 | ---------------------
1660 |
1661 | Should it become necessary to revoke a certificate,
1662 | for example if it is believed that the private key has been compromised,
1663 | run the tool with the ``--revoke`` option on the command line.
1664 |
1665 | When revoking certificates, as a safety measure,
1666 | it is necessary to also specify the name of the private key (or keys) that should be revoked.
1667 | All certificates using that private key will be revoked,
1668 | the certificate files and the primary private key file will be moved to the archive,
1669 | and remote DNS TLSA records will be removed.
1670 |
1671 | The next time the tool is run after a revocation,
1672 | any revoked certificates that are still configured will automatically perform a private key rollover.
1673 |
1674 |
1675 | Authorization Only
1676 | ------------------
1677 |
1678 | Use of the ``--auth`` option on the command line will limit the tool to only performing domain authorizations.
1679 |
1680 |
1681 | Certificates Only
1682 | -----------------
1683 |
1684 | Use of the ``--certs`` option on the command line will limit the tool to only issuing and renewing certificates and keys,
1685 | and updating related files such as Diffie-Hellman paramaters and HPKP headers.
1686 |
1687 |
1688 | Remote TLSA Updates
1689 | -------------------
1690 |
1691 | Use of the ``--tlsa`` option on the command line will limit the tool to only verifying and updating configured TLSA records via remote DNS updates.
1692 |
1693 |
1694 | Signed Certificate Timestamp Updates
1695 | ------------------------------------
1696 |
1697 | Use of the ``--sct`` option on the command line will limit the tool to only verifying and updating configured Signed Certificate Timestamp files.
1698 |
1699 |
1700 | OCSP Response Updates
1701 | ---------------------
1702 |
1703 | Use of the ``--ocsp`` option on the command line will limit the tool to only updating configured OCSP response files.
1704 |
1705 |
1706 | Certificate Installation Verification
1707 | -------------------------------------
1708 |
1709 | Use of the ``--verify`` option on the command line will limit the tool to only performing certificate installation verification.
1710 |
1711 |
1712 | Multiple Operations
1713 | -------------------
1714 |
1715 | The ``--auth``, ``--certs``, ``--tlsa``, ``--sct``, ``-ocsp``, and ``--verify`` options may be combined to perform a combinations of operations.
1716 | If none of these options are specified, all operations will be performed as necessary and configured.
1717 | The order of the operations will not be affected by the order of the command line options.
1718 |
1719 |
1720 | Private Key Encryption
1721 | ----------------------
1722 |
1723 | When encrypting private keys, a passphrase must be provided.
1724 | There are several options for providing the key.
1725 |
1726 | Passphrases may be specified directly in the configuration file,
1727 | both as a default passphrase applying to all keys,
1728 | or specific passphrases for each key.
1729 | Storing passphrases in cleartext in the configuration file obviously does little to protect the private keys if the configuration file is stored on the same machine.
1730 | Either protect the configuration file or use an alternate method of providing passphrases.
1731 |
1732 | Alternatively, by setting the passphrase to ``true`` in the configuration file (the binary value, not the string ``"true"``),
1733 | the tool will attempt to obtain the passphrases at runtime.
1734 |
1735 | Runtime passphrases may be provided on the command line, via an environment variable, via a text prompt, or via an input file.
1736 |
1737 | A command line passphrase is passed via the ``--pass`` option, e.g.::
1738 |
1739 | acmebot --pass "passphrase"
1740 |
1741 | To use an environment variable, set the passphrase in ``ACMEBOT_PASSPHRASE``.
1742 |
1743 | A passphrase passed at the command line or an environment variable will be used for every private key that has it's ``key_passphrase`` set to ``true``.
1744 | If different passphrases are desired for different keys,
1745 | run the tool for each key specifying the private key name on the command line to restrict processing to that key.
1746 |
1747 | If the passphrase is not provided on the command line or an environment variable,
1748 | and the tool is run via a TTY device (e.g. manually in a terminal),
1749 | it will prompt the user for each passphrase as needed.
1750 | Different passphrases may be provided for each private key (the same passphrase will be used for all key types of that key).
1751 |
1752 | Finally, the passphrases may be stored in a file, one per line, and input redirected from that file, e.g.::
1753 |
1754 | acmebot < passphrase_file.txt
1755 |
1756 | Passphrases passed via an input file will be used in the order that the private keys are defined in the configuration file.
1757 | If both certificates and private key sections are defined, the private keys will be processed first, then the certificates.
1758 | You may wish to run the tool without the input file first to verify the private key order.
1759 |
1760 |
1761 |
1762 | Master/Follower Setup
1763 | =====================
1764 |
1765 | In some circumstances, it is useful to run the tool in a master/follower configuration.
1766 | In this setup, the master performs domain authorizations
1767 | while the follower issues and maintains certificates.
1768 |
1769 | This setup is useful when the follower machine does not have the ability to perform domain authorizations,
1770 | for example, an XMPP server behind a firewall that does not have port 80 open or access to a DNS server.
1771 |
1772 | To create a master/follower setup,
1773 | first install and configure the tool on the master server as normal.
1774 | The master server may also issue certificates, but it is not necessary.
1775 |
1776 | Configure any required domain authorizations (see the `Authorizations <#authorizations>`_ section) on the master and run the tool.
1777 |
1778 | Then install the tool on the follower server.
1779 | It is not necessary to configure HTTP challenges or remote DNS update keys on the follower.
1780 |
1781 | Before running the tool on the follower server,
1782 | copy the client key and registration files from the master server.
1783 | These files are normally found in ``/var/local/acmebot`` but an alternate location can be configured in the ``resource`` directory setting.
1784 |
1785 | If the master server also issues certificates for the same domain names or parent domain names as the follower,
1786 | you may want to copy the primary and backup private keys for those certificates to the follower.
1787 | This will cause the follower certificates to use the same keys allowing HPKP headers to safey include subdomains.
1788 |
1789 | Set the follower ``follower_mode`` setting to ``true`` and configure desired certificates on the follower.
1790 |
1791 | Run the tool on the follower server.
1792 |
1793 | When setting up cron jobs for the master and follower,
1794 | be sure the follower runs several minutes after the master so that all authorizations will be complete.
1795 | The master can theoretically take (``max_dns_lookup_attempts`` x ``dns_lookup_delay``) + (``max_authorization_attempts`` x ``authorization_delay``) seconds to obtain domain authorizations (15 minutes at the default settings).
1796 |
1797 | It is possible to run several follower servers for each master,
1798 | the follower cron jobs should not all run at the same time.
1799 |
1800 | The follower server may maintain TLSA records if remote DNS updates are configured on the follower,
1801 | otherwise it is recommended to use spki selectors for TLSA records so that certificate renewals on the follower will not invalidate TLSA records.
1802 |
1803 | If private keys are shared between a master and follower,
1804 | be sure to turn off ``auto_rollover`` and only perform private key rollovers on the master.
1805 | It is also useful to specify the ``previous_key`` directory to preserve previous key pins during the key rollover process.
1806 | After a private key rollover, copy the new primary and backup private key files to the followers.
1807 | The follower will automatically detect the new private key and re-issue certificates on the next run.
1808 | Once all the followers have updated their certificates to the new keys,
1809 | you can safely delete the previous private key file.
1810 |
--------------------------------------------------------------------------------
/config/acmebot.example.json:
--------------------------------------------------------------------------------
1 | {
2 | "account": {
3 | "email": ""
4 | },
5 | "settings": {
6 | "follower_mode": false,
7 | "log_level": "debug",
8 | "color_output": true,
9 | "key_size": 4096,
10 | "key_curve": "secp384r1",
11 | "key_cipher": "blowfish",
12 | "key_passphrase": null,
13 | "key_provided": false,
14 | "dhparam_size": 2048,
15 | "ecparam_curve": "secp384r1",
16 | "file_user": "root",
17 | "file_group": "ssl-cert",
18 | "hpkp_days": 60,
19 | "pin_subdomains": true,
20 | "hpkp_report_uri": null,
21 | "ocsp_must_staple": false,
22 | "ocsp_responder_urls": ["http://ocsp.int-x3.letsencrypt.org"],
23 | "ct_submit_logs": ["google_icarus", "google_pilot"],
24 | "renewal_days": 30,
25 | "expiration_days": 730,
26 | "auto_rollover": false,
27 | "max_dns_lookup_attempts": 60,
28 | "dns_lookup_delay": 10,
29 | "max_domains_per_order": 100,
30 | "max_authorization_attempts": 30,
31 | "authorization_delay": 10,
32 | "cert_poll_time": 30,
33 | "max_ocsp_verify_attempts": 10,
34 | "ocsp_verify_retry_delay": 5,
35 | "min_run_delay": 300,
36 | "max_run_delay": 3600,
37 | "acme_directory_url": "https://acme-v02.api.letsencrypt.org/directory",
38 | "reload_zone_command": "/etc/bind/reload-zone.sh",
39 | "nsupdate_command": "/usr/bin/nsupdate",
40 | "public_suffix_list_url": "https://publicsuffix.org/list/public_suffix_list.dat"
41 | },
42 | "directories": {
43 | "pid": "/var/run",
44 | "log": "/var/log/acmebot",
45 | "resource": "/var/local/acmebot",
46 | "private_key": "/etc/ssl/private",
47 | "backup_key": "/etc/ssl/private",
48 | "previous_key": null,
49 | "full_key": "/etc/ssl/private",
50 | "certificate": "/etc/ssl/certs",
51 | "full_certificate": "/etc/ssl/certs",
52 | "chain": "/etc/ssl/certs",
53 | "param": "/etc/ssl/params",
54 | "challenge": "/etc/ssl/challenges",
55 | "http_challenge": null,
56 | "hpkp": "/etc/ssl/hpkp",
57 | "ocsp": "/etc/ssl/ocsp/",
58 | "sct": "/etc/ssl/scts/{name}/{key_type}",
59 | "update_key": "/etc/ssl/update_keys",
60 | "archive": "/etc/ssl/archive",
61 | "temp": null
62 | },
63 | "key_type_suffixes": {
64 | "rsa": ".rsa",
65 | "ecdsa": ".ecdsa"
66 | },
67 | "file_names": {
68 | "log": "acmebot.log",
69 | "private_key": "{name}{suffix}.key",
70 | "backup_key": "{name}_backup{suffix}.key",
71 | "previous_key": "{name}_previous{suffix}.key",
72 | "full_key": "{name}_full{suffix}.key",
73 | "certificate": "{name}{suffix}.pem",
74 | "full_certificate": "{name}+root{suffix}.pem",
75 | "chain": "{name}_chain{suffix}.pem",
76 | "param": "{name}_param.pem",
77 | "challenge": "{name}",
78 | "hpkp": "{name}.{server}",
79 | "ocsp": "{name}{suffix}.ocsp",
80 | "sct": "{ct_log_name}.sct"
81 | },
82 | "hpkp_headers": {
83 | "apache": "Header always set Public-Key-Pins \"{header}\"\n",
84 | "nginx": "add_header Public-Key-Pins \"{header}\" always;\n"
85 | },
86 | "services": {
87 | "apache": "systemctl reload apache2",
88 | "coturn": "systemctl restart coturn",
89 | "dovecot": "systemctl restart dovecot",
90 | "etherpad": "systemctl restart etherpad",
91 | "mysql": "systemctl reload mysql",
92 | "nginx": "systemctl reload nginx",
93 | "postfix": "systemctl reload postfix",
94 | "postgresql": "systemctl reload postgresql",
95 | "prosody": "systemctl restart prosody",
96 | "slapd": "systemctl restart slapd",
97 | "synapse": "systemctl restart matrix-synapse",
98 | "znc": "systemctl restart znc"
99 | },
100 | "hooks": {
101 | "set_dns_challenge": null,
102 | "clear_dns_challenge": null,
103 | "dns_zone_update": null,
104 | "set_http_challenge": null,
105 | "clear_http_challenge": null,
106 | "private_key_rollover": null,
107 | "private_key_installed": null,
108 | "backup_key_installed": null,
109 | "previous_key_installed": null,
110 | "hpkp_header_installed": null,
111 | "certificate_installed": null,
112 | "full_certificate_installed": null,
113 | "chain_installed": null,
114 | "full_key_installed": null,
115 | "params_installed": null,
116 | "sct_installed": null,
117 | "ocsp_installed": null
118 | },
119 | "ct_logs": {
120 | "google_argon": [
121 | {
122 | "log_id": "sh4FzIuizYogTodm+Su5iiUgZ2va+nDnsklTLe+LkF4=",
123 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6Tx2p1yKY4015NyIYvdrk36es0uAc1zA4PQ+TGRY+3ZjUTIYY9Wyu+3q/147JG4vNVKLtDWarZwVqGkg6lAYzA==",
124 | "url": "https://ct.googleapis.com/logs/argon2020/",
125 | "start": "2020-01-01T00:00:00Z",
126 | "end": "2021-01-01T00:00:00Z"
127 | },
128 | {
129 | "log_id": "9lyUL9F3MCIUVBgIMJRWjuNNExkzv98MLyALzE7xZOM=",
130 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETeBmZOrzZKo4xYktx9gI2chEce3cw/tbr5xkoQlmhB18aKfsxD+MnILgGNl0FOm0eYGilFVi85wLRIOhK8lxKw==",
131 | "url": "https://ct.googleapis.com/logs/argon2021/",
132 | "start": "2021-01-01T00:00:00Z",
133 | "end": "2022-01-01T00:00:00Z"
134 | },
135 | {
136 | "log_id": "KXm+8J45OSHwVnOfY6V35b5XfZxgCvj5TV0mXCVdx4Q=",
137 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeIPc6fGmuBg6AJkv/z7NFckmHvf/OqmjchZJ6wm2qN200keRDg352dWpi7CHnSV51BpQYAj1CQY5JuRAwrrDwg==",
138 | "url": "https://ct.googleapis.com/logs/argon2022/",
139 | "start": "2022-01-01T00:00:00Z",
140 | "end": "2023-01-01T00:00:00Z"
141 | },
142 | {
143 | "log_id": "6D7Q2j71BjUy51covIlryQPTy9ERa+zraeF3fW0GvW4=",
144 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0JCPZFJOQqyEti5M8j13ALN3CAVHqkVM4yyOcKWCu2yye5yYeqDpEXYoALIgtM3TmHtNlifmt+4iatGwLpF3eA==",
145 | "url": "https://ct.googleapis.com/logs/argon2023/",
146 | "start": "2023-01-01T00:00:00Z",
147 | "end": "2024-01-01T00:00:00Z"
148 | }
149 | ],
150 | "google_xenon": [
151 | {
152 | "log_id": "B7dcG+V9aP/xsMYdIxXHuuZXfFeUt2ruvGE6GmnTohw=",
153 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZU75VqjyzSTgFZKAnWg1QeYfFFIRZTMK7q3kWWZsmHhQdrBYnHRZ3OA4kUeUx0JN+xX+dSgt1ruqUhhl7jOvmw==",
154 | "url": "https://ct.googleapis.com/logs/xenon2020/",
155 | "start": "2020-01-01T00:00:00Z",
156 | "end": "2021-01-01T00:00:00Z"
157 | },
158 | {
159 | "log_id": "fT7y+I//iFVoJMLAyp5SiXkrxQ54CX8uapdomX4i8Nc=",
160 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAER+1MInu8Q39BwDZ5Rp9TwXhwm3ktvgJzpk/r7dDgGk7ZacMm3ljfcoIvP1E72T8jvyLT1bvdapylajZcTH6W5g==",
161 | "url": "https://ct.googleapis.com/logs/xenon2021/",
162 | "start": "2021-01-01T00:00:00Z",
163 | "end": "2022-01-01T00:00:00Z"
164 | },
165 | {
166 | "log_id": "RqVV63X6kSAwtaKJafTzfREsQXS+/Um4havy/HD+bUc=",
167 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+WS9FSxAYlCVEzg8xyGwOrmPonoV14nWjjETAIdZvLvukPzIWBMKv6tDNlQjpIHNrUcUt1igRPpqoKDXw2MeKw==",
168 | "url": "https://ct.googleapis.com/logs/xenon2022/",
169 | "start": "2022-01-01T00:00:00Z",
170 | "end": "2023-01-01T00:00:00Z"
171 | },
172 | {
173 | "log_id": "rfe++nz/EMiLnT2cHj4YarRnKV3PsQwkyoWGNOvcgoo=",
174 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEchY+C+/vzj5g3ZXLY3q5qY1Kb2zcYYCmRV4vg6yU84WI0KV00HuO/8XuQqLwLZPjwtCymeLhQunSxgAnaXSuzg==",
175 | "url": "https://ct.googleapis.com/logs/xenon2023/",
176 | "start": "2023-01-01T00:00:00Z",
177 | "end": "2024-01-01T00:00:00Z"
178 | }
179 | ],
180 | "cloudflare_numbus": [
181 | {
182 | "log_id": "Xqdz+d9WwOe1Nkh90EngMnqRmgyEoRIShBh1loFxRVg=",
183 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE01EAhx4o0zPQrXTcYjgCt4MVFsT0Pwjzb1RwrM0lhWDlxAYPP6/gyMCXNkOn/7KFsjL7rwk78tHMpY8rXn8AYg==",
184 | "url": "https://ct.cloudflare.com/logs/nimbus2020/",
185 | "start": "2020-01-01T00:00:00Z",
186 | "end": "2021-01-01T00:00:00Z"
187 | },
188 | {
189 | "log_id": "RJRlLrDuzq/EQAfYqP4owNrmgr7YyzG1P9MzlrW2gag=",
190 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExpon7ipsqehIeU1bmpog9TFo4Pk8+9oN8OYHl1Q2JGVXnkVFnuuvPgSo2Ep+6vLffNLcmEbxOucz03sFiematg==",
191 | "url": "https://ct.cloudflare.com/logs/nimbus2021/",
192 | "start": "2021-01-01T00:00:00Z",
193 | "end": "2022-01-01T00:00:00Z"
194 | },
195 | {
196 | "log_id": "QcjKsd8iRkoQxqE6CUKHXk4xixsD6+tLx2jwkGKWBvY=",
197 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESLJHTlAycmJKDQxIv60pZG8g33lSYxYpCi5gteI6HLevWbFVCdtZx+m9b+0LrwWWl/87mkNN6xE0M4rnrIPA/w==",
198 | "url": "https://ct.cloudflare.com/logs/nimbus2022/",
199 | "start": "2022-01-01T00:00:00Z",
200 | "end": "2023-01-01T00:00:00Z"
201 | },
202 | {
203 | "log_id": "ejKMVNi3LbYg6jjgUh7phBZwMhOFTTvSK8E6V6NS61I=",
204 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEi/8tkhjLRp0SXrlZdTzNkTd6HqmcmXiDJz3fAdWLgOhjmv4mohvRhwXul9bgW0ODgRwC9UGAgH/vpGHPvIS1qA==",
205 | "url": "https://ct.cloudflare.com/logs/nimbus2023/",
206 | "start": "2023-01-01T00:00:00Z",
207 | "end": "2024-01-01T00:00:00Z"
208 | }
209 | ],
210 | "digicert_log_server": {
211 | "log_id": "VhQGmi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0=",
212 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAkbFvhu7gkAW6MHSrBlpE1n4+HCFRkC5OLAjgqhkTH+/uzSfSl8ois8ZxAD2NgaTZe1M9akhYlrYkes4JECs6A==",
213 | "url": "https://ct1.digicert-ct.com/log/"
214 | },
215 | "digicert_log_server_2": {
216 | "log_id": "h3W/51l8+IxDmV+9827/Vo1HVjb/SrVgwbTq/16ggw8=",
217 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEzF05L2a4TH/BLgOhNKPoioYCrkoRxvcmajeb8Dj4XQmNY+gxa4Zmz3mzJTwe33i0qMVp+rfwgnliQ/bM/oFmhA==",
218 | "url": "https://ct2.digicert-ct.com/log/"
219 | },
220 | "digicert_yeti": [
221 | {
222 | "log_id": "8JWkWfIA0YJAEC0vk4iOrUv+HUfjmeHQNKawqKqOsnM=",
223 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEURAG+Zo0ac3n37ifZKUhBFEV6jfcCzGIRz3tsq8Ca9BP/5XUHy6ZiqsPaAEbVM0uI3Tm9U24RVBHR9JxDElPmg==",
224 | "url": "https://yeti2020.ct.digicert.com/log/",
225 | "start": "2020-01-01T00:00:00Z",
226 | "end": "2021-01-01T00:00:00Z"
227 | },
228 | {
229 | "log_id": "XNxDkv7mq0VEsV6a1FbmEDf71fpH3KFzlLJe5vbHDso=",
230 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6J4EbcpIAl1+AkSRsbhoY5oRTj3VoFfaf1DlQkfi7Rbe/HcjfVtrwN8jaC+tQDGjF+dqvKhWJAQ6Q6ev6q9Mew==",
231 | "url": "https://yeti2021.ct.digicert.com/log/",
232 | "start": "2021-01-01T00:00:00Z",
233 | "end": "2022-01-01T00:00:00Z"
234 | },
235 | {
236 | "log_id": "IkVFB1lVJFaWP6Ev8fdthuAjJmOtwEt/XcaDXG7iDwI=",
237 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEn/jYHd77W1G1+131td5mEbCdX/1v/KiYW5hPLcOROvv+xA8Nw2BDjB7y+RGyutD2vKXStp/5XIeiffzUfdYTJg==",
238 | "url": "https://yeti2022.ct.digicert.com/log/",
239 | "start": "2022-01-01T00:00:00Z",
240 | "end": "2023-01-01T00:00:00Z"
241 | },
242 | {
243 | "log_id": "Nc8ZG7+xbFe/D61MbULLu7YnICZR6j/hKu+oA8M71kw=",
244 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfQ0DsdWYitzwFTvG3F4Nbj8Nv5XIVYzQpkyWsU4nuSYlmcwrAp6m092fsdXEw6w1BAeHlzaqrSgNfyvZaJ9y0Q==",
245 | "url": "https://yeti2023.ct.digicert.com/log/",
246 | "start": "2023-01-01T00:00:00Z",
247 | "end": "2024-01-01T00:00:00Z"
248 | }
249 | ],
250 | "digicert_nessie": [
251 | {
252 | "log_id": "xlKg7EjOs/yrFwmSxDqHQTMJ6ABlomJSQBujNioXxWU=",
253 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4hHIyMVIrR9oShgbQMYEk8WX1lmkfFKB448Gn93KbsZnnwljDHY6MQqEnWfKGgMOq0gh3QK48c5ZB3UKSIFZ4g==",
254 | "url": "https://nessie2020.ct.digicert.com/log/",
255 | "start": "2020-01-01T00:00:00Z",
256 | "end": "2021-01-01T00:00:00Z"
257 | },
258 | {
259 | "log_id": "7sCV7o1yZA+S48O5G8cSo2lqCXtLahoUOOZHssvtxfk=",
260 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9o7AiwrbGBIX6Lnc47I6OfLMdZnRzKoP5u072nBi6vpIOEooktTi1gNwlRPzGC2ySGfuc1xLDeaA/wSFGgpYFg==",
261 | "url": "https://nessie2021.ct.digicert.com/log/",
262 | "start": "2021-01-01T00:00:00Z",
263 | "end": "2022-01-01T00:00:00Z"
264 | },
265 | {
266 | "log_id": "UaOw9f0BeZxWbbg3eI8MpHrMGyfL956IQpoN/tSLBeU=",
267 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJyTdaAMoy/5jvg4RR019F2ihEV1McclBKMe2okuX7MCv/C87v+nxsfz1Af+p+0lADGMkmNd5LqZVqxbGvlHYcQ==",
268 | "url": "https://nessie2022.ct.digicert.com/log/",
269 | "start": "2022-01-01T00:00:00Z",
270 | "end": "2023-01-01T00:00:00Z"
271 | },
272 | {
273 | "log_id": "s3N3B+GEUPhjhtYFqdwRCUp5LbFnDAuH3PADDnk2pZo=",
274 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEXu8iQwSCRSf2CbITGpUpBtFVt8+I0IU0d1C36Lfe1+fbwdaI0Z5FktfM2fBoI1bXBd18k2ggKGYGgdZBgLKTg==",
275 | "url": "https://nessie2023.ct.digicert.com/log/",
276 | "start": "2023-01-01T00:00:00Z",
277 | "end": "2024-01-01T00:00:00Z"
278 | }
279 | ],
280 | "sectigo_sabre": {
281 | "log_id": "VYHUwhaQNgFK6gubVzxT8MDkOHhwJQgXL6OqHQcT0ww=",
282 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8m/SiQ8/xfiHHqtls9m7FyOMBg4JVZY9CgiixXGz0akvKD6DEL8S0ERmFe9U4ZiA0M4kbT5nmuk3I85Sk4bagA==",
283 | "url": "https://sabre.ct.comodo.com/"
284 | },
285 | "sectigo_mammoth": {
286 | "log_id": "b1N2rDHwMRnYmQCkURX/dxUcEdkCwQApBo2yCJo32RM=",
287 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7+R9dC4VFbbpuyOL+yy14ceAmEf7QGlo/EmtYU6DRzwat43f/3swtLr/L8ugFOOt1YU/RFmMjGCL17ixv66MZw==",
288 | "url": "https://mammoth.ct.comodo.com/"
289 | },
290 | "lets_encrypt_oak": [
291 | {
292 | "log_id": "5xLysDd+GmL7jskMYYTx6ns3y1YdESZb8+DzS/JBVG4=",
293 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfzb42Zdr/h7hgqgDCo1vrNJqGqbcUvJGJEER9DDqp19W/wFSB0l166hD+U5cAXchpH8ZkBNUuvOHS0OnJ4oJrQ==",
294 | "url": "https://oak.ct.letsencrypt.org/2020/",
295 | "start": "2020-01-01T00:00:00Z",
296 | "end": "2021-01-07T00:00:00Z"
297 | },
298 | {
299 | "log_id": "lCC8Ho7VjWyIcx+CiyIsDdHaTV5sT5Q9YdtOL1hNosI=",
300 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELsYzGMNwo8rBIlaklBIdmD2Ofn6HkfrjK0Ukz1uOIUC6Lm0jTITCXhoIdjs7JkyXnwuwYiJYiH7sE1YeKu8k9w==",
301 | "url": "https://oak.ct.letsencrypt.org/2021/",
302 | "start": "2021-01-01T00:00:00Z",
303 | "end": "2022-01-07T00:00:00Z"
304 | },
305 | {
306 | "log_id": "36Veq2iCTx9sre64X04+WurNohKkal6OOxLAIERcKnM=",
307 | "key": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhjyxDVIjWt5u9sB/o2S8rcGJ2pdZTGA8+IpXhI/tvKBjElGE5r3de4yAfeOPhqTqqc+o7vPgXnDgu/a9/B+RLg==",
308 | "url": "https://oak.ct.letsencrypt.org/2022/",
309 | "start": "2022-01-01T00:00:00Z",
310 | "end": "2023-01-07T00:00:00Z"
311 | }
312 | ]
313 | },
314 | "certificates": {
315 | "": {
316 | "common_name": "",
317 | "alt_names": {
318 | "": ["@", ""]
319 | },
320 | "services": [""],
321 | "tlsa_records": {
322 | "": [
323 | "",
324 | {
325 | "host": "",
326 | "port": ,
327 | "usage": "pkix-ee",
328 | "selector": "spki",
329 | "protocol": "tcp",
330 | "ttl": 300
331 | }
332 | ]
333 | },
334 | "dhparam_size": 2048,
335 | "ecparam_curve": "secp384r1",
336 | "key_types": ["rsa", "ecdsa"],
337 | "key_size": 4096,
338 | "key_curve": "secp384r1",
339 | "key_cipher": "blowfish",
340 | "key_passphrase": null,
341 | "key_provided": false,
342 | "expiration_days": 730,
343 | "auto_rollover": false,
344 | "hpkp_days": 30,
345 | "pin_subdomains": true,
346 | "hpkp_report_uri": null,
347 | "ocsp_must_staple": false,
348 | "ocsp_responder_urls": ["http://ocsp.int-x3.letsencrypt.org"],
349 | "ct_submit_logs": ["google_icarus", "google_pilot"],
350 | "verify": [
351 | 443,
352 | {
353 | "port": 25,
354 | "hosts": ["", ""],
355 | "starttls": "smtp",
356 | "key_types": ["rsa", "ecdsa"]
357 | }
358 | ]
359 | }
360 | },
361 | "private_keys": {
362 | "": {
363 | "certificates": {
364 | "": {
365 | "common_name": "",
366 | "alt_names": {
367 | "": ["@", ""]
368 | },
369 | "services": [""],
370 | "tlsa_records": {
371 | "": [
372 | "",
373 | {
374 | "host": "",
375 | "port": ,
376 | "usage": "pkix-ee",
377 | "selector": "spki",
378 | "protocol": "tcp",
379 | "ttl": 300
380 | }
381 | ]
382 | },
383 | "dhparam_size": 2048,
384 | "ecparam_curve": "secp384r1",
385 | "key_types": ["rsa", "ecdsa"],
386 | "ocsp_must_staple": false,
387 | "ocsp_responder_urls": ["http://ocsp.int-x3.letsencrypt.org"],
388 | "ct_submit_logs": ["google_icarus", "google_pilot"],
389 | "verify": [
390 | 443,
391 | {
392 | "port": 25,
393 | "hosts": ["", ""],
394 | "starttls": "smtp",
395 | "key_types": ["rsa", "ecdsa"]
396 | }
397 | ]
398 | }
399 | },
400 | "key_types": ["rsa", "ecdsa"],
401 | "key_size": 4096,
402 | "key_curve": "secp384r1",
403 | "key_cipher": "blowfish",
404 | "key_passphrase": null,
405 | "key_provided": false,
406 | "expiration_days": 730,
407 | "auto_rollover": false,
408 | "hpkp_days": 30,
409 | "pin_subdomains": true,
410 | "hpkp_report_uri": null
411 | }
412 | },
413 | "authorizations": {
414 | "": ["", ""]
415 | },
416 | "http_challenges": {
417 | "": ""
418 | },
419 | "zone_update_keys": {
420 | "": "",
421 | "": {
422 | "file": "",
423 | "server": "",
424 | "port":
425 | }
426 | }
427 | }
428 |
429 |
--------------------------------------------------------------------------------
/config/acmebot.example.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | account:
3 | email: ""
4 |
5 | settings:
6 | follower_mode: false
7 | log_level: debug
8 | color_output: true
9 | key_size: 4096
10 | key_curve: secp384r1
11 | key_cipher: blowfish
12 | key_passphrase: null
13 | key_provided: false
14 | dhparam_size: 2048
15 | ecparam_curve: secp384r1
16 | file_user: root
17 | file_group: ssl-cert
18 | hpkp_days: 60
19 | pin_subdomains: true
20 | hpkp_report_uri: null
21 | ocsp_must_staple: false
22 | ocsp_responder_urls:
23 | - http://ocsp.int-x3.letsencrypt.org
24 | ct_submit_logs:
25 | - google_icarus
26 | - google_pilot
27 | renewal_days: 30
28 | expiration_days: 730
29 | auto_rollover: false
30 | max_dns_lookup_attempts: 60
31 | dns_lookup_delay: 10
32 | max_domains_per_order: 100
33 | max_authorization_attempts: 30
34 | authorization_delay: 10
35 | cert_poll_time: 30
36 | max_ocsp_verify_attempts: 10
37 | ocsp_verify_retry_delay: 5
38 | min_run_delay: 300
39 | max_run_delay: 3600
40 | acme_directory_url: https://acme-v02.api.letsencrypt.org/directory
41 | reload_zone_command: /etc/bind/reload-zone.sh
42 | nsupdate_command: /usr/bin/nsupdate
43 | public_suffix_list_url: https://publicsuffix.org/list/public_suffix_list.dat
44 |
45 | directories:
46 | pid: /var/run
47 | log: /var/log/acmebot
48 | resource: /var/local/acmebot
49 | private_key: /etc/ssl/private
50 | backup_key: /etc/ssl/private
51 | previous_key: null
52 | full_key: /etc/ssl/private
53 | certificate: /etc/ssl/certs
54 | full_certificate: /etc/ssl/certs
55 | chain: /etc/ssl/certs
56 | param: /etc/ssl/params
57 | challenge: /etc/ssl/challenges
58 | http_challenge: null
59 | hpkp: /etc/ssl/hpkp
60 | ocsp: /etc/ssl/ocsp
61 | sct: "/etc/ssl/scts/{name}/{key_type}"
62 | update_key: /etc/ssl/update_keys
63 | archive: /etc/ssl/archive
64 | temp: null
65 |
66 | key_type_suffixes:
67 | rsa: .rsa
68 | ecdsa: .ecdsa
69 |
70 | file_names:
71 | log: acmebot.log
72 | private_key: "{name}{suffix}.key"
73 | backup_key: "{name}_backup{suffix}.key"
74 | previous_key: "{name}_previous{suffix}.key"
75 | full_key: "{name}_full{suffix}.key"
76 | certificate: "{name}{suffix}.pem"
77 | full_certificate: "{name}+root{suffix}.pem"
78 | chain: "{name}_chain{suffix}.pem"
79 | param: "{name}_param.pem"
80 | challenge: "{name}"
81 | hpkp: "{name}.{server}"
82 | ocsp: "{name}{suffix}.ocsp"
83 | sct: "{ct_log_name}.sct"
84 |
85 | hpkp_headers:
86 | apache: "Header always set Public-Key-Pins \"{header}\"\n"
87 | nginx: "add_header Public-Key-Pins \"{header}\" always;\n"
88 |
89 | services:
90 | apache: systemctl reload apache2
91 | coturn: systemctl restart coturn
92 | dovecot: systemctl restart dovecot
93 | etherpad: systemctl restart etherpad
94 | mysql: systemctl reload mysql
95 | nginx: systemctl reload nginx
96 | postfix: systemctl reload postfix
97 | postgresql: systemctl reload postgresql
98 | prosody: systemctl restart prosody
99 | slapd: systemctl restart slapd
100 | synapse: systemctl restart matrix-synapse
101 | znc: systemctl restart znc
102 |
103 | hooks:
104 | set_dns_challenge:
105 | clear_dns_challenge:
106 | dns_zone_update:
107 | set_http_challenge:
108 | clear_http_challenge:
109 | private_key_rollover:
110 | private_key_installed:
111 | backup_key_installed:
112 | previous_key_installed:
113 | hpkp_header_installed:
114 | certificate_installed:
115 | full_certificate_installed:
116 | chain_installed:
117 | full_key_installed:
118 | params_installed:
119 | sct_installed:
120 | ocsp_installed:
121 |
122 | ct_logs:
123 | google_argon:
124 | - log_id: sh4FzIuizYogTodm+Su5iiUgZ2va+nDnsklTLe+LkF4=
125 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6Tx2p1yKY4015NyIYvdrk36es0uAc1zA4PQ+TGRY+3ZjUTIYY9Wyu+3q/147JG4vNVKLtDWarZwVqGkg6lAYzA==
126 | url: https://ct.googleapis.com/logs/argon2020/
127 | start: 2020-01-01T00:00:00Z
128 | end: 2021-01-01T00:00:00Z
129 | - log_id: 9lyUL9F3MCIUVBgIMJRWjuNNExkzv98MLyALzE7xZOM=
130 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETeBmZOrzZKo4xYktx9gI2chEce3cw/tbr5xkoQlmhB18aKfsxD+MnILgGNl0FOm0eYGilFVi85wLRIOhK8lxKw==
131 | url: https://ct.googleapis.com/logs/argon2021/
132 | start: 2021-01-01T00:00:00Z
133 | end: 2022-01-01T00:00:00Z
134 | - log_id: KXm+8J45OSHwVnOfY6V35b5XfZxgCvj5TV0mXCVdx4Q=
135 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeIPc6fGmuBg6AJkv/z7NFckmHvf/OqmjchZJ6wm2qN200keRDg352dWpi7CHnSV51BpQYAj1CQY5JuRAwrrDwg==
136 | url: https://ct.googleapis.com/logs/argon2022/
137 | start: 2022-01-01T00:00:00Z
138 | end: 2023-01-01T00:00:00Z
139 | - log_id: 6D7Q2j71BjUy51covIlryQPTy9ERa+zraeF3fW0GvW4=
140 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE0JCPZFJOQqyEti5M8j13ALN3CAVHqkVM4yyOcKWCu2yye5yYeqDpEXYoALIgtM3TmHtNlifmt+4iatGwLpF3eA==
141 | url: https://ct.googleapis.com/logs/argon2023/
142 | start: 2023-01-01T00:00:00Z
143 | end: 2024-01-01T00:00:00Z
144 | google_xenon:
145 | - log_id: B7dcG+V9aP/xsMYdIxXHuuZXfFeUt2ruvGE6GmnTohw=
146 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZU75VqjyzSTgFZKAnWg1QeYfFFIRZTMK7q3kWWZsmHhQdrBYnHRZ3OA4kUeUx0JN+xX+dSgt1ruqUhhl7jOvmw==
147 | url: https://ct.googleapis.com/logs/xenon2020/
148 | start: 2020-01-01T00:00:00Z
149 | end: 2021-01-01T00:00:00Z
150 | - log_id: fT7y+I//iFVoJMLAyp5SiXkrxQ54CX8uapdomX4i8Nc=
151 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAER+1MInu8Q39BwDZ5Rp9TwXhwm3ktvgJzpk/r7dDgGk7ZacMm3ljfcoIvP1E72T8jvyLT1bvdapylajZcTH6W5g==
152 | url: https://ct.googleapis.com/logs/xenon2021/
153 | start: 2021-01-01T00:00:00Z
154 | end: 2022-01-01T00:00:00Z
155 | - log_id: RqVV63X6kSAwtaKJafTzfREsQXS+/Um4havy/HD+bUc=
156 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE+WS9FSxAYlCVEzg8xyGwOrmPonoV14nWjjETAIdZvLvukPzIWBMKv6tDNlQjpIHNrUcUt1igRPpqoKDXw2MeKw==
157 | url: https://ct.googleapis.com/logs/xenon2022/
158 | start: 2022-01-01T00:00:00Z
159 | end: 2023-01-01T00:00:00Z
160 | - log_id: rfe++nz/EMiLnT2cHj4YarRnKV3PsQwkyoWGNOvcgoo=
161 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEchY+C+/vzj5g3ZXLY3q5qY1Kb2zcYYCmRV4vg6yU84WI0KV00HuO/8XuQqLwLZPjwtCymeLhQunSxgAnaXSuzg==
162 | url: https://ct.googleapis.com/logs/xenon2023/
163 | start: 2023-01-01T00:00:00Z
164 | end: 2024-01-01T00:00:00Z
165 | cloudflare_numbus:
166 | - log_id: Xqdz+d9WwOe1Nkh90EngMnqRmgyEoRIShBh1loFxRVg=
167 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE01EAhx4o0zPQrXTcYjgCt4MVFsT0Pwjzb1RwrM0lhWDlxAYPP6/gyMCXNkOn/7KFsjL7rwk78tHMpY8rXn8AYg==
168 | url: https://ct.cloudflare.com/logs/nimbus2020/
169 | start: 2020-01-01T00:00:00Z
170 | end: 2021-01-01T00:00:00Z
171 | - log_id: RJRlLrDuzq/EQAfYqP4owNrmgr7YyzG1P9MzlrW2gag=
172 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExpon7ipsqehIeU1bmpog9TFo4Pk8+9oN8OYHl1Q2JGVXnkVFnuuvPgSo2Ep+6vLffNLcmEbxOucz03sFiematg==
173 | url: https://ct.cloudflare.com/logs/nimbus2021/
174 | start: 2021-01-01T00:00:00Z
175 | end: 2022-01-01T00:00:00Z
176 | - log_id: QcjKsd8iRkoQxqE6CUKHXk4xixsD6+tLx2jwkGKWBvY=
177 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESLJHTlAycmJKDQxIv60pZG8g33lSYxYpCi5gteI6HLevWbFVCdtZx+m9b+0LrwWWl/87mkNN6xE0M4rnrIPA/w==
178 | url: https://ct.cloudflare.com/logs/nimbus2022/
179 | start: 2022-01-01T00:00:00Z
180 | end: 2023-01-01T00:00:00Z
181 | - log_id: ejKMVNi3LbYg6jjgUh7phBZwMhOFTTvSK8E6V6NS61I=
182 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEi/8tkhjLRp0SXrlZdTzNkTd6HqmcmXiDJz3fAdWLgOhjmv4mohvRhwXul9bgW0ODgRwC9UGAgH/vpGHPvIS1qA==
183 | url: https://ct.cloudflare.com/logs/nimbus2023/
184 | start: 2023-01-01T00:00:00Z
185 | end: 2024-01-01T00:00:00Z
186 | digicert_log_server:
187 | log_id: VhQGmi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0=
188 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAkbFvhu7gkAW6MHSrBlpE1n4+HCFRkC5OLAjgqhkTH+/uzSfSl8ois8ZxAD2NgaTZe1M9akhYlrYkes4JECs6A==
189 | url: https://ct1.digicert-ct.com/log/
190 | digicert_log_server_2:
191 | log_id: h3W/51l8+IxDmV+9827/Vo1HVjb/SrVgwbTq/16ggw8=
192 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEzF05L2a4TH/BLgOhNKPoioYCrkoRxvcmajeb8Dj4XQmNY+gxa4Zmz3mzJTwe33i0qMVp+rfwgnliQ/bM/oFmhA==
193 | url: https://ct2.digicert-ct.com/log/
194 | digicert_yeti:
195 | - log_id: 8JWkWfIA0YJAEC0vk4iOrUv+HUfjmeHQNKawqKqOsnM=
196 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEURAG+Zo0ac3n37ifZKUhBFEV6jfcCzGIRz3tsq8Ca9BP/5XUHy6ZiqsPaAEbVM0uI3Tm9U24RVBHR9JxDElPmg==
197 | url: https://yeti2020.ct.digicert.com/log/
198 | start: 2020-01-01T00:00:00Z
199 | end: 2021-01-01T00:00:00Z
200 | - log_id: XNxDkv7mq0VEsV6a1FbmEDf71fpH3KFzlLJe5vbHDso=
201 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6J4EbcpIAl1+AkSRsbhoY5oRTj3VoFfaf1DlQkfi7Rbe/HcjfVtrwN8jaC+tQDGjF+dqvKhWJAQ6Q6ev6q9Mew==
202 | url: https://yeti2021.ct.digicert.com/log/
203 | start: 2021-01-01T00:00:00Z
204 | end: 2022-01-01T00:00:00Z
205 | - log_id: IkVFB1lVJFaWP6Ev8fdthuAjJmOtwEt/XcaDXG7iDwI=
206 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEn/jYHd77W1G1+131td5mEbCdX/1v/KiYW5hPLcOROvv+xA8Nw2BDjB7y+RGyutD2vKXStp/5XIeiffzUfdYTJg==
207 | url: https://yeti2022.ct.digicert.com/log/
208 | start: 2022-01-01T00:00:00Z
209 | end: 2023-01-01T00:00:00Z
210 | - log_id: Nc8ZG7+xbFe/D61MbULLu7YnICZR6j/hKu+oA8M71kw=
211 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfQ0DsdWYitzwFTvG3F4Nbj8Nv5XIVYzQpkyWsU4nuSYlmcwrAp6m092fsdXEw6w1BAeHlzaqrSgNfyvZaJ9y0Q==
212 | url: https://yeti2023.ct.digicert.com/log/
213 | start: 2023-01-01T00:00:00Z
214 | end: 2024-01-01T00:00:00Z
215 | digicert_nessie:
216 | - log_id: xlKg7EjOs/yrFwmSxDqHQTMJ6ABlomJSQBujNioXxWU=
217 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4hHIyMVIrR9oShgbQMYEk8WX1lmkfFKB448Gn93KbsZnnwljDHY6MQqEnWfKGgMOq0gh3QK48c5ZB3UKSIFZ4g==
218 | url: https://nessie2020.ct.digicert.com/log/
219 | start: 2020-01-01T00:00:00Z
220 | end: 2021-01-01T00:00:00Z
221 | - log_id: 7sCV7o1yZA+S48O5G8cSo2lqCXtLahoUOOZHssvtxfk=
222 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9o7AiwrbGBIX6Lnc47I6OfLMdZnRzKoP5u072nBi6vpIOEooktTi1gNwlRPzGC2ySGfuc1xLDeaA/wSFGgpYFg==
223 | url: https://nessie2021.ct.digicert.com/log/
224 | start: 2021-01-01T00:00:00Z
225 | end: 2022-01-01T00:00:00Z
226 | - log_id: UaOw9f0BeZxWbbg3eI8MpHrMGyfL956IQpoN/tSLBeU=
227 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEJyTdaAMoy/5jvg4RR019F2ihEV1McclBKMe2okuX7MCv/C87v+nxsfz1Af+p+0lADGMkmNd5LqZVqxbGvlHYcQ==
228 | url: https://nessie2022.ct.digicert.com/log/
229 | start: 2022-01-01T00:00:00Z
230 | end: 2023-01-01T00:00:00Z
231 | - log_id: s3N3B+GEUPhjhtYFqdwRCUp5LbFnDAuH3PADDnk2pZo=
232 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEXu8iQwSCRSf2CbITGpUpBtFVt8+I0IU0d1C36Lfe1+fbwdaI0Z5FktfM2fBoI1bXBd18k2ggKGYGgdZBgLKTg==
233 | url: https://nessie2023.ct.digicert.com/log/
234 | start: 2023-01-01T00:00:00Z
235 | end: 2024-01-01T00:00:00Z
236 | sectigo_sabre:
237 | log_id: VYHUwhaQNgFK6gubVzxT8MDkOHhwJQgXL6OqHQcT0ww=
238 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8m/SiQ8/xfiHHqtls9m7FyOMBg4JVZY9CgiixXGz0akvKD6DEL8S0ERmFe9U4ZiA0M4kbT5nmuk3I85Sk4bagA==
239 | url: https://sabre.ct.comodo.com/
240 | sectigo_mammoth:
241 | log_id: b1N2rDHwMRnYmQCkURX/dxUcEdkCwQApBo2yCJo32RM=
242 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE7+R9dC4VFbbpuyOL+yy14ceAmEf7QGlo/EmtYU6DRzwat43f/3swtLr/L8ugFOOt1YU/RFmMjGCL17ixv66MZw==
243 | url: https://mammoth.ct.comodo.com/
244 | lets_encrypt_oak:
245 | - log_id: 5xLysDd+GmL7jskMYYTx6ns3y1YdESZb8+DzS/JBVG4=
246 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfzb42Zdr/h7hgqgDCo1vrNJqGqbcUvJGJEER9DDqp19W/wFSB0l166hD+U5cAXchpH8ZkBNUuvOHS0OnJ4oJrQ==
247 | url: https://oak.ct.letsencrypt.org/2020/
248 | start: 2020-01-01T00:00:00Z
249 | end: 2021-01-07T00:00:00Z
250 | - log_id: lCC8Ho7VjWyIcx+CiyIsDdHaTV5sT5Q9YdtOL1hNosI=
251 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELsYzGMNwo8rBIlaklBIdmD2Ofn6HkfrjK0Ukz1uOIUC6Lm0jTITCXhoIdjs7JkyXnwuwYiJYiH7sE1YeKu8k9w==
252 | url: https://oak.ct.letsencrypt.org/2021/
253 | start: 2021-01-01T00:00:00Z
254 | end: 2022-01-07T00:00:00Z
255 | - log_id: 36Veq2iCTx9sre64X04+WurNohKkal6OOxLAIERcKnM=
256 | key: MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEhjyxDVIjWt5u9sB/o2S8rcGJ2pdZTGA8+IpXhI/tvKBjElGE5r3de4yAfeOPhqTqqc+o7vPgXnDgu/a9/B+RLg==
257 | url: https://oak.ct.letsencrypt.org/2022/
258 | start: 2022-01-01T00:00:00Z
259 | end: 2023-01-07T00:00:00Z
260 |
261 | certificates:
262 | :
263 | common_name:
264 | alt_names:
265 | :
266 | - "@",
267 | -
268 | services:
269 | -
270 | tlsa_records:
271 | :
272 | -
273 | - host:
274 | port:
275 | usage: pkix-ee
276 | selector: spki
277 | protocol: tcp
278 | ttl: 300
279 | dhparam_size: 2048
280 | ecparam_curve: secp384r1
281 | key_types:
282 | - rsa
283 | - ecdsa
284 | key_size: 4096
285 | key_curve: secp384r1
286 | key_cipher: blowfish
287 | key_passphrase:
288 | key_provided: false
289 | expiration_days: 730
290 | auto_rollover: false
291 | hpkp_days: 30
292 | pin_subdomains: true
293 | hpkp_report_uri:
294 | ocsp_must_staple: false
295 | ocsp_responder_urls:
296 | - http://ocsp.int-x3.letsencrypt.org"
297 | ct_submit_logs:
298 | - google_icarus
299 | - google_pilot
300 | verify:
301 | - 443,
302 | - port: 25
303 | hosts:
304 | -
305 | -
306 | starttls: smtp
307 | key_types:
308 | - rsa
309 | - ecdsa
310 |
311 | private_keys:
312 | :
313 | certificates:
314 | :
315 | common_name:
316 | alt_names:
317 | :
318 | - "@"
319 | -
320 | services:
321 | -
322 | tlsa_records:
323 | :
324 | -
325 | - host:
326 | port:
327 | usage: pkix-ee
328 | selector: spki
329 | protocol: tcp
330 | ttl: 300
331 | dhparam_size: 2048
332 | ecparam_curve: secp384r1
333 | key_types:
334 | - rsa
335 | - ecdsa
336 | ocsp_must_staple: false
337 | ocsp_responder_urls:
338 | - "http://ocsp.int-x3.letsencrypt.org"
339 | ct_submit_logs:
340 | - google_icarus
341 | - google_pilot
342 | verify:
343 | - 443
344 | - port: 25
345 | hosts:
346 | -
347 | -
348 | starttls: smtp
349 | key_types:
350 | - rsa
351 | - ecdsa
352 | key_types:
353 | - rsa
354 | - ecdsa
355 | key_size: 4096
356 | key_curve: secp384r1
357 | key_cipher: blowfish
358 | key_passphrase:
359 | key_provided: false
360 | expiration_days: 730
361 | auto_rollover: false
362 | hpkp_days: 30
363 | pin_subdomains: true
364 | hpkp_report_uri: null
365 |
366 | authorizations:
367 | :
368 | -
369 | -
370 |
371 | http_challenges:
372 | :
373 |
374 | zone_update_keys:
375 | :
376 | :
377 | file:
378 | server:
379 | port:
380 |
--------------------------------------------------------------------------------
/logrotate.d/acmebot:
--------------------------------------------------------------------------------
1 | /var/log/acmebot/*.log {
2 | weekly
3 | missingok
4 | rotate 12
5 | compress
6 | delaycompress
7 | notifempty
8 | }
9 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ['setuptools', 'setuptools_scm']
3 | build-backend = 'setuptools.build_meta'
4 |
5 |
6 | [project]
7 | name = 'acmebot'
8 | description = 'ACME protocol automatic certitificate manager'
9 | readme = 'README.rst'
10 | requires-python = '>= 3.8'
11 | dependencies = [
12 | 'appdirs >= 1.4.3, < 2.0.0',
13 | 'pyparsing >= 2.2.0, < 3.2.0',
14 | 'packaging >= 16.8',
15 | 'pyOpenSSL >= 17.5.0',
16 | 'py3dns >= 3.1.0, < 5.0.0',
17 | 'cryptography >= 2.6.1',
18 | 'asn1crypto >= 0.24.0, < 2.0.0',
19 | 'acme >= 2.0.0, < 4.0.0',
20 | 'PyYAML >= 3.1, < 7.0.0',
21 | 'josepy >=1.0.0, < 2.0.0',
22 | ]
23 | dynamic = ['version']
24 |
25 |
26 | [[project.authors]]
27 | name = 'Peter Linss'
28 | email = 'peter@linss.com'
29 |
30 |
31 | [project.urls]
32 | homepage = 'https://acmebot.org'
33 |
34 |
35 | [project.scripts]
36 | acmebot = "acmebot:run"
37 |
38 |
39 | [project.optional-dependencies]
40 | dev = [
41 | 'types-PyYAML',
42 | 'mypy',
43 | 'flake8',
44 | 'flake8-annotations',
45 | 'flake8-bandit',
46 | 'flake8-bugbear',
47 | 'flake8-commas',
48 | 'flake8-comprehensions',
49 | 'flake8-continuation',
50 | 'flake8-datetimez',
51 | 'flake8-docstrings',
52 | 'flake8-import-order',
53 | 'flake8-literal',
54 | 'flake8-modern-annotations',
55 | 'flake8-noqa',
56 | 'flake8-pyproject',
57 | 'flake8-requirements',
58 | 'flake8-typechecking-import',
59 | 'flake8-use-fstring',
60 | 'pep8-naming',
61 | ]
62 |
63 |
64 | [tool.setuptools_scm]
65 |
66 |
67 | [tool.flake8]
68 | ignore = ['D107', 'D401', 'W503', 'ANN002', 'ANN003', 'ANN101', 'ANN102', 'ANN401', 'FS003', 'S110']
69 | max-line-length = 120
70 |
71 |
72 | [tool.mypy]
73 | mypy_path = 'stubs'
74 |
--------------------------------------------------------------------------------
/src/acmebot/__init__.py:
--------------------------------------------------------------------------------
1 | """ACMEbot module."""
2 |
3 | from .acmebot import AcmeError, AcmeManager, ErrorCode, PrivateKeyError
4 |
5 | __all__ = ['AcmeManager', 'AcmeError', 'ErrorCode', 'PrivateKeyError']
6 |
7 | def run() -> int:
8 | exit_code = ErrorCode.EXCEPTION
9 | manager = None
10 | try:
11 | manager = AcmeManager()
12 | manager.run()
13 | except AcmeError:
14 | pass
15 | if (manager):
16 | exit_code = manager.exit_code
17 | try:
18 | del manager
19 | except Exception:
20 | pass
21 | return exit_code
22 |
23 | if __name__ == '__main__': # called from the command line
24 | sys.exit(run())
25 |
--------------------------------------------------------------------------------