Fail chalenge when change port: 80 to 8044, 443 to 8443

My domain is: vietnamthink.today

I ran this command: $ sudo certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py --preferred-challenges
dns --debug-challenges -d *.vietnamthink.today -d vietnamthink.today -v

It produced this output:

Requesting a certificate for *.vietnamthink.today and vietnamthink.today
Performing the following challenges:
dns-01 challenge for vietnamthink.today
Running manual-auth-hook command: /etc/letsencrypt/acme-dns-auth.py


Challenges loaded. Press continue to submit to CA. Pass "-v" for more info about
challenges.


Press Enter to Continue
Waiting for verification...
Challenge failed for domain vietnamthink.today
dns-01 challenge for vietnamthink.today
Certbot failed to authenticate some domains (authenticator: manual). The Certificate Authority reported these problems:
Domain: vietnamthink.today
Type: unauthorized
Detail: Incorrect TXT record "zX2iuDDspbr-gRwMJs6mI52OpTPGKfYERloxEyd62rs" found at _acme-challenge.vietnamthink.today
Hint: The Certificate Authority failed to verify the DNS TXT records created by the --manual-auth-hook. Ensure that this hook
is functioning correctly and that it waits a sufficient duration of time for DNS propagation. Refer to "certbot --help manual" and the Certbot User Guide.
Cleaning up challenges
Some challenges have failed.
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /var/log/letsencrypt/letsencrypt.log or re-run Certbot with -v for more details.
My web server is (include version): Nginx 1.18.0 (ubuntu 22.04)

The operating system my web server runs on is (include version):

My hosting provider, if applicable, is: my server at home with NAT

I can login to a root shell on my machine (yes or no, or I don't know): yes

I'm using a control panel to manage my site (no, or provide the name and version of the control panel): no

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot): 1.21.0
Thank you
I follow this tuto: How To Acquire a Let's Encrypt Certificate Using DNS Validation with acme-dns-certbot on Ubuntu 18.04 | DigitalOcean

A DNS-01 challenge request for two "names" will require two TXT record entries.
Using --manual will force certbot to prompt you for each action and guide you every step of the way.

Since you are having trouble, and will likely be testing things for a bit until you get it right, you should do your testing against the staging system [use: --staging].
Once all tests are passed, then you can switch to production [removing --staging from the working test].

I'd start by removing the existing TXT record.
Then slowly follow the prompts and verify all steps while using the staging environment until you are confident your testing is complete.

6 Likes

Thank for your support, but with --manual and --staging, it still not show TXT token

1 Like

How are you adding the TXT records?
And into which DNS system are you adding them?

4 Likes

I deleted TXT in FreeDNS.afraid.org DNS system. But it not show step by step for TXT token

How is /etc/letsencrypt/acme-dns-auth.py configured? It suggests that you're using acme-dns, but the fact you can actually delete a TXT record at Afraid is kinda weird if you'd use acme-dns.. Contradictory..

3 Likes

This is my acme-dns-auth.py

!/usr/bin/env python3
import json
import os
import requests
import sys
### EDIT THESE: Configuration values ###
# URL to acme-dns instance
ACMEDNS_URL = "https://auth.acme-dns.io"
# Path for acme-dns credential storage
STORAGE_PATH = "/etc/letsencrypt/acmedns.json"
# Whitelist for address ranges to allow the updates from
# Example: ALLOW_FROM = ["192.168.10.0/24", "::1/128"]
ALLOW_FROM = []
# Force re-registration. Overwrites the already existing acme-dns accounts.
FORCE_REGISTER = False
###   DO NOT EDIT BELOW THIS POINT   ###
###         HERE BE DRAGONS          ###
DOMAIN = os.environ["CERTBOT_DOMAIN"]
if DOMAIN.startswith("*."):
    DOMAIN = DOMAIN[2:]
VALIDATION_DOMAIN = "_acme-challenge."+DOMAIN
VALIDATION_TOKEN = os.environ["CERTBOT_VALIDATION"]
class AcmeDnsClient(object):
    """
    Handles the communication with ACME-DNS API
    """
    def __init__(self, acmedns_url):
        self.acmedns_url = acmedns_url
    def register_account(self, allowfrom):
        """Registers a new ACME-DNS account"""
        if allowfrom:
            # Include whitelisted networks to the registration call
            reg_data = {"allowfrom": allowfrom}
            res = requests.post(self.acmedns_url+"/register",
                                data=json.dumps(reg_data))
        else:
            res = requests.post(self.acmedns_url+"/register")
     if res.status_code == 201:
            # The request was successful
            return res.json()
        else:
            # Encountered an error
            msg = ("Encountered an error while trying to register a new acme-dns "
                   "account. HTTP status {}, Response body: {}")
            print(msg.format(res.status_code, res.text))
            sys.exit(1)
    def update_txt_record(self, account, txt):
        """Updates the TXT challenge record to ACME-DNS subdomain."""
        update = {"subdomain": account['subdomain'], "txt": txt}
        headers = {"X-Api-User": account['username'],
                   "X-Api-Key": account['password'],
                   "Content-Type": "application/json"}
        res = requests.post(self.acmedns_url+"/update",
                            headers=headers,
                            data=json.dumps(update))
        if res.status_code == 200:
            # Successful update
            return
        else:
           msg = ("Encountered an error while trying to update TXT record in "
                   "acme-dns. \n"
                   "------- Request headers:\n{}\n"
                   "------- Request body:\n{}\n"
                   "------- Response HTTP status: {}\n"
                   "------- Response body: {}")
            s_headers = json.dumps(headers, indent=2, sort_keys=True)
            s_update = json.dumps(update, indent=2, sort_keys=True)
            s_body = json.dumps(res.json(), indent=2, sort_keys=True)
            print(msg.format(s_headers, s_update, res.status_code, s_body))
            sys.exit(1)
class Storage(object):
    def __init__(self, storagepath):
        self.storagepath = storagepath
        self._data = self.load()
    def load(self):
        """Reads the storage content from the disk to a dict structure"""
        data = dict()
        filedata = ""
        try:
            with open(self.storagepath, 'r') as fh:
                filedata = fh.read()
        except IOError as e:
            if os.path.isfile(self.storagepath):
                # Only error out if file exists, but cannot be read
                print("ERROR: Storage file exists but cannot be read")
                sys.exit(1)
        try:
            data = json.loads(filedata)
        except ValueError:
            if len(filedata) > 0:
                # Storage file is corrupted
                print("ERROR: Storage JSON is corrupted")
                sys.exit(1)
        return data
    def save(self):
        """Saves the storage content to disk"""
        serialized = json.dumps(self._data)
        try:
            with os.fdopen(os.open(self.storagepath,
                                   os.O_WRONLY | os.O_CREAT, 0o600), 'w') as fh:
                fh.truncate()
                fh.write(serialized)
        except IOError as e:
            print("ERROR: Could not write storage file.")
            sys.exit(1)
    def put(self, key, value):
        """Puts the configuration value to storage and sanitize it"""
        # If wildcard domain, remove the wildcard part as this will use the
        # same validation record name as the base domain
        if key.startswith("*."):
            key = key[2:]
        self._data[key] = value
    def fetch(self, key):
        """Gets configuration value from storage"""
        try:
            return self._data[key]
        except KeyError:
           return None
if __name__ == "__main__":
    # Init
    client = AcmeDnsClient(ACMEDNS_URL)
    storage = Storage(STORAGE_PATH)
    # Check if an account already exists in storage
    account = storage.fetch(DOMAIN)
    if FORCE_REGISTER or not account:
        # Create and save the new account
        account = client.register_account(ALLOW_FROM)
        storage.put(DOMAIN, account)
        storage.save()
        # Display the notification for the user to update the main zone
        msg = "Please add the following CNAME record to your main DNS zone:\n{}"
        cname = "{} CNAME {}.".format(VALIDATION_DOMAIN, account["fulldomain"])
        print(msg.format(cname))
    # Update the TXT record in acme-dns instance
    client.update_txt_record(account, VALIDATION_TOKEN)


This is acmedns.json file

Certbot failed to authenticate some domains (authenticator: manual). The Certificate Authority reported these problems:
Domain: vietnamthink.today
Type: unauthorized
Detail: Incorrect TXT record "1906fa54-XXXX-XXXX-a5ab-3db60907c0d4.auth.acme-dns.io" found at _acme-challenge.vietnamthink.today
Domain: vietnamthink.today
Type: unauthorized
Detail: Incorrect TXT record "1906fa54-XXXX-XXXX-a5ab-3db60907c0d4.auth.acme-dns.io" found at _acme-challenge.vietnamthink.today
Hint: The Certificate Authority failed to verify the DNS TXT records created by the --manual-auth-hook. Ensure that
this hook is functioning correctly and that it waits a sufficient duration of time for DNS propagation. Refer to "certbot --help manual" and the Certbot User Guide.
Cleaning up challenges
Some challenges have failed.
Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /var/log/letsencrypt/letsencrypt.log or re-run Certbot with -v for more details.

I must agree.

I think you may have skipped a step [CNAME _acme-challenge.vietnamthink.today to 1906fa54-xxxx-xxxx-a5ab-3db60907c0d4.auth.acme-dns.io]
OR
You don't fully understand how ACME-DNS.IO is used.

3 Likes

BTW, My system has two server, the web hosting server 192.168.1.111 (ubuntu 22.04, Nginx, Wordpress with Letsencrypt SSL) for www.vietnamthink.today/vietnamthink.today its ok; and the mail server (192.168.1.222 with ubuntu 22.04, Nginx, iRedMail) for mail.vietnamthink.today:8044/8443. Both behind NAT by ADSL (8044/8443 to mail server 192.168.1.222 and 80/443 NAT to web server 192.168.1.111)

I tested with Mxtoolbox, it has been deployed

That is NOT a CNAME.
It's a TXT record with the contents of the CNAME entry.

5 Likes

Then we only need to talk about the web server.

2 Likes

YEEEEESSSSS, I changed to CNAME and it worked, thank you so much

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.