├── .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 | --------------------------------------------------------------------------------