├── .gitignore ├── Dockerfile ├── LICENSE.txt ├── MANIFEST.in ├── README.rst ├── certbot_dns_standalone ├── __init__.py ├── dns_standalone.py └── dns_standalone_test.py ├── docs ├── .gitignore ├── Makefile ├── api.rst ├── api │ └── dns_standalone.rst ├── conf.py ├── index.rst └── make.bat ├── local-oldest-requirements.txt ├── readthedocs.org.requirements.txt ├── setup.cfg ├── setup.py ├── snap-constraints.txt └── snap └── snapcraft.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.egg-info/ 3 | .eggs/ 4 | build/ 5 | dist*/ 6 | /venv*/ 7 | /kgs/ 8 | /.tox/ 9 | /releases*/ 10 | /log* 11 | letsencrypt.log 12 | certbot.log 13 | letsencrypt-auto-source/letsencrypt-auto.sig.lzma.base64 14 | 15 | # coverage 16 | .coverage 17 | /htmlcov/ 18 | 19 | /.vagrant 20 | 21 | tags 22 | 23 | # editor temporary files 24 | *~ 25 | *.sw? 26 | \#*# 27 | .idea 28 | .ropeproject 29 | 30 | # auth --cert-path --chain-path 31 | /*.pem 32 | 33 | # letstest 34 | tests/letstest/letest-*/ 35 | tests/letstest/*.pem 36 | tests/letstest/venv/ 37 | 38 | .venv 39 | 40 | # pytest cache 41 | .cache 42 | .mypy_cache/ 43 | .pytest_cache/ 44 | 45 | # docker files 46 | .docker 47 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM certbot/certbot 2 | 3 | ENTRYPOINT [ "certbot" ] 4 | EXPOSE 80 443 5 | VOLUME /etc/letsencrypt /var/lib/letsencrypt 6 | WORKDIR /opt/certbot 7 | 8 | COPY . /opt/certbot/src/plugin 9 | RUN python tools/pip_install.py --no-cache-dir --editable /opt/certbot/src/plugin 10 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2015 Electronic Frontier Foundation and others 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | 15 | Apache License 16 | Version 2.0, January 2004 17 | http://www.apache.org/licenses/ 18 | 19 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 20 | 21 | 1. Definitions. 22 | 23 | "License" shall mean the terms and conditions for use, reproduction, 24 | and distribution as defined by Sections 1 through 9 of this document. 25 | 26 | "Licensor" shall mean the copyright owner or entity authorized by 27 | the copyright owner that is granting the License. 28 | 29 | "Legal Entity" shall mean the union of the acting entity and all 30 | other entities that control, are controlled by, or are under common 31 | control with that entity. For the purposes of this definition, 32 | "control" means (i) the power, direct or indirect, to cause the 33 | direction or management of such entity, whether by contract or 34 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 35 | outstanding shares, or (iii) beneficial ownership of such entity. 36 | 37 | "You" (or "Your") shall mean an individual or Legal Entity 38 | exercising permissions granted by this License. 39 | 40 | "Source" form shall mean the preferred form for making modifications, 41 | including but not limited to software source code, documentation 42 | source, and configuration files. 43 | 44 | "Object" form shall mean any form resulting from mechanical 45 | transformation or translation of a Source form, including but 46 | not limited to compiled object code, generated documentation, 47 | and conversions to other media types. 48 | 49 | "Work" shall mean the work of authorship, whether in Source or 50 | Object form, made available under the License, as indicated by a 51 | copyright notice that is included in or attached to the work 52 | (an example is provided in the Appendix below). 53 | 54 | "Derivative Works" shall mean any work, whether in Source or Object 55 | form, that is based on (or derived from) the Work and for which the 56 | editorial revisions, annotations, elaborations, or other modifications 57 | represent, as a whole, an original work of authorship. For the purposes 58 | of this License, Derivative Works shall not include works that remain 59 | separable from, or merely link (or bind by name) to the interfaces of, 60 | the Work and Derivative Works thereof. 61 | 62 | "Contribution" shall mean any work of authorship, including 63 | the original version of the Work and any modifications or additions 64 | to that Work or Derivative Works thereof, that is intentionally 65 | submitted to Licensor for inclusion in the Work by the copyright owner 66 | or by an individual or Legal Entity authorized to submit on behalf of 67 | the copyright owner. For the purposes of this definition, "submitted" 68 | means any form of electronic, verbal, or written communication sent 69 | to the Licensor or its representatives, including but not limited to 70 | communication on electronic mailing lists, source code control systems, 71 | and issue tracking systems that are managed by, or on behalf of, the 72 | Licensor for the purpose of discussing and improving the Work, but 73 | excluding communication that is conspicuously marked or otherwise 74 | designated in writing by the copyright owner as "Not a Contribution." 75 | 76 | "Contributor" shall mean Licensor and any individual or Legal Entity 77 | on behalf of whom a Contribution has been received by Licensor and 78 | subsequently incorporated within the Work. 79 | 80 | 2. Grant of Copyright License. Subject to the terms and conditions of 81 | this License, each Contributor hereby grants to You a perpetual, 82 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 83 | copyright license to reproduce, prepare Derivative Works of, 84 | publicly display, publicly perform, sublicense, and distribute the 85 | Work and such Derivative Works in Source or Object form. 86 | 87 | 3. Grant of Patent License. Subject to the terms and conditions of 88 | this License, each Contributor hereby grants to You a perpetual, 89 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 90 | (except as stated in this section) patent license to make, have made, 91 | use, offer to sell, sell, import, and otherwise transfer the Work, 92 | where such license applies only to those patent claims licensable 93 | by such Contributor that are necessarily infringed by their 94 | Contribution(s) alone or by combination of their Contribution(s) 95 | with the Work to which such Contribution(s) was submitted. If You 96 | institute patent litigation against any entity (including a 97 | cross-claim or counterclaim in a lawsuit) alleging that the Work 98 | or a Contribution incorporated within the Work constitutes direct 99 | or contributory patent infringement, then any patent licenses 100 | granted to You under this License for that Work shall terminate 101 | as of the date such litigation is filed. 102 | 103 | 4. Redistribution. You may reproduce and distribute copies of the 104 | Work or Derivative Works thereof in any medium, with or without 105 | modifications, and in Source or Object form, provided that You 106 | meet the following conditions: 107 | 108 | (a) You must give any other recipients of the Work or 109 | Derivative Works a copy of this License; and 110 | 111 | (b) You must cause any modified files to carry prominent notices 112 | stating that You changed the files; and 113 | 114 | (c) You must retain, in the Source form of any Derivative Works 115 | that You distribute, all copyright, patent, trademark, and 116 | attribution notices from the Source form of the Work, 117 | excluding those notices that do not pertain to any part of 118 | the Derivative Works; and 119 | 120 | (d) If the Work includes a "NOTICE" text file as part of its 121 | distribution, then any Derivative Works that You distribute must 122 | include a readable copy of the attribution notices contained 123 | within such NOTICE file, excluding those notices that do not 124 | pertain to any part of the Derivative Works, in at least one 125 | of the following places: within a NOTICE text file distributed 126 | as part of the Derivative Works; within the Source form or 127 | documentation, if provided along with the Derivative Works; or, 128 | within a display generated by the Derivative Works, if and 129 | wherever such third-party notices normally appear. The contents 130 | of the NOTICE file are for informational purposes only and 131 | do not modify the License. You may add Your own attribution 132 | notices within Derivative Works that You distribute, alongside 133 | or as an addendum to the NOTICE text from the Work, provided 134 | that such additional attribution notices cannot be construed 135 | as modifying the License. 136 | 137 | You may add Your own copyright statement to Your modifications and 138 | may provide additional or different license terms and conditions 139 | for use, reproduction, or distribution of Your modifications, or 140 | for any such Derivative Works as a whole, provided Your use, 141 | reproduction, and distribution of the Work otherwise complies with 142 | the conditions stated in this License. 143 | 144 | 5. Submission of Contributions. Unless You explicitly state otherwise, 145 | any Contribution intentionally submitted for inclusion in the Work 146 | by You to the Licensor shall be under the terms and conditions of 147 | this License, without any additional terms or conditions. 148 | Notwithstanding the above, nothing herein shall supersede or modify 149 | the terms of any separate license agreement you may have executed 150 | with Licensor regarding such Contributions. 151 | 152 | 6. Trademarks. This License does not grant permission to use the trade 153 | names, trademarks, service marks, or product names of the Licensor, 154 | except as required for reasonable and customary use in describing the 155 | origin of the Work and reproducing the content of the NOTICE file. 156 | 157 | 7. Disclaimer of Warranty. Unless required by applicable law or 158 | agreed to in writing, Licensor provides the Work (and each 159 | Contributor provides its Contributions) on an "AS IS" BASIS, 160 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 161 | implied, including, without limitation, any warranties or conditions 162 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 163 | PARTICULAR PURPOSE. You are solely responsible for determining the 164 | appropriateness of using or redistributing the Work and assume any 165 | risks associated with Your exercise of permissions under this License. 166 | 167 | 8. Limitation of Liability. In no event and under no legal theory, 168 | whether in tort (including negligence), contract, or otherwise, 169 | unless required by applicable law (such as deliberate and grossly 170 | negligent acts) or agreed to in writing, shall any Contributor be 171 | liable to You for damages, including any direct, indirect, special, 172 | incidental, or consequential damages of any character arising as a 173 | result of this License or out of the use or inability to use the 174 | Work (including but not limited to damages for loss of goodwill, 175 | work stoppage, computer failure or malfunction, or any and all 176 | other commercial damages or losses), even if such Contributor 177 | has been advised of the possibility of such damages. 178 | 179 | 9. Accepting Warranty or Additional Liability. While redistributing 180 | the Work or Derivative Works thereof, You may choose to offer, 181 | and charge a fee for, acceptance of support, warranty, indemnity, 182 | or other liability obligations and/or rights consistent with this 183 | License. However, in accepting such obligations, You may act only 184 | on Your own behalf and on Your sole responsibility, not on behalf 185 | of any other Contributor, and only if You agree to indemnify, 186 | defend, and hold each Contributor harmless for any liability 187 | incurred by, or claims asserted against, such Contributor by reason 188 | of your accepting any such warranty or additional liability. 189 | 190 | END OF TERMS AND CONDITIONS 191 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE.txt 2 | include README.rst 3 | recursive-include docs * 4 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Standalone DNS Authenticator plugin for Certbot 2 | =============================================== 3 | 4 | This is a Certbot plugin that uses an integrated DNS server to respond to the 5 | ``_acme-challenge`` records, so the domain's records do not have to be 6 | modified. 7 | 8 | Installation 9 | ============ 10 | 11 | pip 12 | --- 13 | 14 | :: 15 | 16 | # pip3 install certbot certbot-dns-standalone 17 | 18 | snap 19 | ---- 20 | 21 | :: 22 | 23 | # snap install certbot certbot-dns-standalone 24 | # snap set certbot trust-plugin-with-root=ok 25 | # snap connect certbot:plugin certbot-dns-standalone 26 | # snap connect certbot-dns-standalone:certbot-metadata certbot:certbot-metadata 27 | 28 | Debian 29 | ------ 30 | 31 | :: 32 | 33 | # apt-get install certbot python3-certbot-dns-standalone 34 | 35 | Docker 36 | ------ 37 | 38 | See below. 39 | 40 | Usage 41 | ===== 42 | 43 | First, you need to pick a central address for certbot, e.g. 44 | ``acme.example.com``. 45 | 46 | Next, the ``_acme-challenge`` records need to be pointed to 47 | ``$domain.acme.example.com`` using CNAME records, e.g. for ``example.net``: 48 | 49 | :: 50 | 51 | _acme-challenge IN CNAME example.net.acme.example.com. 52 | 53 | Finally, you need to point ``*.acme.example.com`` to certbot. There are two 54 | options for that. 55 | 56 | Firstly, if you have an IP address with port ``53`` available, you could 57 | configure it as the nameserver for ``acme.example.com``: 58 | 59 | :: 60 | 61 | acme IN NS ns.acme.example.com. 62 | ns.acme IN A 1.2.3.4 63 | 64 | where ``1.2.3.4`` is the IP of the server where certbot will be run. This 65 | configuration directs any requests to ``*.acme.example.com`` to ``1.2.3.4`` 66 | where the plugin will respond with the relevant challenge. 67 | 68 | Any server can be used as long as port ``53`` is available which means that 69 | a DNS server cannot be run at that particular IP at the same time. 70 | 71 | You can then run certbot as follows: 72 | 73 | :: 74 | 75 | certbot --non-interactive --agree-tos --email certmaster@example.com certonly \ 76 | --authenticator dns-standalone \ 77 | --dns-standalone-address=1.2.3.4 \ 78 | -d example.net -d '*.example.net' 79 | 80 | Secondly, if you already run a DNS server you could configure it to forward 81 | all requests to ``*.acme.example.com`` to another IP/port instead where you 82 | would run certbot. 83 | 84 | With Knot DNS you can use ``mod-dnsproxy``: 85 | 86 | :: 87 | 88 | remote: 89 | - id: certbot 90 | address: 127.0.0.1@5555 91 | 92 | mod-dnsproxy: 93 | - id: certbot 94 | remote: certbot 95 | fallback: off 96 | 97 | zone: 98 | - domain: acme.example.com 99 | module: mod-dnsproxy/certbot 100 | 101 | Using this configuration all requests to ``*.acme.example.com`` are directed 102 | to ``127.0.0.1`` port ``5555``. 103 | 104 | You can then run certbot as follows: 105 | 106 | :: 107 | 108 | certbot --non-interactive --agree-tos --email certmaster@example.com certonly \ 109 | --authenticator dns-standalone \ 110 | --dns-standalone-address=127.0.0.1 \ 111 | --dns-standalone-port=5555 \ 112 | -d example.net -d '*.example.net' 113 | 114 | By default the plugin binds to all available interfaces. The validation usually 115 | takes less than a second. 116 | 117 | To renew the certificates add ``certbot renew`` to ``crontab``. 118 | 119 | Usage with Docker 120 | ================= 121 | 122 | In order to use the latest image published in Docker Hub, run: 123 | 124 | :: 125 | 126 | docker run -it --rm --name certbot-dns-standalone \ 127 | -v "/etc/letsencrypt:/etc/letsencrypt" \ 128 | -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \ 129 | -p 8080:80 -p 1.2.3.4:53:53/tcp -p 1.2.3.4:53:53/udp \ 130 | laurik/certbot-dns-standalone:latest certonly 131 | 132 | where ``1.2.3.4`` is the IP address to use for responding the challenges. HTTP 133 | challenges should be directed to port ``8080``. 134 | 135 | ``/etc/letsencrypt`` and ``/var/lib/letsencrypt`` need to be mapped to 136 | permanent storage. 137 | 138 | Alternatively, you may also build the plugin image locally by running: 139 | 140 | :: 141 | 142 | docker build -t certbot-dns-standalone-local /path/to/certbot-dns-standalone/ 143 | 144 | and then: 145 | 146 | :: 147 | 148 | docker run -it --rm \ 149 | -v "/etc/letsencrypt:/etc/letsencrypt" \ 150 | -v "/var/lib/letsencrypt:/var/lib/letsencrypt" \ 151 | -p 8080:80 -p 1.2.3.4:53:53/tcp -p 1.2.3.4:53:53/udp \ 152 | certbot-dns-standalone-local certonly 153 | 154 | Supported parameters 155 | ==================== 156 | 157 | Parameters can be specified as ``--dns-standalone-PARAMETER=VALUE``. For older 158 | certbot versions it should be 159 | ``--certbot-dns-standalone:dns-standalone-PARAMETER=VALUE``. 160 | 161 | Supported parameters are: 162 | 163 | * ``address`` -- IPv4 address to bind to, defaults to ``0.0.0.0`` 164 | * ``ipv6-address`` -- IPv6 address to bind to, defaults to ``::`` 165 | * ``port`` -- port to use, defaults to ``53`` 166 | 167 | The relevant parameters in ``/etc/letsencrypt/renewal/*.conf`` are 168 | ``dns_standalone_address``, ``dns_standalone_port`` and 169 | ``dns_standalone_ipv6_address``. 170 | 171 | Third party projects 172 | ==================== 173 | 174 | Third party projects integrating certbot-dns-standalone: 175 | 176 | * `CertCache `_ 177 | -------------------------------------------------------------------------------- /certbot_dns_standalone/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | The `~certbot_dns_standalone.dns_standalone` plugin automates the process of 3 | completing a ``dns-01`` challenge (`~acme.challenges.DNS01`) by using an 4 | integrated DNS server. 5 | 6 | This allows using CNAME records to direct validation elsewhere in case of 7 | domains not under your control or when simply wanting to avoid making changes 8 | to the DNS records. You only need an IP address with a free port 53. 9 | 10 | First you need to choose a subdomain that you will use, e.g. 11 | `acme.example.com`. 12 | 13 | Next, you need to configure the relevant NS and A records 14 | 15 | .. code-block:: none 16 | 17 | acme IN NS ns.acme.example.com. 18 | ns.acme IN A 1.2.3.4 19 | 20 | where `1.2.3.4` the IP of the server that will be running `certbot`. 21 | 22 | Next, you need to configure `_acme-challenge` as a CNAME record to point to 23 | `domain.acme.example.com`, e.g.: 24 | 25 | .. code-block:: none 26 | 27 | _acme-challenge IN CNAME example.org.acme.example.com. 28 | 29 | where `example.org` is the domain you are requesting the certificate for. The 30 | domain name itself is not used anywhere, but it is a good practice to specify 31 | it anyway. 32 | 33 | 34 | Named Arguments 35 | --------------- 36 | 37 | ======================================== ===================================== 38 | ``--dns-standalone-address`` IPv4 address to bind to 39 | (default: 0.0.0.0) 40 | ``--dns-standalone-ipv6-address`` IPv6 address to bind to 41 | (default: ::) 42 | ``--dns-standalone-port`` Port to use 43 | (default: 53) 44 | ======================================== ===================================== 45 | 46 | 47 | Examples 48 | -------- 49 | 50 | .. code-block:: bash 51 | :caption: To acquire a certificate for ``example.com`` using the IP 52 | ``1.2.3.4`` 53 | 54 | certbot certonly \\ 55 | --preferred-challenges dns --authenticator dns-standalone \\ 56 | --dns-standalone-address 1.2.3.4 \\ 57 | --dns-standalone-ipv6-address=:: \\ 58 | --dns-standalone-port=53 \\ 59 | -d example.com 60 | 61 | .. code-block:: bash 62 | :caption: To acquire a single certificate for both ``example.com`` and 63 | ``www.example.com`` using the IP ``1.2.3.4`` 64 | 65 | certbot certonly \\ 66 | --preferred-challenges dns --authenticator dns-standalone \\ 67 | --dns-standalone-address 1.2.3.4 \\ 68 | -d example.com \\ 69 | -d www.example.com 70 | 71 | """ 72 | -------------------------------------------------------------------------------- /certbot_dns_standalone/dns_standalone.py: -------------------------------------------------------------------------------- 1 | """Standalone DNS Authenticator.""" 2 | import logging 3 | 4 | import copy 5 | 6 | from dnslib import RR 7 | from dnslib.server import DNSServer,DNSHandler,BaseResolver,DNSLogger,UDPServer,TCPServer 8 | 9 | from socket import AF_INET6,SOCK_DGRAM 10 | 11 | from certbot import errors 12 | from certbot import interfaces 13 | from certbot.plugins import dns_common 14 | 15 | logger = logging.getLogger(__name__) 16 | dnsLogger = DNSLogger("truncated,error",False) 17 | 18 | 19 | class Authenticator(dns_common.DNSAuthenticator): 20 | """Standalone DNS Authenticator 21 | 22 | This Authenticator uses a standalone DNS server to fulfill a dns-01 challenge. 23 | """ 24 | 25 | description = ('Obtain certificates using an integrated DNS server') 26 | 27 | def __init__(self, *args, **kwargs): 28 | super(Authenticator, self).__init__(*args, **kwargs) 29 | self.resolver = None 30 | self.servers = None 31 | 32 | @classmethod 33 | def add_parser_arguments(cls, add): # pylint: disable=arguments-differ 34 | super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=0) 35 | add('address', help='IP address to bind to.', default='0.0.0.0') 36 | add('ipv6-address', help='IPv6 address to bind to.', default='::') 37 | add('port', help='Port to bind to.', default='53') 38 | 39 | def _setup_credentials(self): 40 | return 41 | 42 | def more_info(self): # pylint: disable=missing-docstring,no-self-use 43 | return 'This plugin uses a standalone DNS server to respond to a dns-01 challenge.' 44 | 45 | def _perform(self, domain, validation_name, validation): 46 | if self.resolver is None: 47 | self.resolver = _AcmeResolver() 48 | 49 | self.resolver.addToken(validation) 50 | 51 | if self.servers is None: 52 | self.servers = [] 53 | active_udp_server = False 54 | error = None 55 | 56 | for Server in [TCP6Server, TCPServer, UDP6Server, UDPServer]: 57 | # Try IPv6 version first since it may listen on IPv4 as well. 58 | try: 59 | if Server.address_family == AF_INET6: 60 | address = self.conf('ipv6-address') 61 | else: 62 | address = self.conf('address') 63 | if address is not None: 64 | server = DNSServer(self.resolver, port=int(self.conf('port')), address=address, 65 | server=Server, logger=dnsLogger) 66 | server.start_thread() 67 | self.servers.append(server) 68 | if Server.socket_type == SOCK_DGRAM: 69 | active_udp_server = True 70 | except Exception as e: 71 | error = e 72 | 73 | if not active_udp_server: 74 | # Re-raise the exception when no UDP server was started successfully. 75 | raise errors.PluginError('Error starting DNS server: {0}'.format(error)) 76 | 77 | def _cleanup(self, domain, validation_name, validation): 78 | if self.servers: 79 | for server in self.servers: 80 | server.stop() 81 | 82 | 83 | class _AcmeResolver(BaseResolver): 84 | def __init__(self): 85 | self.tokens = [] 86 | 87 | def addToken(self,validation): 88 | self.tokens.append(validation) 89 | 90 | def resolve(self,request,handler): 91 | reply = request.reply() 92 | qname = request.q.qname 93 | 94 | if request.q.qtype == 16: 95 | records = "" 96 | for r in self.tokens: 97 | records += ". 60 TXT %s\n" % r 98 | 99 | resp = RR.fromZone(records) 100 | else: 101 | resp = RR.fromZone(". 60 A 127.0.0.1") # for dig 102 | 103 | if request.q.qtype == 1 or request.q.qtype == 16: 104 | for rr in resp: 105 | a = copy.copy(rr) 106 | a.rname = qname 107 | reply.add_answer(a) 108 | 109 | return reply 110 | 111 | class UDP6Server(UDPServer): 112 | address_family = AF_INET6 113 | 114 | class TCP6Server(TCPServer): 115 | address_family = AF_INET6 116 | -------------------------------------------------------------------------------- /certbot_dns_standalone/dns_standalone_test.py: -------------------------------------------------------------------------------- 1 | """Tests for certbot_dns_standalone.dns_standalone.""" 2 | 3 | import os 4 | import unittest 5 | 6 | import mock 7 | 8 | from certbot import errors 9 | from certbot.plugins import dns_test_common 10 | from certbot.plugins.dns_test_common import DOMAIN 11 | from certbot.tests import util as test_util 12 | 13 | 14 | class AuthenticatorTest(test_util.TempDirTestCase, dns_test_common.BaseAuthenticatorTest): 15 | 16 | def setUp(self): 17 | from certbot_dns_standalone.dns_standalone import Authenticator 18 | 19 | super(AuthenticatorTest, self).setUp() 20 | 21 | self.config = mock.MagicMock(standalone_address='127.0.0.1') 22 | 23 | self.auth = Authenticator(self.config, "standalone") 24 | 25 | def test_perform(self): 26 | return # TODO 27 | 28 | def test_perform(self): 29 | return # TODO 30 | 31 | 32 | if __name__ == "__main__": 33 | unittest.main() # pragma: no cover 34 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | /_build/ 2 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = certbot-dns-standalone 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/api.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | API Documentation 3 | ================= 4 | 5 | .. toctree:: 6 | :glob: 7 | 8 | api/** 9 | -------------------------------------------------------------------------------- /docs/api/dns_standalone.rst: -------------------------------------------------------------------------------- 1 | :mod:`certbot_dns_standalone.dns_standalone` 2 | -------------------------------------------- 3 | 4 | .. automodule:: certbot_dns_standalone.dns_standalone 5 | :members: 6 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # certbot-dns-standalone documentation build configuration file, created by 4 | # sphinx-quickstart on Tue May 9 10:20:04 2017. 5 | # 6 | # This file is execfile()d with the current directory set to its 7 | # containing dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | # If extensions (or modules to document with autodoc) are in another directory, 16 | # add these directories to sys.path here. If the directory is relative to the 17 | # documentation root, use os.path.abspath to make it absolute, like shown here. 18 | # 19 | import os 20 | # import sys 21 | # sys.path.insert(0, os.path.abspath('.')) 22 | 23 | 24 | # -- General configuration ------------------------------------------------ 25 | 26 | # If your documentation needs a minimal Sphinx version, state it here. 27 | # 28 | needs_sphinx = '1.0' 29 | 30 | # Add any Sphinx extension module names here, as strings. They can be 31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 32 | # ones. 33 | extensions = ['sphinx.ext.autodoc', 34 | 'sphinx.ext.intersphinx', 35 | 'sphinx.ext.todo', 36 | 'sphinx.ext.coverage', 37 | 'sphinx.ext.viewcode'] 38 | 39 | autodoc_member_order = 'bysource' 40 | autodoc_default_flags = ['show-inheritance', 'private-members'] 41 | 42 | # Add any paths that contain templates here, relative to this directory. 43 | templates_path = ['_templates'] 44 | 45 | # The suffix(es) of source filenames. 46 | # You can specify multiple suffix as a list of string: 47 | # 48 | # source_suffix = ['.rst', '.md'] 49 | source_suffix = '.rst' 50 | 51 | # The master toctree document. 52 | master_doc = 'index' 53 | 54 | # General information about the project. 55 | project = u'certbot-dns-standalone' 56 | copyright = u'2018, Certbot Project' 57 | author = u'Certbot Project' 58 | 59 | # The version info for the project you're documenting, acts as replacement for 60 | # |version| and |release|, also used in various other places throughout the 61 | # built documents. 62 | # 63 | # The short X.Y version. 64 | version = u'0' 65 | # The full version, including alpha/beta/rc tags. 66 | release = u'0' 67 | 68 | # The language for content autogenerated by Sphinx. Refer to documentation 69 | # for a list of supported languages. 70 | # 71 | # This is also used if you do content translation via gettext catalogs. 72 | # Usually you set "language" from the command line for these cases. 73 | language = 'en' 74 | 75 | # List of patterns, relative to source directory, that match files and 76 | # directories to ignore when looking for source files. 77 | # This patterns also effect to html_static_path and html_extra_path 78 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] 79 | 80 | default_role = 'py:obj' 81 | 82 | # The name of the Pygments (syntax highlighting) style to use. 83 | pygments_style = 'sphinx' 84 | 85 | # If true, `todo` and `todoList` produce output, else they produce nothing. 86 | todo_include_todos = True 87 | 88 | 89 | # -- Options for HTML output ---------------------------------------------- 90 | 91 | # The theme to use for HTML and HTML Help pages. See the documentation for 92 | # a list of builtin themes. 93 | # 94 | 95 | # http://docs.readthedocs.org/en/latest/theme.html#how-do-i-use-this-locally-and-on-read-the-docs 96 | # on_rtd is whether we are on readthedocs.org 97 | on_rtd = os.environ.get('READTHEDOCS', None) == 'True' 98 | if not on_rtd: # only import and set the theme if we're building docs locally 99 | import sphinx_rtd_theme 100 | html_theme = 'sphinx_rtd_theme' 101 | html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] 102 | # otherwise, readthedocs.org uses their theme by default, so no need to specify it 103 | 104 | # Theme options are theme-specific and customize the look and feel of a theme 105 | # further. For a list of options available for each theme, see the 106 | # documentation. 107 | # 108 | # html_theme_options = {} 109 | 110 | # Add any paths that contain custom static files (such as style sheets) here, 111 | # relative to this directory. They are copied after the builtin static files, 112 | # so a file named "default.css" will overwrite the builtin "default.css". 113 | html_static_path = ['_static'] 114 | 115 | 116 | # -- Options for HTMLHelp output ------------------------------------------ 117 | 118 | # Output file base name for HTML help builder. 119 | htmlhelp_basename = 'certbot-dns-standalonedoc' 120 | 121 | 122 | # -- Options for LaTeX output --------------------------------------------- 123 | 124 | latex_elements = { 125 | # The paper size ('letterpaper' or 'a4paper'). 126 | # 127 | # 'papersize': 'letterpaper', 128 | 129 | # The font size ('10pt', '11pt' or '12pt'). 130 | # 131 | # 'pointsize': '10pt', 132 | 133 | # Additional stuff for the LaTeX preamble. 134 | # 135 | # 'preamble': '', 136 | 137 | # Latex figure (float) alignment 138 | # 139 | # 'figure_align': 'htbp', 140 | } 141 | 142 | # Grouping the document tree into LaTeX files. List of tuples 143 | # (source start file, target name, title, 144 | # author, documentclass [howto, manual, or own class]). 145 | latex_documents = [ 146 | (master_doc, 'certbot-dns-standalone.tex', u'certbot-dns-standalone Documentation', 147 | u'Certbot Project', 'manual'), 148 | ] 149 | 150 | 151 | # -- Options for manual page output --------------------------------------- 152 | 153 | # One entry per manual page. List of tuples 154 | # (source start file, name, description, authors, manual section). 155 | man_pages = [ 156 | (master_doc, 'certbot-dns-standalone', u'certbot-dns-standalone Documentation', 157 | [author], 1) 158 | ] 159 | 160 | 161 | # -- Options for Texinfo output ------------------------------------------- 162 | 163 | # Grouping the document tree into Texinfo files. List of tuples 164 | # (source start file, target name, title, author, 165 | # dir menu entry, description, category) 166 | texinfo_documents = [ 167 | (master_doc, 'certbot-dns-standalone', u'certbot-dns-standalone Documentation', 168 | author, 'certbot-dns-standalone', 'One line description of project.', 169 | 'Miscellaneous'), 170 | ] 171 | 172 | 173 | 174 | 175 | # Example configuration for intersphinx: refer to the Python standard library. 176 | intersphinx_mapping = { 177 | 'python': ('https://docs.python.org/', None), 178 | 'acme': ('https://acme-python.readthedocs.org/en/latest/', None), 179 | 'certbot': ('https://certbot.eff.org/docs/', None), 180 | } 181 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. certbot-dns-standalone documentation master file, created by 2 | sphinx-quickstart on Tue May 9 10:20:04 2017. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to certbot-dns-standalone's documentation! 7 | ================================================== 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | .. automodule:: certbot_dns_standalone 14 | :members: 15 | 16 | .. toctree:: 17 | :maxdepth: 1 18 | 19 | api 20 | 21 | 22 | Indices and tables 23 | ================== 24 | 25 | * :ref:`genindex` 26 | * :ref:`modindex` 27 | * :ref:`search` 28 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | set SPHINXPROJ=certbot-dns-standalone 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 20 | echo.installed, then set the SPHINXBUILD environment variable to point 21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 22 | echo.may add the Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /local-oldest-requirements.txt: -------------------------------------------------------------------------------- 1 | acme[dev]==0.21.1 2 | certbot[dev]==0.21.1 3 | -------------------------------------------------------------------------------- /readthedocs.org.requirements.txt: -------------------------------------------------------------------------------- 1 | # readthedocs.org gives no way to change the install command to "pip 2 | # install -e .[docs]" (that would in turn install documentation 3 | # dependencies), but it allows to specify a requirements.txt file at 4 | # https://readthedocs.org/dashboard/letsencrypt/advanced/ (c.f. #259) 5 | 6 | # Although ReadTheDocs certainly doesn't need to install the project 7 | # in --editable mode (-e), just "pip install .[docs]" does not work as 8 | # expected and "pip install -e .[docs]" must be used instead 9 | 10 | -e acme 11 | -e . 12 | -e certbot-dns-standalone[docs] 13 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal = 1 3 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | from setuptools import find_packages 3 | 4 | with open('README.rst') as file: 5 | long_description = file.read() 6 | 7 | version = '1.2.1' 8 | 9 | # Remember to update local-oldest-requirements.txt when changing the minimum 10 | # acme/certbot version. 11 | install_requires = [ 12 | 'acme>=0.21.1', 13 | 'certbot>=3.0.0', 14 | 'dnslib>=0.9.0', 15 | 'mock', 16 | 'setuptools', 17 | ] 18 | 19 | docs_extras = [ 20 | 'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags 21 | 'sphinx_rtd_theme', 22 | ] 23 | 24 | setup( 25 | name='certbot-dns-standalone', 26 | version=version, 27 | description="Standalone DNS Authenticator plugin for Certbot", 28 | url='https://github.com/siilike/certbot-dns-standalone', 29 | author="Lauri Keel", 30 | license='Apache License 2.0', 31 | python_requires='>=3.9', 32 | classifiers=[ 33 | 'Development Status :: 5 - Production/Stable', 34 | 'Environment :: Plugins', 35 | 'Intended Audience :: System Administrators', 36 | 'License :: OSI Approved :: Apache Software License', 37 | 'Operating System :: POSIX :: Linux', 38 | 'Programming Language :: Python', 39 | 'Programming Language :: Python :: 3', 40 | 'Programming Language :: Python :: 3.9', 41 | 'Programming Language :: Python :: 3.10', 42 | 'Programming Language :: Python :: 3.11', 43 | 'Programming Language :: Python :: 3.12', 44 | 'Topic :: Internet :: WWW/HTTP', 45 | 'Topic :: Security', 46 | 'Topic :: System :: Installation/Setup', 47 | 'Topic :: System :: Networking', 48 | 'Topic :: System :: Systems Administration', 49 | 'Topic :: Utilities', 50 | ], 51 | long_description=long_description, 52 | long_description_content_type='text/x-rst', 53 | packages=find_packages(), 54 | include_package_data=True, 55 | install_requires=install_requires, 56 | extras_require={ 57 | 'docs': docs_extras, 58 | }, 59 | entry_points={ 60 | 'certbot.plugins': [ 61 | 'dns-standalone = certbot_dns_standalone.dns_standalone:Authenticator', 62 | ], 63 | }, 64 | test_suite='certbot_dns_standalone', 65 | ) 66 | -------------------------------------------------------------------------------- /snap-constraints.txt: -------------------------------------------------------------------------------- 1 | # This file was generated by tools/pinning/current/repin.sh and can be updated using 2 | # that script. 3 | # 4 | # It is normally used as constraints to pip, however, it has the name 5 | # requirements.txt so that is scanned by GitHub. See 6 | # https://docs.github.com/en/github/visualizing-repository-data-with-graphs/about-the-dependency-graph#supported-package-ecosystems 7 | # for more info. 8 | alabaster==0.7.13 ; python_version >= "3.7" and python_version < "4.0" 9 | apacheconfig==0.3.2 ; python_version >= "3.7" and python_version < "4.0" 10 | appnope==0.1.3 ; python_version >= "3.7" and python_version < "4.0" and sys_platform == "darwin" 11 | astroid==2.13.5 ; python_full_version >= "3.7.2" and python_version < "4.0" 12 | attrs==23.1.0 ; python_version >= "3.7" and python_version < "4.0" 13 | azure-core==1.27.1 ; python_version >= "3.7" and python_version < "4.0" 14 | azure-devops==7.1.0b3 ; python_version >= "3.7" and python_version < "4.0" 15 | babel==2.12.1 ; python_version >= "3.7" and python_version < "4.0" 16 | backcall==0.2.0 ; python_version >= "3.7" and python_version < "4.0" 17 | backports-cached-property==1.0.2 ; python_version >= "3.7" and python_version < "3.8" 18 | bcrypt==4.0.1 ; python_version >= "3.7" and python_version < "4.0" 19 | beautifulsoup4==4.12.2 ; python_version >= "3.7" and python_version < "4.0" 20 | bleach==6.0.0 ; python_version >= "3.7" and python_version < "4.0" 21 | boto3==1.26.162 ; python_version >= "3.7" and python_version < "4.0" 22 | botocore==1.29.162 ; python_version >= "3.7" and python_version < "4.0" 23 | cachecontrol==0.12.14 ; python_version >= "3.7" and python_version < "4.0" 24 | cachetools==5.3.1 ; python_version >= "3.7" and python_version < "4.0" 25 | cachy==0.3.0 ; python_version >= "3.7" and python_version < "4.0" 26 | certifi==2023.5.7 ; python_version >= "3.7" and python_version < "4.0" 27 | cffi==1.15.1 ; python_version >= "3.7" and python_version < "4.0" 28 | charset-normalizer==3.1.0 ; python_version >= "3.7" and python_version < "4.0" 29 | cleo==1.0.0a5 ; python_version >= "3.7" and python_version < "4.0" 30 | cloudflare==2.11.6 ; python_version >= "3.7" and python_version < "4.0" 31 | colorama==0.4.6 ; python_version < "4.0" and sys_platform == "win32" and python_version >= "3.7" or python_version >= "3.7" and python_version < "4.0" and platform_system == "Windows" 32 | configargparse==1.5.5 ; python_version >= "3.7" and python_version < "4.0" 33 | configobj==5.0.8 ; python_version >= "3.7" and python_version < "4.0" 34 | coverage==7.2.7 ; python_version >= "3.7" and python_version < "4.0" 35 | crashtest==0.3.1 ; python_version >= "3.7" and python_version < "4.0" 36 | cryptography==41.0.1 ; python_version >= "3.7" and python_version < "4.0" 37 | cython==0.29.35 ; python_version >= "3.7" and python_version < "4.0" 38 | decorator==5.1.1 ; python_version >= "3.7" and python_version < "4.0" 39 | dill==0.3.6 ; python_full_version >= "3.7.2" and python_version < "4.0" 40 | distlib==0.3.6 ; python_version >= "3.7" and python_version < "4.0" 41 | distro==1.8.0 ; python_version >= "3.7" and python_version < "4.0" 42 | dns-lexicon==3.12.0 ; python_version >= "3.7" and python_version < "4.0" 43 | dnspython==2.3.0 ; python_version >= "3.7" and python_version < "4.0" 44 | docutils==0.18.1 ; python_version >= "3.7" and python_version < "4.0" 45 | dulwich==0.20.50 ; python_version >= "3.7" and python_version < "4.0" 46 | exceptiongroup==1.1.1 ; python_version >= "3.7" and python_version < "3.11" 47 | execnet==1.9.0 ; python_version >= "3.7" and python_version < "4.0" 48 | fabric==3.1.0 ; python_version >= "3.7" and python_version < "4.0" 49 | filelock==3.12.2 ; python_version >= "3.7" and python_version < "4.0" 50 | google-api-core==2.11.1 ; python_version >= "3.7" and python_version < "4.0" 51 | google-api-python-client==2.90.0 ; python_version >= "3.7" and python_version < "4.0" 52 | google-auth-httplib2==0.1.0 ; python_version >= "3.7" and python_version < "4.0" 53 | google-auth==2.21.0 ; python_version >= "3.7" and python_version < "4.0" 54 | googleapis-common-protos==1.59.1 ; python_version >= "3.7" and python_version < "4.0" 55 | html5lib==1.1 ; python_version >= "3.7" and python_version < "4.0" 56 | httplib2==0.22.0 ; python_version >= "3.7" and python_version < "4.0" 57 | idna==3.4 ; python_version >= "3.7" and python_version < "4.0" 58 | imagesize==1.4.1 ; python_version >= "3.7" and python_version < "4.0" 59 | importlib-metadata==4.13.0 ; python_version >= "3.7" and python_version < "4.0" 60 | importlib-resources==5.12.0 ; python_version >= "3.7" and python_version < "3.9" 61 | iniconfig==2.0.0 ; python_version >= "3.7" and python_version < "4.0" 62 | invoke==2.1.3 ; python_version >= "3.7" and python_version < "4.0" 63 | ipdb==0.13.13 ; python_version >= "3.7" and python_version < "4.0" 64 | ipython==7.34.0 ; python_version >= "3.7" and python_version < "4.0" 65 | isodate==0.6.1 ; python_version >= "3.7" and python_version < "4.0" 66 | isort==5.11.5 ; python_full_version >= "3.7.2" and python_version < "4.0" 67 | jaraco-classes==3.2.3 ; python_version >= "3.7" and python_version < "4.0" 68 | jedi==0.18.2 ; python_version >= "3.7" and python_version < "4.0" 69 | jeepney==0.8.0 ; python_version >= "3.7" and python_version < "4.0" and sys_platform == "linux" 70 | jinja2==3.1.2 ; python_version >= "3.7" and python_version < "4.0" 71 | jmespath==1.0.1 ; python_version >= "3.7" and python_version < "4.0" 72 | josepy==1.13.0 ; python_version >= "3.7" and python_version < "4.0" 73 | jsonlines==3.1.0 ; python_version >= "3.7" and python_version < "4.0" 74 | jsonpickle==3.0.1 ; python_version >= "3.7" and python_version < "4.0" 75 | jsonschema==4.17.3 ; python_version >= "3.7" and python_version < "4.0" 76 | keyring==24.1.1 ; python_version >= "3.7" and python_version < "4.0" 77 | lazy-object-proxy==1.9.0 ; python_full_version >= "3.7.2" and python_version < "4.0" 78 | lockfile==0.12.2 ; python_version >= "3.7" and python_version < "4.0" 79 | markdown-it-py==2.2.0 ; python_version >= "3.7" and python_version < "4.0" 80 | markupsafe==2.1.3 ; python_version >= "3.7" and python_version < "4.0" 81 | matplotlib-inline==0.1.6 ; python_version >= "3.7" and python_version < "4.0" 82 | mccabe==0.7.0 ; python_full_version >= "3.7.2" and python_version < "4.0" 83 | mdurl==0.1.2 ; python_version >= "3.7" and python_version < "4.0" 84 | more-itertools==9.1.0 ; python_version >= "3.7" and python_version < "4.0" 85 | msgpack==1.0.5 ; python_version >= "3.7" and python_version < "4.0" 86 | msrest==0.7.1 ; python_version >= "3.7" and python_version < "4.0" 87 | mypy-extensions==1.0.0 ; python_version >= "3.7" and python_version < "4.0" 88 | mypy==1.4.1 ; python_version >= "3.7" and python_version < "4.0" 89 | oauthlib==3.2.2 ; python_version >= "3.7" and python_version < "4.0" 90 | packaging==23.1 ; python_version >= "3.7" and python_version < "4.0" 91 | paramiko==3.2.0 ; python_version >= "3.7" and python_version < "4.0" 92 | parsedatetime==2.6 ; python_version >= "3.7" and python_version < "4.0" 93 | parso==0.8.3 ; python_version >= "3.7" and python_version < "4.0" 94 | pexpect==4.8.0 ; python_version >= "3.7" and python_version < "4.0" 95 | pickleshare==0.7.5 ; python_version >= "3.7" and python_version < "4.0" 96 | pip==23.1.2 ; python_version >= "3.7" and python_version < "4.0" 97 | pkginfo==1.9.6 ; python_version >= "3.7" and python_version < "4.0" 98 | pkgutil-resolve-name==1.3.10 ; python_version >= "3.7" and python_version < "3.9" 99 | platformdirs==2.6.2 ; python_version < "4.0" and python_version >= "3.7" 100 | pluggy==1.2.0 ; python_version >= "3.7" and python_version < "4.0" 101 | ply==3.11 ; python_version >= "3.7" and python_version < "4.0" 102 | poetry-core==1.3.2 ; python_version >= "3.7" and python_version < "4.0" 103 | poetry-plugin-export==1.2.0 ; python_version >= "3.7" and python_version < "4.0" 104 | poetry==1.2.2 ; python_version >= "3.7" and python_version < "4.0" 105 | prompt-toolkit==3.0.38 ; python_version >= "3.7" and python_version < "4.0" 106 | protobuf==4.23.3 ; python_version >= "3.7" and python_version < "4.0" 107 | ptyprocess==0.7.0 ; python_version >= "3.7" and python_version < "4.0" 108 | py==1.11.0 ; python_version >= "3.7" and python_version < "4.0" 109 | pyasn1-modules==0.3.0 ; python_version >= "3.7" and python_version < "4.0" 110 | pyasn1==0.5.0 ; python_version >= "3.7" and python_version < "4.0" 111 | pycparser==2.21 ; python_version >= "3.7" and python_version < "4.0" 112 | pygments==2.15.1 ; python_version >= "3.7" and python_version < "4.0" 113 | pylev==1.4.0 ; python_version >= "3.7" and python_version < "4.0" 114 | pylint==2.15.5 ; python_full_version >= "3.7.2" and python_version < "4.0" 115 | pynacl==1.5.0 ; python_version >= "3.7" and python_version < "4.0" 116 | pynsist==2.7 ; python_version >= "3.7" and python_version < "4.0" 117 | pyopenssl==23.2.0 ; python_version >= "3.7" and python_version < "4.0" 118 | pyparsing==3.1.0 ; python_version >= "3.7" and python_version < "4.0" 119 | pyrfc3339==1.1 ; python_version >= "3.7" and python_version < "4.0" 120 | pyrsistent==0.19.3 ; python_version >= "3.7" and python_version < "4.0" 121 | pytest-cov==4.1.0 ; python_version >= "3.7" and python_version < "4.0" 122 | pytest-xdist==3.3.1 ; python_version >= "3.7" and python_version < "4.0" 123 | pytest==7.4.0 ; python_version >= "3.7" and python_version < "4.0" 124 | python-augeas==1.1.0 ; python_version >= "3.7" and python_version < "4.0" 125 | python-dateutil==2.8.2 ; python_version >= "3.7" and python_version < "4.0" 126 | python-digitalocean==1.17.0 ; python_version >= "3.7" and python_version < "4.0" 127 | pytz==2023.3 ; python_version >= "3.7" and python_version < "4.0" 128 | pywin32-ctypes==0.2.2 ; python_version >= "3.7" and python_version < "4.0" and sys_platform == "win32" 129 | pywin32==306 ; python_version >= "3.7" and python_version < "4.0" and sys_platform == "win32" 130 | pyyaml==6.0 ; python_version >= "3.7" and python_version < "4.0" 131 | readme-renderer==37.3 ; python_version >= "3.7" and python_version < "4.0" 132 | requests-download==0.1.2 ; python_version >= "3.7" and python_version < "4.0" 133 | requests-file==1.5.1 ; python_version >= "3.7" and python_version < "4.0" 134 | requests-oauthlib==1.3.1 ; python_version >= "3.7" and python_version < "4.0" 135 | requests-toolbelt==0.9.1 ; python_version >= "3.7" and python_version < "4.0" 136 | requests==2.31.0 ; python_version >= "3.7" and python_version < "4.0" 137 | rfc3986==2.0.0 ; python_version >= "3.7" and python_version < "4.0" 138 | rich==13.4.2 ; python_version >= "3.7" and python_version < "4.0" 139 | rsa==4.9 ; python_version >= "3.7" and python_version < "4" 140 | s3transfer==0.6.1 ; python_version >= "3.7" and python_version < "4.0" 141 | secretstorage==3.3.3 ; python_version >= "3.7" and python_version < "4.0" and sys_platform == "linux" 142 | semantic-version==2.10.0 ; python_version >= "3.7" and python_version < "4.0" 143 | setuptools-rust==1.6.0 ; python_version >= "3.7" and python_version < "4.0" 144 | setuptools==67.4.0 ; python_version >= "3.7" and python_version < "4.0" 145 | shellingham==1.5.0.post1 ; python_version >= "3.7" and python_version < "4.0" 146 | six==1.16.0 ; python_version >= "3.7" and python_version < "4.0" 147 | snowballstemmer==2.2.0 ; python_version >= "3.7" and python_version < "4.0" 148 | soupsieve==2.4.1 ; python_version >= "3.7" and python_version < "4.0" 149 | sphinx-rtd-theme==1.2.2 ; python_version >= "3.7" and python_version < "4.0" 150 | sphinx==5.3.0 ; python_version >= "3.7" and python_version < "4.0" 151 | sphinxcontrib-applehelp==1.0.2 ; python_version >= "3.7" and python_version < "4.0" 152 | sphinxcontrib-devhelp==1.0.2 ; python_version >= "3.7" and python_version < "4.0" 153 | sphinxcontrib-htmlhelp==2.0.0 ; python_version >= "3.7" and python_version < "4.0" 154 | sphinxcontrib-jquery==4.1 ; python_version >= "3.7" and python_version < "4.0" 155 | sphinxcontrib-jsmath==1.0.1 ; python_version >= "3.7" and python_version < "4.0" 156 | sphinxcontrib-qthelp==1.0.3 ; python_version >= "3.7" and python_version < "4.0" 157 | sphinxcontrib-serializinghtml==1.1.5 ; python_version >= "3.7" and python_version < "4.0" 158 | tldextract==3.4.4 ; python_version >= "3.7" and python_version < "4.0" 159 | tomli==2.0.1 ; python_version >= "3.7" and python_full_version <= "3.11.0a6" 160 | tomlkit==0.11.8 ; python_version < "4.0" and python_version >= "3.7" 161 | tox==3.28.0 ; python_version >= "3.7" and python_version < "4.0" 162 | traitlets==5.9.0 ; python_version >= "3.7" and python_version < "4.0" 163 | twine==4.0.2 ; python_version >= "3.7" and python_version < "4.0" 164 | typed-ast==1.5.4 ; python_version < "3.8" and python_version >= "3.7" 165 | types-httplib2==0.22.0.1 ; python_version >= "3.7" and python_version < "4.0" 166 | types-pyopenssl==23.2.0.1 ; python_version >= "3.7" and python_version < "4.0" 167 | types-pyrfc3339==1.1.1.4 ; python_version >= "3.7" and python_version < "4.0" 168 | types-python-dateutil==2.8.19.13 ; python_version >= "3.7" and python_version < "4.0" 169 | types-pytz==2023.3.0.0 ; python_version >= "3.7" and python_version < "4.0" 170 | types-pywin32==306.0.0.2 ; python_version >= "3.7" and python_version < "4.0" 171 | types-requests==2.31.0.1 ; python_version >= "3.7" and python_version < "4.0" 172 | types-setuptools==68.0.0.0 ; python_version >= "3.7" and python_version < "4.0" 173 | types-six==1.16.21.8 ; python_version >= "3.7" and python_version < "4.0" 174 | types-urllib3==1.26.25.13 ; python_version >= "3.7" and python_version < "4.0" 175 | typing-extensions==4.6.3 ; python_version >= "3.7" and python_version < "4.0" 176 | uritemplate==4.1.1 ; python_version >= "3.7" and python_version < "4.0" 177 | urllib3==1.26.16 ; python_version >= "3.7" and python_version < "4.0" 178 | virtualenv==20.21.1 ; python_version >= "3.7" and python_version < "4.0" 179 | wcwidth==0.2.6 ; python_version >= "3.7" and python_version < "4.0" 180 | webencodings==0.5.1 ; python_version >= "3.7" and python_version < "4.0" 181 | wheel==0.40.0 ; python_version >= "3.7" and python_version < "4.0" 182 | wrapt==1.15.0 ; python_full_version >= "3.7.2" and python_version < "4.0" 183 | xattr==0.9.9 ; python_version >= "3.7" and python_version < "4.0" and sys_platform == "darwin" 184 | yarg==0.1.9 ; python_version >= "3.7" and python_version < "4.0" 185 | zipp==3.15.0 ; python_version >= "3.7" and python_version < "4.0" 186 | -------------------------------------------------------------------------------- /snap/snapcraft.yaml: -------------------------------------------------------------------------------- 1 | # This file is generated automatically and should not be edited manually. 2 | name: certbot-dns-standalone 3 | summary: Standalone DNS Authenticator plugin for Certbot 4 | description: Standalone DNS Authenticator plugin for Certbot 5 | confinement: strict 6 | grade: stable 7 | base: core24 8 | adopt-info: certbot-dns-standalone 9 | 10 | environment: 11 | AUGEAS_LENS_LIB: "$SNAP/usr/share/augeas/lenses/dist" 12 | CERTBOT_SNAPPED: "True" 13 | # This is needed to help openssl find its legacy provider on architectures 14 | # where we cannot use cryptography's pre-built wheels. See 15 | # https://github.com/certbot/certbot/issues/10055. 16 | OPENSSL_MODULES: "$SNAP/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/ossl-modules" 17 | PATH: "$SNAP/bin:$SNAP/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games" 18 | PYTHONPATH: "$SNAP/lib/python3.12/site-packages:${PYTHONPATH}" 19 | 20 | parts: 21 | certbot-dns-standalone: 22 | plugin: python 23 | source: . 24 | override-pull: | 25 | snapcraftctl pull 26 | snapcraftctl set-version `grep ^version $SNAPCRAFT_PART_SRC/setup.py | cut -f2 -d= | tr -d "'[:space:]"` 27 | build-environment: 28 | # We set this environment variable while building to try and increase the 29 | # stability of fetching the rust crates needed to build the cryptography 30 | # library. 31 | - CARGO_NET_GIT_FETCH_WITH_CLI: "true" 32 | # Constraints are passed through the environment variable PIP_CONSTRAINTS instead of using the 33 | # parts.[part_name].constraints option available in snapcraft.yaml when the Python plugin is 34 | # used. This is done to let these constraints be applied not only on the certbot package 35 | # build, but also on any isolated build that pip could trigger when building wheels for 36 | # dependencies. See https://github.com/certbot/certbot/pull/8443 for more info. 37 | - PIP_CONSTRAINT: $SNAPCRAFT_PART_SRC/snap-constraints.txt 38 | - SNAP_BUILD: "True" 39 | # To build cryptography and cffi if needed 40 | build-packages: 41 | - gcc 42 | - git 43 | - build-essential 44 | - libssl-dev 45 | - libffi-dev 46 | - python3-dev 47 | - cargo 48 | - pkg-config 49 | certbot-metadata: 50 | plugin: dump 51 | source: . 52 | stage: [setup.py, certbot-shared] 53 | override-pull: | 54 | snapcraftctl pull 55 | mkdir -p $SNAPCRAFT_PART_SRC/certbot-shared 56 | 57 | slots: 58 | certbot: 59 | interface: content 60 | content: certbot-1 61 | read: 62 | - $SNAP/lib/python3.12/site-packages 63 | 64 | plugs: 65 | certbot-metadata: 66 | interface: content 67 | content: metadata-1 68 | target: $SNAP/certbot-shared 69 | --------------------------------------------------------------------------------