{"id":29826660,"url":"https://github.com/infinityofspace/certbot_dns_duckdns","last_synced_at":"2026-03-17T08:37:19.847Z","repository":{"id":36962262,"uuid":"335080352","full_name":"infinityofspace/certbot_dns_duckdns","owner":"infinityofspace","description":"Plugin for certbot for a DNS-01 challenge with a DuckDNS domain.","archived":false,"fork":false,"pushed_at":"2026-02-01T19:42:36.000Z","size":270,"stargazers_count":112,"open_issues_count":1,"forks_count":20,"subscribers_count":4,"default_branch":"main","last_synced_at":"2026-02-02T03:39:20.247Z","etag":null,"topics":["certbot-dns-plugin","dns-01-challange","duckdns"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/infinityofspace.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":"License","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-02-01T20:49:41.000Z","updated_at":"2026-02-01T19:05:35.000Z","dependencies_parsed_at":"2026-02-01T21:02:33.711Z","dependency_job_id":null,"html_url":"https://github.com/infinityofspace/certbot_dns_duckdns","commit_stats":{"total_commits":135,"total_committers":8,"mean_commits":16.875,"dds":"0.31851851851851853","last_synced_commit":"dbc5383147cf9d35fa15797a2dd7bab3dd4c6bee"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/infinityofspace/certbot_dns_duckdns","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infinityofspace%2Fcertbot_dns_duckdns","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infinityofspace%2Fcertbot_dns_duckdns/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infinityofspace%2Fcertbot_dns_duckdns/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infinityofspace%2Fcertbot_dns_duckdns/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/infinityofspace","download_url":"https://codeload.github.com/infinityofspace/certbot_dns_duckdns/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/infinityofspace%2Fcertbot_dns_duckdns/sbom","scorecard":{"id":488000,"data":{"date":"2025-08-11","repo":{"name":"github.com/infinityofspace/certbot_dns_duckdns","commit":"a4e6d6ebb3847898a8747eb7abcae00afd4bb577"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.3,"checks":[{"name":"Maintained","score":1,"reason":"2 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":3,"reason":"Found 3/10 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/docker-publish-dev.yml:1","Warn: no topLevel permission defined: .github/workflows/docker-publish-release.yml:1","Warn: no topLevel permission defined: .github/workflows/docker-publish-unstable.yml:1","Warn: no topLevel permission defined: .github/workflows/formatting_check.yml:1","Warn: no topLevel permission defined: .github/workflows/linting.yml:1","Warn: no topLevel permission defined: .github/workflows/pypi-build-test.yml:1","Warn: no topLevel permission defined: .github/workflows/pypi-publish-release.yml:1","Warn: no topLevel permission defined: .github/workflows/snap_install_test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: License:0","Info: FSF or OSI recognized license: MIT License: License:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/docker-publish-dev.yml:10"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docker-publish-dev.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-dev.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-publish-dev.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-dev.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-publish-dev.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-dev.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-publish-dev.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-dev.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-publish-dev.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-dev.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-publish-dev.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-dev.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docker-publish-dev.yml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-dev.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docker-publish-release.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-publish-release.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-publish-release.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-publish-release.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-publish-release.yml:42: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-publish-release.yml:50: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docker-publish-release.yml:66: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docker-publish-unstable.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-unstable.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-publish-unstable.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-unstable.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-publish-unstable.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-unstable.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-publish-unstable.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-unstable.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-publish-unstable.yml:33: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-unstable.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docker-publish-unstable.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-unstable.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docker-publish-unstable.yml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/docker-publish-unstable.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/formatting_check.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/formatting_check.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/formatting_check.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/formatting_check.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/linting.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/linting.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/linting.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/linting.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi-build-test.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/pypi-build-test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi-build-test.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/pypi-build-test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi-build-test.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/pypi-build-test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi-build-test.yml:46: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/pypi-build-test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi-build-test.yml:67: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/pypi-build-test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi-publish-release.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/pypi-publish-release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi-publish-release.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/pypi-publish-release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi-publish-release.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/pypi-publish-release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi-publish-release.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/pypi-publish-release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pypi-publish-release.yml:53: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/pypi-publish-release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/snap_install_test.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/snap_install_test.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/snap_install_test.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/snap_install_test.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/snap_install_test.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/infinityofspace/certbot_dns_duckdns/snap_install_test.yml/main?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1","Warn: containerImage not pinned by hash: Dockerfile:16: pin your Docker image by updating python:3.13-alpine3.19 to python:3.13-alpine3.19@sha256:8287ca207e905649e9f399b5f91a119e5e9051d8cd110d5f8c3b4bd9458ebd1d","Warn: containerImage not pinned by hash: docker/cron/Dockerfile:1: pin your Docker image by updating alpine:latest to alpine:latest@sha256:4bcff63911fcb4448bd4fdacec207030997caf25e9bea4045fa6c8c44de311d1","Warn: pipCommand not pinned by hash: Dockerfile:11","Warn: pipCommand not pinned by hash: Dockerfile:14","Warn: pipCommand not pinned by hash: .github/workflows/formatting_check.yml:24","Warn: pipCommand not pinned by hash: .github/workflows/linting.yml:24","Warn: pipCommand not pinned by hash: .github/workflows/pypi-build-test.yml:27","Warn: pipCommand not pinned by hash: .github/workflows/pypi-build-test.yml:28","Warn: pipCommand not pinned by hash: .github/workflows/pypi-build-test.yml:32","Warn: pipCommand not pinned by hash: .github/workflows/pypi-build-test.yml:52","Warn: pipCommand not pinned by hash: .github/workflows/pypi-publish-release.yml:22","Info:   0 out of  21 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of  17 third-party GitHubAction dependencies pinned","Info:   0 out of   3 containerImage dependencies pinned","Info:   0 out of   9 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 24 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"11 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-3rq5-2g8h-59hc","Warn: Project is vulnerable to: PYSEC-2014-14 / GHSA-652x-xj99-gmcc","Warn: Project is vulnerable to: GHSA-9hjg-9r4m-mvj7","Warn: Project is vulnerable to: GHSA-9wx4-h78v-vm56","Warn: Project is vulnerable to: PYSEC-2014-13 / GHSA-cfj3-7x9c-4p3h","Warn: Project is vulnerable to: PYSEC-2018-28 / GHSA-x84v-xcm2-53pg","Warn: Project is vulnerable to: PYSEC-2015-17","Warn: Project is vulnerable to: PYSEC-2023-74","Warn: Project is vulnerable to: PYSEC-2025-49 / GHSA-5rjg-fvgr-3xxf","Warn: Project is vulnerable to: GHSA-cx63-2mw6-8hw5","Warn: Project is vulnerable to: PYSEC-2022-43012 / GHSA-r9hx-vwmv-q579"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T18:18:12.136Z","repository_id":36962262,"created_at":"2025-08-19T18:18:12.136Z","updated_at":"2025-08-19T18:18:12.136Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30619218,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-17T08:10:05.930Z","status":"ssl_error","status_checked_at":"2026-03-17T08:10:04.972Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["certbot-dns-plugin","dns-01-challange","duckdns"],"created_at":"2025-07-29T05:11:35.148Z","updated_at":"2026-03-17T08:37:19.830Z","avatar_url":"https://github.com/infinityofspace.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Certbot DNS DuckDNS Plugin\n\nPlugin for certbot for a DNS-01 challenge with a DuckDNS domain.\n\n---\n\n![PyPI - Python Version](https://img.shields.io/pypi/pyversions/certbot_dns_duckdns?style=for-the-badge) [![GitHub](https://img.shields.io/github/license/infinityofspace/certbot_dns_duckdns?style=for-the-badge)](https://github.com/infinityofspace/certbot_dns_duckdns/blob/master/License)\n\n[![PyPI](https://img.shields.io/pypi/v/certbot_dns_duckdns?style=for-the-badge)](https://pypi.org/project/certbot-dns-duckdns/) ![PyPI - Downloads](https://img.shields.io/pypi/dm/certbot_dns_duckdns?style=for-the-badge) [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/infinityofspace/certbot_dns_duckdns/pypi-build-test.yml?style=for-the-badge)](https://github.com/infinityofspace/certbot_dns_duckdns/actions/workflows/pypi-build-test.yml)\n\n[![Docker Image Version (latest semver)](https://img.shields.io/docker/v/infinityofspace/certbot_dns_duckdns?style=for-the-badge\u0026sort=semver\u0026label=Docker)](https://hub.docker.com/r/infinityofspace/certbot_dns_duckdns) ![Docker Image Size (latest semver)](https://img.shields.io/docker/image-size/infinityofspace/certbot_dns_duckdns?style=for-the-badge\u0026sort=semver) [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/infinityofspace/certbot_dns_duckdns/docker-publish-unstable.yml?style=for-the-badge)](https://github.com/infinityofspace/certbot_dns_duckdns/actions/workflows/docker-publish-unstable.yml)\n\n[![certbot-dns-duckdns](https://snapcraft.io/certbot-dns-duckdns/badge.svg)](https://snapcraft.io/certbot-dns-duckdns)\n\n---\n\n### Table of Contents\n\n1. [About](#about)\n2. [Installation](#installation)\n    1. [Prerequirements](#prerequirements)\n    2. [With pip (recommend)](#with-pip-recommend)\n    3. [From source](#from-source)\n    4. [Snap](#snap)\n3. [Usage](#usage)\n    1. [Credentials file or cli parameters](#credentials-file-or-cli-parameters)\n    2. [Local installation usage](#local-installation-usage)\n    3. [Docker usage](#docker-usage)\n    4. [Plugin arguments](#plugin-arguments)\n4. [FAQ](#faq)\n5. [Development](#development)\n    1. [Setup environment](#setup-environment)\n    2. [Tests](#tests)\n6. [Third party notices](#third-party-notices)\n7. [License](#license)\n\n---\n\n### About\n\n*certbot_dn_duckdns* is a plugin for [*certbot*](https://github.com/certbot/certbot) to create the DNS-01 challenge for\na DuckDNS domain. The plugin takes care of setting and deleting the TXT entry via the DuckDNS API.\n\n### Installation\n\n#### Prerequirements\n\n*If you want to use the docker image, then you don't need any requirements other than a working docker installation and\ncan proceed directly to the [usage](#docker-usage)*\n\nIf you prefer the local installation, then you need at least version 3.7 of Python installed. If you want to install\nthis plugin with pip, then you also need pip3 installed.\n\nIf you already have *certbot* installed, make sure you have at least version `1.18.0` installed. When you installed\n*certbot* as snap then you have to use the [snap installation](#snap) of the plugin.\n\nYou can check what version of *certbot* is installed with this command:\n\n```commandline\ncertbot --version\n```\n\nIf you don't have certbot installed yet, then the PyPI version of certbot will be installed automatically during the\ninstallation.\n\n**Note: If you want to run certbot with root privileges, then you need to install the plugin with root privileges too.\nOtherwise, certbot cannot find the plugin.**\n\n#### With pip (recommend)\n\nUse the following command to install *certbot_dns_duckdns* with pip:\n\n```commandline\npip install certbot_dns_duckdns\n```\n\nYou can also very easily update to a newer version:\n\n```commandline\npip install certbot_dns_duckdns -U\n```\n\n#### From source\n\n```commandline\ngit clone https://github.com/infinityofspace/certbot_dns_duckdns\ncd certbot_dns_duckdns\npip install .\n```\n\n#### Snap\n\nIf you use the *certbot* as snap package then you have to install *certbot_dns_duckdns* as a snap too:\n\n```commandline\nsnap install certbot-dns-duckdns\n```\n\nNow connect the *certbot* snap installation with the plugin snap installation:\n\n```commandline\nsudo snap connect certbot:plugin certbot-dns-duckdns\n```\n\nThe following command should now list `dns-duckdns` as an installed plugin:\n\n```commandline\ncertbot plugins\n```\n\n### Usage\n\n_Note: You cannot create certificates for multiple DuckDNS domains with one certbot call. This is because DuckDNS only\nallows one TXT record. If certificates for several domains should be created at the same time, then the same number of\ndistinct DNS TXT records must be created. To solve the problem, you simply have to make a separate certbot call for each\ndomain._\n\n**Note that the certificate generation through Letsencrypt has rate limits. For testing, use the additional\nargument `--staging` to solve this problem.**\n\n#### DuckDNS Token\n\nYou can either use cli parameters to pass authentication information to certbot:\n\n```commandline\n...\n--dns-duckdns-token \u003cyour-duckdns-token\u003e\n```\n\nOr to prevent your credentials from showing up in your bash history, you can also create a\ncredentials-file `duckdns.ini` (the name does not matter) with the following content:\n\n```ini\ndns_duckdns_token=\u003cyour-duckdns-token\u003e\n```\n\nAnd then instead of using the `--dns-duckdns-key` parameter above you can use\n\n```commandline\n...\n--dns-duckdns-credentials \u003c/path/to/your/duckdns.ini\u003e\n```\n\nYou can also mix these usages, though the cli parameters always take precedence over the ini file.\n\nMoreover, if your do not specify the `--dns-duckdns-token` or `--dns-duckdns-credentials` parameter, then the plugin\nwill try to read the token from the environment variable `DUCKDNS_TOKEN`.\nThe priority of the token is as follows:\n\n- cli parameter\n- credentials file\n- environment variable\n\n#### Local installation usage\n\nTo check if the plugin is installed correctly and detected properly by certbot, you can use the following command:\n\n```commandline\ncertbot plugins\n```\n\nBelow are some examples of how to use the plugin:\n\n---\n\nGenerate a certificate for a DNS-01 challenge of the domain \"example.duckdns.org\":\n\n```commandline\ncertbot certonly \\\n  --non-interactive \\\n  --agree-tos \\\n  --email \u003cyour-email\u003e \\\n  --preferred-challenges dns \\\n  --authenticator dns-duckdns \\\n  --dns-duckdns-token \u003cyour-duckdns-token\u003e \\\n  --dns-duckdns-propagation-seconds 60 \\\n  -d \"example.duckdns.org\"\n```\n\n---\n\nGenerate a certificate for a DNS-01 challenge of the subdomain \"cloud.example.duckdns.org\":\n\n```commandline\ncertbot certonly \\\n  --non-interactive \\\n  --agree-tos \\\n  --email \u003cyour-email\u003e \\\n  --preferred-challenges dns \\\n  --authenticator dns-duckdns \\\n  --dns-duckdns-token \u003cyour-duckdns-token\u003e \\\n  --dns-duckdns-propagation-seconds 60 \\\n  -d \"cloud.example.duckdns.org\"\n```\n\n---\n\nGenerate a wildcard certificate for a DNS-01 challenge of all subdomains \"*.example.duckdns.org\":\n\n```commandline\ncertbot certonly \\\n  --non-interactive \\\n  --agree-tos \\\n  --email \u003cyour-email\u003e \\\n  --preferred-challenges dns \\\n  --authenticator dns-duckdns \\\n  --dns-duckdns-token \u003cyour-duckdns-token\u003e \\\n  --dns-duckdns-propagation-seconds 60 \\\n  -d \"*.example.duckdns.org\"\n```\n\n---\n\nGenerate a certificate for a DNS-01 challenge of the domain \"example.duckdns.org\" using a credentials file:\n\n```commandline\ncertbot certonly \\\n  --non-interactive \\\n  --agree-tos \\\n  --email \u003cyour-email\u003e \\\n  --preferred-challenges dns \\\n  --authenticator dns-duckdns \\\n  --dns-duckdns-credentials \u003c/path/to/your/duckdns.ini\u003e \\\n  --dns-duckdns-propagation-seconds 60 \\\n  -d \"example.duckdns.org\"\n```\n\n---\n\nGenerate a certificate for a DNS-01 challenge of the domain \"example.duckdns.org\" without an account (i.e. without an\nemail address):\n\n```commandline\ncertbot certonly \\\n  --non-interactive \\\n  --agree-tos \\\n  --register-unsafely-without-email \\\n  --preferred-challenges dns \\\n  --authenticator dns-duckdns \\\n  --dns-duckdns-token \u003cyour-duckdns-token\u003e \\\n  --dns-duckdns-propagation-seconds 60 \\\n  -d \"example.duckdns.org\"\n```\n\n---\n\nGenerate a staging certificate (i.e. temporary testing certificate) for a DNS-01 challenge of the domain \"\nexample.duckdns.org\":\n\n```commandline\ncertbot certonly \\\n  --non-interactive \\\n  --agree-tos \\\n  --email \u003cyour-email\u003e \\\n  --preferred-challenges dns \\\n  --authenticator dns-duckdns \\\n  --dns-duckdns-token \u003cyour-duckdns-token\u003e \\\n  --dns-duckdns-propagation-seconds 60 \\\n  -d \"example.duckdns.org\" \\\n  --staging\n```\n\n---\n\nDNS-01 Challenges allow using CNAME records or NS records to delegate the challenge response to other DNS zones.\nFor example, this allows you to resolve the DNS challenge for another provider's domain using a duckdns domain.\nFor example, we have `abc.duckdns.org` as duckdns domain and `example.com` as our other domain.\nWe might have an existing DNS configuration which look like this:\n\n```commandline\none.example.com. 600 IN CNAME two.example.com.\ntwo.example.com. 600 IN CNAME abc.duckdns.org.\n```\n\nIt chains `one.example.com` to `two.example.com` and finally to `abc.duckdns.org`.\n\nNow we want to issue a DNS-01 challenge for the subdomain \"test.example.com\".\nSo we create a CNAME record for \"_acme-challenge.test.example.com\" pointing to \"one.example.com\".\nThe DNS records now look like this:\n\n```commandline\n_acme-challenge.test.example.com. 600 IN CNAME one.example.com.\none.example.com. 600 IN CNAME two.example.com.\ntwo.example.com. 600 IN CNAME abc.duckdns.org.\n```\n\nNow we use certbot to generate a certificate for the domain `test.example.com` with the DNS challenge:\n\n```commandline\ncertbot certonly \\\n  --non-interactive \\\n  --agree-tos \\\n  --email \u003cyour-email\u003e \\\n  --preferred-challenges dns \\\n  --authenticator dns-duckdns \\\n  --dns-duckdns-token \u003cyour-duckdns-token\u003e \\\n  --dns-duckdns-propagation-seconds 60 \\\n  -d \"test.example.com\" \\\n```\n\nWhat happens in the background can be seen very well in the DNS records:\n\n```commandline\n_acme-challenge.test.example.com. 600 IN CNAME one.example.com.\none.example.com. 600 IN CNAME two.example.com.\ntwo.example.com. 600 IN CNAME abc.duckdns.org.\nabc.duckdns.org. 60 TXT \"asduh9asudhßa97sdhap9sudaisudoi\"\n```\n\nWhen validating the DNS challenge value, all CNAME records are now traversed.\nIt starts with `_acme-challenge.test.example.com` and goes to `one.example.com`, then to `two.example.com` and finally\nto `abc.duckdns.org`. Here is the validation token stored as TXT record.\n\nThe example could also be shortened by directly creating a CNAME entry from `_acme-challenge.test.example.com` to\n`abc.duckdns.org`. So we skip all other CNAME records in between. To make it clear that any CNAME records are traversed\nduring validation, the intermediate parts are added in the previous example.\n\n---\n\nTry to update all currently generated certificates:\n\n```commandline\ncertbot renew\n```\n\n---\n\nYou can find al list of all available certbot cli options in\nthe [official documentation](https://certbot.eff.org/docs/using.html#certbot-command-line-options) of *certbot*.\n\n#### Docker usage\n\nYou can simply start a new container and use the same certbot commands to obtain a new certificate:\n\n```commandline\ndocker run -v \"/etc/letsencrypt:/etc/letsencrypt\" -v \"/var/log/letsencrypt:/var/log/letsencrypt\" infinityofspace/certbot_dns_duckdns:latest \\\n   certonly \\\n     --non-interactive \\\n     --agree-tos \\\n     --email \u003cyour-email\u003e \\\n     --preferred-challenges dns \\\n     --authenticator dns-duckdns \\\n     --dns-duckdns-token \u003cyour-duckdns-token\u003e \\\n     --dns-duckdns-propagation-seconds 60 \\\n     -d \"example.duckdns.org\"\n```\n\nOr you can use a credentials file:\n\n```commandline\ndocker run -v \"/etc/letsencrypt:/etc/letsencrypt\" -v \"/var/log/letsencrypt:/var/log/letsencrypt\" -v \"/absolute/path/to/your/duckdns.ini:/conf/duckdns.ini\" infinityofspace/certbot_dns_duckdns:latest \\\n   certonly \\\n     --non-interactive \\\n     --agree-tos \\\n     --email \u003cyour-email\u003e \\\n     --preferred-challenges dns \\\n     --authenticator dns-duckdns \\\n     --dns-duckdns-credentials /conf/duckdns.ini \\\n     --dns-duckdns-propagation-seconds 60 \\\n     -d \"example.duckdns.org\"\n```\n\nIf you want to use the docker image to renew your certificates automatically, you can do this with the host cron, for\nexample. To use this example you must have crontab and cron installed beforehand. Note that depending on the\ninstallation you may need to use the crontab of a root user to access the docker daemon or file directories. For\nexample, use the following crontab expression:\n\n```\n0 3 */8 * * docker run --rm -v \"/etc/letsencrypt:/etc/letsencrypt\" -v \"/var/log/letsencrypt:/var/log/letsencrypt\" -v \"/absolute/path/to/your/duckdns.ini:/conf/duckdns.ini\" infinityofspace/certbot_dns_duckdns:latest  renew\n```\n\nThis will start a temporary docker container every 8 days at 3am and tries to renew expiring certificates.\n\nAn example for the usage with docker-compose can be found [here](docker/simple/Readme.md).\n\n##### Docker secrets\n\nThe docker image supports the use of docker secrets. Create a secret with the default name `DUCKDNS_TOKEN` or a custom\nname specified in the parameter `--dns-duckdns-token-env` and do not provide the `--dns-duckdns-token` or\n`--dns-duckdns-credentials` parameter. The image will automatically read the secret and use it.\n\n#### Plugin arguments\n\n```commandline\nObtain certificates using a DNS TXT record for DuckDNS domains\n\n  --dns-duckdns-propagation-seconds DNS_DUCKDNS_PROPAGATION_SECONDS\n                        The number of seconds to wait for DNS to propagate before asking the ACME server to verify the DNS record. (default: 30)\n  --dns-duckdns-credentials DNS_DUCKDNS_CREDENTIALS\n                        DuckDNS credentials INI file. (default: None)\n  --dns-duckdns-token DNS_DUCKDNS_TOKEN\n                        DuckDNS token (overwrites credentials file) (default: None)\n  --dns-duckdns-token-env DNS_DUCKDNS_TOKEN_ENV\n                        Environment variable name for the DuckDNS token (default: DUCKDNS_TOKEN)\n  --dns-duckdns-no-txt-restore\n                        Do not restore the original TXT record (default: False)\n```\n\n### FAQ\n\nYou can read the FAQ in the [wiki](https://github.com/infinityofspace/certbot_dns_duckdns/wiki/FAQ).\n\n### Development\n\n#### Setup environment\n\nFirst get the source code:\n\n```commandline\ngit clone https://github.com/infinityofspace/certbot_dns_duckdns.git\ncd certbot_dns_porkbun\n```\n\nNow create a virtual environment, activate it and install all dependencies with the following commands:\n\n```commandline\npython3 -m venv venv\nsource venv/bin/activate\npip3 install -r requirements-dev.txt\n```\n\nNow you can start developing.\n\nFeel free to contribute to this project by creating a pull request.\nBefore you create a pull request, make sure that you code meets the following requirements (you can use the specified\ncommands to check/fulfill the requirements):\n\n- check unit tests: `python -m unittest tests/*.py`\n- format the code: `ruff format`\n- lint the code:\n```commandline\nflake8 certbot_dns_duckdns --count --ignore E501 --show-source --statistics\npylint certbot_dns_duckdns --disable C0301\n```\n\n#### Tests\n\nYou can run the tests with the following command:\n\n```commandline\npython -m unittest tests/*.py\n```\n\n### Third party notices\n\nAll modules used by this project are listed below:\n\n|                        Name                        |                                      License                                       |\n|:--------------------------------------------------:|:----------------------------------------------------------------------------------:|\n|   [certbot](https://github.com/certbot/certbot)    | [Apache 2.0](https://raw.githubusercontent.com/certbot/certbot/master/LICENSE.txt) |\n|    [requests](https://github.com/psf/requests)     |    [Apache 2.0](https://raw.githubusercontent.com/psf/requests/master/LICENSE)     |\n|  [setuptools](https://github.com/pypa/setuptools)  |       [MIT](https://raw.githubusercontent.com/pypa/setuptools/main/LICENSE)        |\n| [dnspython](https://github.com/rthalley/dnspython) |     [ISC](https://raw.githubusercontent.com/rthalley/dnspython/master/LICENSE)     |\n\nFurthermore, this readme file contains embeddings of [Shields.io](https://github.com/badges/shields).\n\n### License\n\n[MIT](License) - Copyright (c) 2021-2024 Marvin Heptner\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfinityofspace%2Fcertbot_dns_duckdns","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finfinityofspace%2Fcertbot_dns_duckdns","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finfinityofspace%2Fcertbot_dns_duckdns/lists"}