mjl- / mox

modern full-featured open source secure mail server for low-maintenance self-hosted email
https://www.xmox.nl
MIT License
3.71k stars 113 forks source link

autocert issues #13

Closed sherief closed 1 year ago

sherief commented 1 year ago

(I apologize if this is the wrong place and / or if my issue is considered as a support request - if so please point me towards the right channels)

I'm trying to set up mox for email with my own domain, on a separate VPS, and I don't seem to be able to get autocert to respond to LetsEncrypt's challenge. Here's the log output from a fresh run with LogLevel: debug

Mar 04 13:09:25 my-vps mox[33501]: l=print m="https listener" pkg=http name=public kinds=acme-tls-alpn01,autoconfig-https,mtasts-https address=<vps-ip>:443
Mar 04 13:09:25 my-vps mox[33501]: l=print m="listening for smtp" pkg=smtpserver listener=public address=<vps-ip>:25 protocol=smtp
Mar 04 13:09:25 my-vps mox[33501]: l=print m="listening for smtp" pkg=smtpserver listener=public address=<vps-ip>:465 protocol=submissions
Mar 04 13:09:25 my-vps mox[33501]: l=print m="listening for imap" pkg=imapserver listener=public addr=<vps-ip>:993 protocol=imaps
Mar 04 13:09:26 my-vps mox[33501]: l=print m="ensuring certificate availability" pkg=http hostname=mail.sherief.fyi
Mar 04 13:09:26 my-vps mox[33501]: l=info m="getting cert from dir cache" err="acme/autocert: certificate cache miss" pkg=autotls name=mail.sherief.fyi
Mar 04 13:09:26 my-vps mox[33501]: l=debug m="dircache get result" err="acme/autocert: certificate cache miss" pkg=autotls name=mail.sherief.fyi
Mar 04 13:09:26 my-vps mox[33501]: l=debug m="autotls hostpolicy result" pkg=autotls host=mail.sherief.fyi
Mar 04 13:09:27 my-vps mox[33501]: l=debug m="dircache put result" pkg=autotls name=mail.sherief.fyi+token
Mar 04 13:09:29 my-vps mox[33501]: l=info m="new connection" pkg=smtpserver remote=178.33.24.135:61000 local=<vps-ip>:465 submission=true tls=true listener=public cid=186acbdcf3e delta="53.036µs"
Mar 04 13:09:31 my-vps mox[33501]: l=info m="connection closed" err="write: tls: client offered only unsupported versions: [302 301] (fatal io error)" pkg=smtpserver cid=186acbdcf3e delta=1.950629207s
Mar 04 13:09:38 my-vps mox[33501]: l=error m="requesting automatic certificate" err="acme/autocert: unable to satisfy \"https://acme-v02.api.letsencrypt.org/acme/authz-v3/208140824327\" for domain \"mail.sherief.fyi\": no viable challenge type found" pkg=http hostname=mail.sherief.fyi
Mar 04 13:09:38 my-vps mox[33501]: l=debug m="dircache delete result" pkg=autotls name=mail.sherief.fyi+token

autotls seems to be able to satisfy tls-alpn-01 and mox is listening on port 443. Here's my mox.conf:

# certs/keys. If this is a relative path, it is relative to the directory of
# mox.conf.
DataDir: ../data

# Default log level, one of: error, info, debug, trace, traceauth, tracedata.
# Trace logs SMTP and IMAP protocol transcripts, with traceauth also messages with
# passwords, and tracedata on top of that also the full data exchanges (full
# messages), which can be a large amount of data.
LogLevel: debug

# Full hostname of system, e.g. mail.<domain>
Hostname: mail.sherief.fyi

# If enabled, a single DNS TXT lookup of _updates.xmox.nl is done every 24h to
# check for a new release. Each time a new release is found, a changelog is
# fetched from https://updates.xmox.nl and delivered to the postmaster mailbox.
# (optional)
#
# RECOMMENDED: please enable to stay up to date
#
#CheckUpdates: true

# Automatic TLS configuration with ACME, e.g. through Let's Encrypt. The key is a
# name referenced in TLS configs, e.g. letsencrypt. (optional)
ACME:
    letsencrypt:

        # For letsencrypt, use https://acme-v02.api.letsencrypt.org/directory.
        DirectoryURL: https://acme-v02.api.letsencrypt.org/directory

        # Email address to register at ACME provider. The provider can email you when
        # certificates are about to expire. If you configure an address for which email is
        # delivered by this server, keep in mind that TLS misconfigurations could result
        # in such notification emails not arriving.
        ContactEmail: <my email>

# File containing hash of admin password, for authentication in the web admin
# pages (if enabled). (optional)
AdminPasswordFile: adminpasswd

# Listeners are groups of IP addresses and services enabled on those IP addresses,
# such as SMTP/IMAP or internal endpoints for administration or Prometheus
# metrics. All listeners with SMTP/IMAP services enabled will serve all configured
# domains.
Listeners:
    internal:

        # Use 0.0.0.0 to listen on all IPv4 and/or :: to listen on all IPv6 addresses.
        IPs:
            - 127.0.0.1
            - ::1

        # If empty, the config global Hostname is used. (optional)
        Hostname: localhost

        # Account web interface, for email users wanting to change their accounts, e.g.
        # set new password, set new delivery rulesets. (optional)
        AccountHTTP:
            Enabled: true

        # Admin web interface, for managing domains, accounts, etc. Served at /admin/.
        # Preferrably only enable on non-public IPs. (optional)
        AdminHTTP:
            Enabled: true

        # Serve prometheus metrics, for monitoring. You should not enable this on a public
        # IP. (optional)
        MetricsHTTP:
            Enabled: true
    public:

        # Use 0.0.0.0 to listen on all IPv4 and/or :: to listen on all IPv6 addresses.
        IPs:
            - <vps-ipv4>

        # For SMTP/IMAP STARTTLS, direct TLS and HTTPS connections. (optional)
        TLS:

            # Name of provider from top-level configuration to use for ACME, e.g. letsencrypt.
            # (optional)
            ACME: letsencrypt

        # (optional)
        SMTP:
            Enabled: true

            # Addresses of DNS block lists for incoming messages. Block lists are only
            # consulted for connections/messages without enough reputation to make an
            # accept/reject decision. This prevents sending IPs of all communications to the
            # block list provider. If any of the listed DNSBLs contains a requested IP
            # address, the message is rejected as spam. The DNSBLs are checked for healthiness
            # before use, at most once per 4 hours. Example DNSBLs: sbl.spamhaus.org,
            # bl.spamcop.net (optional)
            #DNSBLs:
                #- sbl.spamhaus.org
                #- bl.spamcop.net

        # SMTP over TLS for submitting email, by email applications. Requires a TLS
        # config. (optional)
        Submissions:
            Enabled: true

        # IMAP over TLS for reading email, by email applications. Requires a TLS config.
        # (optional)
        IMAPS:
            Enabled: true

        # Serve autoconfiguration/autodiscovery to simplify configuring email
        # applications, will use port 443. Requires a TLS config. (optional)
        AutoconfigHTTPS:
            Enabled: true

        # Serve MTA-STS policies describing SMTP TLS requirements, will use port 443.
        # Requires a TLS config. (optional)
        MTASTSHTTPS:
            Enabled: true

# Destination for emails delivered to postmaster address.
Postmaster:
    Account: sherief

    # E.g. Postmaster or Inbox.
    Mailbox: Postmaster

Any pointers as to how I can debug this further? I'm not a domain expert so I might be missing some basic config items.

mjl- commented 1 year ago

You've come to the right place! (: I see your hostname has an ipv6 address too (it resolves to both an ipv4 and ipv6 address. There is a good chance Let's Encrypt is trying to connect to it. I've had a similar error too once while testing, where my ipv6 address had changed (after a reinstall). Could you try it with the ipv6 address added to the IPs in the "public" listener? Or is there a reason you didn't add it there? Or did the quickstart not find and add it?

sherief commented 1 year ago

Thank you :D

Here's my new mox.conf:

# Directory where all data is stored, e.g. queue, accounts and messages, ACME TLS
# certs/keys. If this is a relative path, it is relative to the directory of
# mox.conf.
DataDir: ../data

# Default log level, one of: error, info, debug, trace, traceauth, tracedata.
# Trace logs SMTP and IMAP protocol transcripts, with traceauth also messages with
# passwords, and tracedata on top of that also the full data exchanges (full
# messages), which can be a large amount of data.
LogLevel: debug

# Full hostname of system, e.g. mail.<domain>
Hostname: mail.sherief.fyi

# If enabled, a single DNS TXT lookup of _updates.xmox.nl is done every 24h to
# check for a new release. Each time a new release is found, a changelog is
# fetched from https://updates.xmox.nl and delivered to the postmaster mailbox.
# (optional)
#
# RECOMMENDED: please enable to stay up to date
#
#CheckUpdates: true

# Automatic TLS configuration with ACME, e.g. through Let's Encrypt. The key is a
# name referenced in TLS configs, e.g. letsencrypt. (optional)
ACME:
    letsencrypt:

        # For letsencrypt, use https://acme-v02.api.letsencrypt.org/directory.
        DirectoryURL: https://acme-v02.api.letsencrypt.org/directory

        # Email address to register at ACME provider. The provider can email you when
        # certificates are about to expire. If you configure an address for which email is
        # delivered by this server, keep in mind that TLS misconfigurations could result
        # in such notification emails not arriving.
        ContactEmail: sherief.personal@gmail.com

# File containing hash of admin password, for authentication in the web admin
# pages (if enabled). (optional)
AdminPasswordFile: adminpasswd

# Listeners are groups of IP addresses and services enabled on those IP addresses,
# such as SMTP/IMAP or internal endpoints for administration or Prometheus
# metrics. All listeners with SMTP/IMAP services enabled will serve all configured
# domains.
Listeners:
    internal:

        # Use 0.0.0.0 to listen on all IPv4 and/or :: to listen on all IPv6 addresses.
        IPs:
            - 127.0.0.1
            - ::1

        # If empty, the config global Hostname is used. (optional)
        Hostname: localhost

        # Account web interface, for email users wanting to change their accounts, e.g.
        # set new password, set new delivery rulesets. (optional)
        AccountHTTP:
            Enabled: true

        # Admin web interface, for managing domains, accounts, etc. Served at /admin/.
        # Preferrably only enable on non-public IPs. (optional)
        AdminHTTP:
            Enabled: true

        # Serve prometheus metrics, for monitoring. You should not enable this on a public
        # IP. (optional)
        MetricsHTTP:
            Enabled: true
    public:

        # Use 0.0.0.0 to listen on all IPv4 and/or :: to listen on all IPv6 addresses.
        IPs:
            - 51.222.27.213
            - 2607:5300:205:200::279f

        # For SMTP/IMAP STARTTLS, direct TLS and HTTPS connections. (optional)
        TLS:

            # Name of provider from top-level configuration to use for ACME, e.g. letsencrypt.
            # (optional)
            ACME: letsencrypt

        # (optional)
        SMTP:
            Enabled: true

            # Addresses of DNS block lists for incoming messages. Block lists are only
            # consulted for connections/messages without enough reputation to make an
            # accept/reject decision. This prevents sending IPs of all communications to the
            # block list provider. If any of the listed DNSBLs contains a requested IP
            # address, the message is rejected as spam. The DNSBLs are checked for healthiness
            # before use, at most once per 4 hours. Example DNSBLs: sbl.spamhaus.org,
            # bl.spamcop.net (optional)
            #DNSBLs:
                #- sbl.spamhaus.org
                #- bl.spamcop.net

        # SMTP over TLS for submitting email, by email applications. Requires a TLS
        # config. (optional)
        Submissions:
            Enabled: true

        # IMAP over TLS for reading email, by email applications. Requires a TLS config.
        # (optional)
        IMAPS:
            Enabled: true

        # Serve autoconfiguration/autodiscovery to simplify configuring email
        # applications, will use port 443. Requires a TLS config. (optional)
        AutoconfigHTTPS:
            Enabled: true

        # Serve MTA-STS policies describing SMTP TLS requirements, will use port 443.
        # Requires a TLS config. (optional)
        MTASTSHTTPS:
            Enabled: true

# Destination for emails delivered to postmaster address.
Postmaster:
    Account: sherief

    # E.g. Postmaster or Inbox.
    Mailbox: Postmaster

But it seems bind() fails when I add that:

Mar 04 19:42:39 vps-312889aa mox[34362]: l=print m="http listener" pkg=http name=internal kinds=account-http,admin-http address=[::1]:80
Mar 04 19:42:39 vps-312889aa mox[34362]: l=print m="http listener" pkg=http name=internal kinds=metrics-http address=127.0.0.1:8010
Mar 04 19:42:39 vps-312889aa mox[34362]: l=print m="http listener" pkg=http name=internal kinds=metrics-http address=[::1]:8010
Mar 04 19:42:39 vps-312889aa mox[34362]: l=debug m="autotls add hostname" pkg=autotls hostname=mail.sherief.fyi
Mar 04 19:42:39 vps-312889aa mox[34362]: l=print m="https listener" pkg=http name=public kinds=acme-tls-alpn01,autoconfig-https,mtasts-https address=51.222.27.213:443
Mar 04 19:42:39 vps-312889aa mox[34362]: l=print m="https listener" pkg=http name=public kinds=acme-tls-alpn01,autoconfig-https,mtasts-https address=[2607:5300:205:200::279f]:443
Mar 04 19:42:39 vps-312889aa mox[34362]: l=fatal m="https: listen" err="listen tcp6 [2607:5300:205:200::279f]:443: bind: cannot assign requested address" pkg=http addr=[2607:5300:205:200::279f]:443
Mar 04 19:42:39 vps-312889aa systemd[1]: mox.service: Main process exited, code=exited, status=1/FAILURE
Mar 04 19:42:39 vps-312889aa systemd[1]: mox.service: Failed with result 'exit-code'.

I also tried commenting out the ipv4 address and leaving the ipv6 only, but I got the same error.

mjl- commented 1 year ago

I don't normally see the error message bind: cannot assign requested address. Not being able to bind due to no permission is more common. Is the IPv6 address configured and working? I'm not getting ping responses back from your ipv6 address, but I do from your IPv4 address.

Or perhaps something is already listening on [::]:443? E.g. port 443 for all IPv6 addresses? On linux you can easily check this with netstat -ntulp and look for :::443.

Or could there be something in play that hides the ipv6 IP? Are you running this from the systemd service file? If so, could you try start outside systemd, by just running (as root) with "./mox serve" and see if that makes a difference? Mox.service should have RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX AF_NETLINK, perhaps the AF_INET6 is missing?

Or perhaps you're using docker?

sherief commented 1 year ago

ipv6 was misconfigured on my VPS. I fixed that and.. it worked! I now have my own email server, and the only point of friction was my misunderstanding of ipv6 configuration!

I am blown away. Thank you, this is amazing. I never thought I'd be able to pull this off with how little server administration I know.