Skip to content

Add reject_unknown_client_hostname to main.cf#2691

Merged
polarathene merged 4 commits intodocker-mailserver:masterfrom
GoliathLabs:patch-1
Sep 5, 2022
Merged

Add reject_unknown_client_hostname to main.cf#2691
polarathene merged 4 commits intodocker-mailserver:masterfrom
GoliathLabs:patch-1

Conversation

@GoliathLabs
Copy link
Copy Markdown
Contributor

@GoliathLabs GoliathLabs commented Jul 24, 2022

Description

As discussed in the below mentioned issue this adds the reject_unknown_client_hostname option.

Reference: http://www.postfix.org/postconf.5.html#reject_unknown_client_hostname

Fixes #2650

Type of change

  • Improvement (non-breaking change that does improve existing functionality)

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (README.md or the documentation under docs/)
  • If necessary I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@GoliathLabs
Copy link
Copy Markdown
Contributor Author

Not sure whether change in the docs is needed

@polarathene
Copy link
Copy Markdown
Member

From the associated issue:

  • Users could additionally configure known problematic clients to bypass the restriction via check_client_access.

It could be worth documenting that, but until an issue is raised regarding it, I'm fine avoiding docs for now as I'd like to know if this change does cause problems for users.


This change is for the more strict version than reject_unknown_reverse_client_hostname which was approved.

With reject_unknown_client_hostname, the HELO hostname must have a DNS A record that resolves to the IP matching the client, otherwise the client is rejected.

I suspect that can be a common misconfiguration by our users based on past issues. For those using OVERRIDE_HOSTNAME ENV, our scripts do export this as HOSTNAME ENV, but I'm not sure if services like Postfix detect that (it seems we configure for that explicitly for Postfix).

I realize this is about filtering out inbound mail, nothing related to outbound mail, but I was thinking of scenarios with tests or when one DMS instance sends to another.


Ideally any legitimate mail server is going to be configured correctly, and pass those additional conditions, so hopefully when users update, they're not going to find legitimate mail being rejected that is received from third-parties.

@georglauterbach
Copy link
Copy Markdown
Member

I also think this is a worthwhile addition and a right one :)

@GoliathLabs
Copy link
Copy Markdown
Contributor Author

GoliathLabs commented Jul 27, 2022

@georglauterbach @polarathene one thing I noticed yesterday is that sending mail from another container on the same host will fail: dani-garcia/vaultwarden#2647

@GoliathLabs
Copy link
Copy Markdown
Contributor Author

Normally you would want to have a separate host for your mails, but in some cases that is not the case. So we need to solve this somehow by allowing mails from the internal Docker networks. I tried both connected-networks and network as allowed networks, but in both cases the test mail is rejected because of the message 4.7.25 Client host rejected: cannot find your hostname.

@polarathene
Copy link
Copy Markdown
Member

polarathene commented Jul 27, 2022

I figured you might get something like that happening 😅

You can play around with a fully offline setup with local DNS as I demonstrate here.

Your change shouldn't cause new rejections if the client passes either permits: permit_sasl_authenticated, permit_mynetworks.

Is your client sending on port 25 instead of 587/465? If so you'd need to sort out the network, which you can debug in this method to ensure both containers have the same network/interface to connect to each other and that the IP falls within the subnet.

@polarathene polarathene added this to the v12.0.0 milestone Jul 28, 2022
@polarathene polarathene added priority/low service/postfix kind/improvement Improve an existing feature, configuration file or the documentation area/configuration (file) labels Jul 28, 2022
Copy link
Copy Markdown
Member

@casperklein casperklein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, however this should be fixed:

#2691 (comment)

@GoliathLabs
Copy link
Copy Markdown
Contributor Author

I am sending over 587 and STARTTLS. When I change the permit_network to connected-networks or network, it still doesn't work. Interestingly, 172.25.0.1 is the gateway IP of the mailserver_default network, which normally shouldn't be a problem since we included it with either network or connected-works. Nevertheless, it doesn't seem to work.

The main.cf with connected-networks:

# Basic configuration
# myhostname =
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = $myhostname, localhost.$mydomain, localhost
relayhost =
mynetworks = 127.0.0.0/8 [::1]/128 [fe80::]/64 127.0.0.0/8 172.26.0.0/16 172.25.0.0/16
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all

@polarathene
Copy link
Copy Markdown
Member

Have you tried following my advice for a local multi-instance setup with the local DNS config it shows?

It may still fail though as the Corefile there doesn't configure rDNS 🤔


I am unable to help investigate any time soon, but I did link to full offline setup you can adapt. I know it's not quite enough to copy/paste and test, but at least would provide a more common config to reproduce from, since you haven't really shared much information of your own for reproduction.

If the hostname is really an issue look in /etc/hosts for each container, and also try use DNS utilities to contact the other container by hostname (within the containers themselves, not the docker host) advertised from the SMTP HELO. Best to first try reproduce that error outside of all the mail software involved.

@GoliathLabs
Copy link
Copy Markdown
Contributor Author

GoliathLabs commented Aug 3, 2022

My findings so far and my mail server setup. And thank you @polarathene for taking the time to help me. Sadtly I don't have time to create a replica of my mail server at home right now. But I did find out some interesting things below which may help to debug this problem? (hopefully)
docker-compose.yml

version: '3.8'

services:
  mailserver:
    image: mailserver/docker-mailserver:11.1.0
    hostname: mail
    domainname: example.com
    env_file: mailserver.env
    depends_on:
      - ipv6nat
    # To avoid conflicts with yaml base-60 float, DO NOT remove the quotation marks.
    # More information about the mailserver ports:
    # https://docker-mailserver.github.io/docker-mailserver/edge/config/security/understanding-the-ports/
#    dns:
#      - 5.1.66.255
#      - 185.150.99.255
#      - "2001:678:e68:f000::"
#      - "2001:678:ed0:f000::"
    ports:
      - "25:25"    # SMTP  (explicit TLS => STARTTLS)
      - "143:143"  # IMAP4 (explicit TLS => STARTTLS)
      - "465:465"  # ESMTP (implicit TLS)
      - "587:587"  # ESMTP (explicit TLS => STARTTLS)
      - "993:993"  # IMAP4 (implicit TLS)
    volumes:
      - ./data:/var/mail/
      - ./state:/var/mail-state/
      - ./logs:/var/log/mail/
      - /etc/localtime:/etc/localtime:ro
      - ./config/:/tmp/docker-mailserver/
      - ./certs/:/certs
      - ./config/dovecot/20-lmtp.conf:/etc/dovecot/conf.d/20-lmtp.conf
      - ./config/dovecot/20-imap.conf:/etc/dovecot/conf.d/20-imap.conf
      - ./config/dovecot/20-pop3.conf:/etc/dovecot/conf.d/20-pop3.conf
      - ./config/dovecot/fts-xapian-plugin.conf:/etc/dovecot/conf.d/10-plugin.conf:ro
      - ./header_checks.pcre:/etc/postfix/maps/header_checks.pcre
      - /opt/containers/traefik/data/acme.json:/etc/letsencrypt/acme.json:ro
      - ./cron/sa-learn:/etc/cron.d/sa-learn
      - ./cron/fts-index:/etc/cron.d/fts-index
    restart: always
    stop_grace_period: 1m
    cap_add:
      - NET_ADMIN
      - SYS_PTRACE
    networks:
      - default
      - mail

  ipv6nat:
    restart: always
    image: robbertkl/ipv6nat:0.4.4
    privileged: true
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /lib/modules:/lib/modules:ro
    network_mode: "host"

  autodiscover:
    image: monogramm/autodiscover-email-settings:production
    container_name: autodiscover
    environment:
      - COMPANY_NAME=Morph Network
      - SUPPORT_URL=https://autodiscover.example.com
      - DOMAIN=example.com
      # IMAP configuration (host mandatory to enable)
      - IMAP_HOST=IMAP.example.com
      - IMAP_PORT=143
      - IMAP_SOCKET=STARTTLS
      # SMTP configuration (host mandatory to enable)
      - SMTP_HOST=SMTP.example.com
      - SMTP_PORT=587
      - SMTP_SOCKET=STARTTLS
      # Apple mobile config identifiers (identifier mandatory to enable)
      - PROFILE_IDENTIFIER=com.example.autodiscover
      - PROFILE_UUID=64263270-c3c3-43f7-9a81-65b75184c832
      - MAIL_UUID=1ec26cc6-7dc4-48bd-a2ef-d2a92e135202
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.autodiscover.entrypoints=http"
      - "traefik.http.routers.autodiscover.rule=Host(`autoconfig.example.com`, `autodiscover.example.com`)"
      - "traefik.http.middlewares.autodiscover-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.autodiscover.middlewares=autodiscover-https-redirect"
      - "traefik.http.routers.autodiscover-secure.entrypoints=https"
      - "traefik.http.routers.autodiscover-secure.rule=Host(`autoconfig.example.com`, `autodiscover.example.com`)"
      - "traefik.http.routers.autodiscover-secure.tls=true"
      - "traefik.http.routers.autodiscover-secure.tls.certresolver=http"
      - "traefik.http.routers.autodiscover-secure.service=autodiscover"
      - "traefik.http.services.autodiscover.loadbalancer.server.port=8000"
      - "traefik.docker.network=proxy"
      - "traefik.http.routers.autodiscover-secure.middlewares=secHeaders@file"
      - "traefik.port=8000"
    networks:
      - proxy

  roundcubemail:
    image: roundcube/roundcubemail:1.5.x-fpm-alpine
    container_name: roundcubemail
    # restart: unless-stopped
    depends_on:
      - roundcubedb
    links:
      - roundcubedb
    volumes:
      - /opt/containers/mailserver/roundcube:/var/www/html
    environment:
      - ROUNDCUBEMAIL_DB_TYPE=pgsql
      - ROUNDCUBEMAIL_DB_HOST=roundcubedb # same as pgsql container name
      - ROUNDCUBEMAIL_DB_NAME=roundcube # same as pgsql POSTGRES_DB env name
      - ROUNDCUBEMAIL_DB_USER=roundcube # same as pgsql POSTGRES_USER env name
      - ROUNDCUBEMAIL_DB_PASSWORD=somefancypassword # same as pgsql POSTGRES_PASSWORD env name
      - ROUNDCUBEMAIL_SKIN=elastic
      - ROUNDCUBEMAIL_DEFAULT_HOST=tls://mail.example.com
      - ROUNDCUBEMAIL_SMTP_SERVER=tls://mail.example.com

  roundcubedb:
    image: postgres:14.4-alpine
    container_name: roundcubedb
    restart: unless-stopped
    volumes:
      - ./database:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=roundcube
      - POSTGRES_USER=roundcube
      - POSTGRES_PASSWORD=somefancypassword

  roundcubenginx:
    image: nginx:1.23.1-alpine
    container_name: roundcubenginx
    # restart: unless-stopped
      # If you need SSL connection
      # - '443:443'
    depends_on:
      - roundcubemail
    links:
      - roundcubemail
    volumes:
      - ./roundcube:/var/www/html
      - ./nginx/templates:/etc/nginx/templates
      # Provide a custom nginx conf
      # - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      # If you need SSL connection, you can provide your own certificates
      # - ./certs:/etc/letsencrypt
      # - ./certs-data:/data/letsencrypt
    environment:
      - NGINX_HOST=localhost # set your local domain or your live domain
      - NGINX_PHP_CGI=roundcubemail:9000 # same as roundcubemail container name
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.roundcube.entrypoints=http"
      - "traefik.http.routers.roundcube.rule=Host(`mail.example.com`, `webmail.example.com`, `imap.example.com`, `smtp.example.com`)"
      - "traefik.http.middlewares.roundcube-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.roundcube.middlewares=roundcube-https-redirect"
      - "traefik.http.routers.roundcube-secure.entrypoints=https"
      - "traefik.http.routers.roundcube-secure.rule=Host(`mail.example.com`, `webmail.example.com`, `imap.example.com`, `smtp.example.com`)"
      - "traefik.http.routers.roundcube-secure.tls=true"
      - "traefik.http.routers.roundcube-secure.tls.certresolver=http"
      - "traefik.http.routers.roundcube-secure.service=roundcube"
      - "traefik.http.services.roundcube.loadbalancer.server.port=80"
      - "traefik.docker.network=proxy"
      - "traefik.http.routers.roundcube-secure.middlewares=secHeaders@file"
    networks:
      - default
      - proxy

  mta-sts:
    image: nginx:1.23.1-alpine
    restart: unless-stopped
    volumes:
      - /opt/containers/mailserver/mta-sts:/usr/share/nginx/html:ro
      - /opt/containers/mailserver/mta-sts.conf:/etc/nginx/conf.d/default.conf
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.mta-sts.entrypoints=http"
      - "traefik.http.routers.mta-sts.rule=Host(`mta-sts.example.com`)"
      - "traefik.http.middlewares.mta-sts-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.mta-sts.middlewares=mta-sts-https-redirect"
      - "traefik.http.routers.mta-sts-secure.entrypoints=https"
      - "traefik.http.routers.mta-sts-secure.rule=Host(`mta-sts.example.com)"
      - "traefik.http.routers.mta-sts-secure.tls=true"
      - "traefik.http.routers.mta-sts-secure.tls.certresolver=http"
      - "traefik.http.routers.mta-sts-secure.service=mta-sts"
      - "traefik.http.services.mta-sts.loadbalancer.server.port=80"
      - "traefik.docker.network=proxy"
    networks:
      - proxy
    healthcheck:
      test: ["CMD-SHELL", "wget -O /dev/null http://localhost || exit 1"]
      interval: 2s
      timeout: 30s
      retries: 15

networks:
  proxy:
    external: true
networks:
  default:
    driver: bridge
    enable_ipv6: true
    ipam:
      driver: default
      config:
        - subnet: fd00:0123:4567::/48
          gateway: fd00:0123:4567::1
  proxy:
    external: true
  mail:
    external: true

mailserver.env

# -----------------------------------------------
# --- Mailserver Environment Variables ----------
# -----------------------------------------------

# DOCUMENTATION FOR THESE VARIABLES IS FOUND UNDER
# https://docker-mailserver.github.io/docker-mailserver/edge/config/environment/

# -----------------------------------------------
# --- General Section ---------------------------
# -----------------------------------------------

# empty => uses the `hostname` command to get the mail server's canonical hostname
# => Specify a fully-qualified domainname to serve mail for.  This is used for many of the config features so if you can't set your hostname (e.g. you're in a container platform that doesn't let you) specify it in this environment variable.
OVERRIDE_HOSTNAME=mail.example.com

# REMOVED in version v11.0.0! Use LOG_LEVEL instead.
DMS_DEBUG=0

# Set the log level for DMS.
# This is mostly relevant for container startup scripts and change detection event feedback.
#
# Valid values (in order of increasing verbosity) are: `error`, `warn`, `info`, `debug` and `trace`.
# The default log level is `info`.
LOG_LEVEL=info

# critical => Only show critical messages
# error => Only show erroneous output
# **warn** => Show warnings
# info => Normal informational output
# debug => Also show debug messages
SUPERVISOR_LOGLEVEL=info

# 0 => mail state in default directories
# 1 => consolidate all states into a single directory (`/var/mail-state`) to allow persistence using docker volumes
ONE_DIR=1

# empty => [email protected]
# => Specify the postmaster address
[email protected]

# Check for updates on container start and then once a day
# If an update is available, a mail is sent to POSTMASTER_ADDRESS
# 0 => Update check disabled
# 1 => Update check enabled
ENABLE_UPDATE_CHECK=1

# Customize the update check interval.
# Number + Suffix. Suffix must be 's' for seconds, 'm' for minutes, 'h' for hours or 'd' for days.
UPDATE_CHECK_INTERVAL=1d

# Set different options for mynetworks option (can be overwrite in postfix-main.cf)
# **WARNING**: Adding the docker network's gateway to the list of trusted hosts, e.g. using the `network` or
# `connected-networks` option, can create an open relay
# https://github.com/docker-mailserver/docker-mailserver/issues/1405#issuecomment-590106498
# The same can happen for rootless podman. To prevent this, set the value to "none" or configure slirp4netns
# https://github.com/docker-mailserver/docker-mailserver/issues/2377
#
# none => Explicitly force authentication
# container => Container IP address only
# host => Add docker container network (ipv4 only)
# network => Add all docker container networks (ipv4 only)
# connected-networks => Add all connected docker networks (ipv4 only)
PERMIT_DOCKER=connected-networks

# Set the timezone. If this variable is unset, the container runtime will try to detect the time using
# `/etc/localtime`, which you can alternatively mount into the container. The value of this variable
# must follow the pattern `AREA/ZONE`, i.e. of you want to use Germany's time zone, use `Europe/Berlin`.
# You can lookup all available timezones here: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
TZ=Europe/Berlin

# In case you network interface differs from 'eth0', e.g. when you are using HostNetworking in Kubernetes,
# you can set NETWORK_INTERFACE to whatever interface you want. This interface will then be used.
#  - **empty** => eth0
NETWORK_INTERFACE=

# empty => modern
# modern => Enables TLSv1.2 and modern ciphers only. (default)
# intermediate => Enables TLSv1, TLSv1.1 and TLSv1.2 and broad compatibility ciphers.
TLS_LEVEL=modern

# Configures the handling of creating mails with forged sender addresses.
#
# empty => (not recommended, but default for backwards compatibility reasons)
#           Mail address spoofing allowed. Any logged in user may create email messages with a forged sender address.
#           See also https://en.wikipedia.org/wiki/Email_spoofing
# 1 => (recommended) Mail spoofing denied. Each user may only send with his own or his alias addresses.
#       Addresses with extension delimiters(http://www.postfix.org/postconf.5.html#recipient_delimiter) are not able to send messages.
SPOOF_PROTECTION=1

# Enables the Sender Rewriting Scheme. SRS is needed if your mail server acts as forwarder. See [postsrsd](https://github.com/roehling/postsrsd/blob/master/README.md#sender-rewriting-scheme-crash-course) for further explanation.
#  - **0** => Disabled
#  - 1 => Enabled
ENABLE_SRS=0

# 1 => Enables POP3 service
# empty => disables POP3
ENABLE_POP3=
ENABLE_CLAMAV=1

# Amavis content filter (used for ClamAV & SpamAssassin)
# 0 => Disabled
# 1 => Enabled
ENABLE_AMAVIS=1

# -1/-2/-3 => Only show errors
# **0**    => Show warnings
# 1/2      => Show default informational output
# 3/4/5    => log debug information (very verbose)
AMAVIS_LOGLEVEL=1

# This enables the [zen.spamhaus.org](https://www.spamhaus.org/zen/) DNS block list in postfix
# and various [lists](https://github.com/docker-mailserver/docker-mailserver/blob/f7465a50888eef909dbfc01aff4202b9c7d8bc00/target/postfix/main.cf#L58-L66) in postscreen.
# Note: Emails will be rejected, if they don't pass the block list checks!
# **0** => DNS block lists are disabled
# 1     => DNS block lists are enabled
ENABLE_DNSBL=1

# If you enable Fail2Ban, don't forget to add the following lines to your `docker-compose.yml`:
#    cap_add:
#      - NET_ADMIN
# Otherwise, `nftables` won't be able to ban IPs.
ENABLE_FAIL2BAN=1

# Fail2Ban blocktype
# drop   => drop packet (send NO reply)
# reject => reject packet (send ICMP unreachable)
FAIL2BAN_BLOCKTYPE=drop

# 1 => Enables Managesieve on port 4190
# empty => disables Managesieve
ENABLE_MANAGESIEVE=1

# **enforce** => Allow other tests to complete. Reject attempts to deliver mail with a 550 SMTP reply, and log the helo/sender/recipient information. Repeat this test the next time the client connects.
# drop => Drop the connection immediately with a 521 SMTP reply. Repeat this test the next time the client connects.
# ignore => Ignore the failure of this test. Allow other tests to complete. Repeat this test the next time the client connects. This option is useful for testing and collecting statistics without blocking mail.
POSTSCREEN_ACTION=drop

# empty => all daemons start
# 1 => only launch postfix smtp
SMTP_ONLY=

# Please read [the SSL page in the documentation](https://docker-mailserver.github.io/docker-mailserver/edge/config/security/ssl) for more information.
#
# empty => SSL disabled
# letsencrypt => Enables Let's Encrypt certificates
# custom => Enables custom certificates
# manual => Let's you manually specify locations of your SSL certificates for non-standard cases
# self-signed => Enables self-signed certificates
SSL_TYPE=letsencrypt

# These are only supported with `SSL_TYPE=manual`.
# Provide the path to your cert and key files that you've mounted access to within the container.
SSL_CERT_PATH=
SSL_KEY_PATH=
# Optional: A 2nd certificate can be supported as fallback (dual cert support), eg ECDSA with an RSA fallback.
# Useful for additional compatibility with older MTA and MUA (eg pre-2015).
SSL_ALT_CERT_PATH=
SSL_ALT_KEY_PATH=

# Set how many days a virusmail will stay on the server before being deleted
# empty => 7 days
VIRUSMAILS_DELETE_DELAY=

# This Option is activating the Usage of POSTFIX_DAGENT to specify a lmtp client different from default dovecot socket.
# empty => disabled
# 1 => enabled
ENABLE_POSTFIX_VIRTUAL_TRANSPORT=

# Enabled by ENABLE_POSTFIX_VIRTUAL_TRANSPORT. Specify the final delivery of postfix
#
# empty => fail
# `lmtp:unix:private/dovecot-lmtp` (use socket)
# `lmtps:inet:<host>:<port>` (secure lmtp with starttls, take a look at https://sys4.de/en/blog/2014/11/17/sicheres-lmtp-mit-starttls-in-dovecot/)
# `lmtp:<kopano-host>:2003` (use kopano as mailstore)
# etc.
POSTFIX_DAGENT=

# Set the mailbox size limit for all users. If set to zero, the size will be unlimited (default).
#
# empty => 0
POSTFIX_MAILBOX_SIZE_LIMIT=

# See https://docker-mailserver.github.io/docker-mailserver/edge/config/user-management/accounts/#notes
# 0 => Dovecot quota is disabled
# 1 => Dovecot quota is enabled
ENABLE_QUOTAS=1

# Set the message size limit for all users. If set to zero, the size will be unlimited (not recommended!)
#
# empty => 10240000 (~10 MB)
POSTFIX_MESSAGE_SIZE_LIMIT=

# Mails larger than this limit won't be scanned.
# ClamAV must be enabled (ENABLE_CLAMAV=1) for this.
#
# empty => 25M (25 MB)
CLAMAV_MESSAGE_SIZE_LIMIT=

# Enables regular pflogsumm mail reports.
# This is a new option. The old REPORT options are still supported for backwards compatibility. If this is not set and reports are enabled with the old options, logrotate will be used.
#
# not set => No report
# daily_cron => Daily report for the previous day
# logrotate => Full report based on the mail log when it is rotated
PFLOGSUMM_TRIGGER=

# Recipient address for pflogsumm reports.
#
# not set => Use REPORT_RECIPIENT or POSTMASTER_ADDRESS
# => Specify the recipient address(es)
PFLOGSUMM_RECIPIENT=

# Sender address (`FROM`) for pflogsumm reports if pflogsumm reports are enabled.
#
# not set => Use REPORT_SENDER
# => Specify the sender address
PFLOGSUMM_SENDER=

# Interval for logwatch report.
#
# none => No report is generated
# daily => Send a daily report
# weekly => Send a report every week
LOGWATCH_INTERVAL=

# Recipient address for logwatch reports if they are enabled.
#
# not set => Use REPORT_RECIPIENT or POSTMASTER_ADDRESS
# => Specify the recipient address(es)
LOGWATCH_RECIPIENT=

# Sender address (`FROM`) for logwatch reports if logwatch reports are enabled.
#
# not set => Use REPORT_SENDER
# => Specify the sender address
LOGWATCH_SENDER=

# Defines who receives reports if they are enabled.
# **empty** => ${POSTMASTER_ADDRESS}
# => Specify the recipient address
REPORT_RECIPIENT=

# Defines who sends reports if they are enabled.
# **empty** => mailserver-report@${DOMAINNAME}
# => Specify the sender address
REPORT_SENDER=

# Changes the interval in which log files are rotated
# **weekly** => Rotate log files weekly
# daily => Rotate log files daily
# monthly => Rotate log files monthly
#
# Note: This Variable actually controls logrotate inside the container
# and rotates the log files depending on this setting. The main log output is
# still available in its entirety via `docker logs mail` (Or your
# respective container name). If you want to control logrotation for
# the Docker-generated logfile see:
# https://docs.docker.com/config/containers/logging/configure/
#
# Note: This variable can also determine the interval for Postfix's log summary reports, see [`PFLOGSUMM_TRIGGER`](#pflogsumm_trigger).
LOGROTATE_INTERVAL=weekly

# Choose TCP/IP protocols for postfix to use
# **all** => All possible protocols.
# ipv4 => Use only IPv4 traffic. Most likely you want this behind Docker.
# ipv6 => Use only IPv6 traffic.
#
# Note: More details at http://www.postfix.org/postconf.5.html#inet_protocols
POSTFIX_INET_PROTOCOLS=all

# Choose TCP/IP protocols for dovecot to use
# **all** => Listen on all interfaces
# ipv4 => Listen only on IPv4 interfaces. Most likely you want this behind Docker.
# ipv6 => Listen only on IPv6 interfaces.
#
# Note: More information at https://dovecot.org/doc/dovecot-example.conf
DOVECOT_INET_PROTOCOLS=all

# -----------------------------------------------
# --- SpamAssassin Section ----------------------
# -----------------------------------------------

ENABLE_SPAMASSASSIN=1

# deliver spam messages in the inbox (eventually tagged using SA_SPAM_SUBJECT)
SPAMASSASSIN_SPAM_TO_INBOX=1

# KAM is a 3rd party SpamAssassin ruleset, provided by the McGrail Foundation.
# If SpamAssassin is enabled, KAM can be used in addition to the default ruleset.
# - **0** => KAM disabled
# - 1 => KAM enabled
#
# Note: only has an effect if `ENABLE_SPAMASSASSIN=1`
ENABLE_SPAMASSASSIN_KAM=1

# spam messages will be moved in the Junk folder (SPAMASSASSIN_SPAM_TO_INBOX=1 required)
MOVE_SPAM_TO_JUNK=1

# add spam info headers if at, or above that level:
SA_TAG=2.0

# add 'spam detected' headers at that level
SA_TAG2=5.00

# triggers spam evasive actions
SA_KILL=5.00

# add tag to subject if spam detected
SA_SPAM_SUBJECT=***SPAM*****

# -----------------------------------------------
# --- Fetchmail Section -------------------------
# -----------------------------------------------

ENABLE_FETCHMAIL=0

# The interval to fetch mail in seconds
FETCHMAIL_POLL=300

# -----------------------------------------------
# --- LDAP Section ------------------------------
# -----------------------------------------------

# A second container for the ldap service is necessary (i.e. https://github.com/osixia/docker-openldap)
# For preparing the ldap server to use in combination with this container this article may be helpful: http://acidx.net/wordpress/2014/06/installing-a-mailserver-with-postfix-dovecot-sasl-ldap-roundcube/

# empty => LDAP authentification is disabled
# 1 => LDAP authentification is enabled
ENABLE_LDAP=

# empty => no
# yes => LDAP over TLS enabled for Postfix
LDAP_START_TLS=

# If you going to use the mailserver in combination with docker-compose you can set the service name here
# empty => mail.domain.com
# Specify the dns-name/ip-address where the ldap-server
LDAP_SERVER_HOST=

# empty => ou=people,dc=domain,dc=com
# => e.g. LDAP_SEARCH_BASE=dc=mydomain,dc=local
LDAP_SEARCH_BASE=

# empty => cn=admin,dc=domain,dc=com
# => take a look at examples of SASL_LDAP_BIND_DN
LDAP_BIND_DN=

# empty** => admin
# => Specify the password to bind against ldap
LDAP_BIND_PW=

# e.g. `"(&(mail=%s)(mailEnabled=TRUE))"`
# => Specify how ldap should be asked for users
LDAP_QUERY_FILTER_USER=

# e.g. `"(&(mailGroupMember=%s)(mailEnabled=TRUE))"`
# => Specify how ldap should be asked for groups
LDAP_QUERY_FILTER_GROUP=

# e.g. `"(&(mailAlias=%s)(mailEnabled=TRUE))"`
# => Specify how ldap should be asked for aliases
LDAP_QUERY_FILTER_ALIAS=

# e.g. `"(&(|(mail=*@%s)(mailalias=*@%s)(mailGroupMember=*@%s))(mailEnabled=TRUE))"`
# => Specify how ldap should be asked for domains
LDAP_QUERY_FILTER_DOMAIN=

# -----------------------------------------------
# --- Dovecot Section ---------------------------
# -----------------------------------------------

# empty => no
# yes => LDAP over TLS enabled for Dovecot
DOVECOT_TLS=

# e.g. `"(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))"`
DOVECOT_USER_FILTER=

# e.g. `"(&(objectClass=PostfixBookMailAccount)(uniqueIdentifier=%n))"`
DOVECOT_PASS_FILTER=

# Define the mailbox format to be used
# default is maildir, supported values are: sdbox, mdbox, maildir
DOVECOT_MAILBOX_FORMAT=maildir

# empty => no
# yes => Allow bind authentication for LDAP
# https://wiki.dovecot.org/AuthDatabase/LDAP/AuthBinds
DOVECOT_AUTH_BIND=

# -----------------------------------------------
# --- Postgrey Section --------------------------
# -----------------------------------------------

ENABLE_POSTGREY=1
# greylist for N seconds
POSTGREY_DELAY=300
# delete entries older than N days since the last time that they have been seen
POSTGREY_MAX_AGE=35
# response when a mail is greylisted
POSTGREY_TEXT="Delayed by Postgrey"
# whitelist host after N successful deliveries (N=0 to disable whitelisting)
POSTGREY_AUTO_WHITELIST_CLIENTS=5

# -----------------------------------------------
# --- SASL Section ------------------------------
# -----------------------------------------------

ENABLE_SASLAUTHD=0

# empty => pam
# `ldap` => authenticate against ldap server
# `shadow` => authenticate against local user db
# `mysql` => authenticate against mysql db
# `rimap` => authenticate against imap server
# Note: can be a list of mechanisms like pam ldap shadow
SASLAUTHD_MECHANISMS=

# empty => None
# e.g. with SASLAUTHD_MECHANISMS rimap you need to specify the ip-address/servername of the imap server  ==> xxx.xxx.xxx.xxx
SASLAUTHD_MECH_OPTIONS=

# empty => Use value of LDAP_SERVER_HOST
# Note: since version 10.0.0, you can specify a protocol here (like ldaps://); this deprecates SASLAUTHD_LDAP_SSL.
SASLAUTHD_LDAP_SERVER=

# empty => Use value of LDAP_BIND_DN
# specify an object with priviliges to search the directory tree
# e.g. active directory: SASLAUTHD_LDAP_BIND_DN=cn=Administrator,cn=Users,dc=mydomain,dc=net
# e.g. openldap: SASLAUTHD_LDAP_BIND_DN=cn=admin,dc=mydomain,dc=net
SASLAUTHD_LDAP_BIND_DN=

# empty => Use value of LDAP_BIND_PW
SASLAUTHD_LDAP_PASSWORD=

# empty => Use value of LDAP_SEARCH_BASE
# specify the search base
SASLAUTHD_LDAP_SEARCH_BASE=

# empty => default filter `(&(uniqueIdentifier=%u)(mailEnabled=TRUE))`
# e.g. for active directory: `(&(sAMAccountName=%U)(objectClass=person))`
# e.g. for openldap: `(&(uid=%U)(objectClass=person))`
SASLAUTHD_LDAP_FILTER=

# empty => no
# yes => LDAP over TLS enabled for SASL
# If set to yes, the protocol in SASLAUTHD_LDAP_SERVER must be ldap:// or missing.
SASLAUTHD_LDAP_START_TLS=

# empty => no
# yes => Require and verify server certificate
# If yes you must/could specify SASLAUTHD_LDAP_TLS_CACERT_FILE or SASLAUTHD_LDAP_TLS_CACERT_DIR.
SASLAUTHD_LDAP_TLS_CHECK_PEER=

# File containing CA (Certificate Authority) certificate(s).
# empty => Nothing is added to the configuration
# Any value => Fills the `ldap_tls_cacert_file` option
SASLAUTHD_LDAP_TLS_CACERT_FILE=

# Path to directory with CA (Certificate Authority) certificates.
# empty => Nothing is added to the configuration
# Any value => Fills the `ldap_tls_cacert_dir` option
SASLAUTHD_LDAP_TLS_CACERT_DIR=

# Specify what password attribute to use for password verification.
# empty => Nothing is added to the configuration but the documentation says it is `userPassword` by default.
# Any value => Fills the `ldap_password_attr` option
SASLAUTHD_LDAP_PASSWORD_ATTR=

# empty => No sasl_passwd will be created
# string => `/etc/postfix/sasl_passwd` will be created with the string as password
SASL_PASSWD=

# empty => `bind` will be used as a default value
# `fastbind` => The fastbind method is used
# `custom` => The custom method uses userPassword attribute to verify the password
SASLAUTHD_LDAP_AUTH_METHOD=

# Specify the authentication mechanism for SASL bind
# empty => Nothing is added to the configuration
# Any value => Fills the `ldap_mech` option
SASLAUTHD_LDAP_MECH=

# -----------------------------------------------
# --- SRS Section -------------------------------
# -----------------------------------------------

# envelope_sender => Rewrite only envelope sender address (default)
# header_sender => Rewrite only header sender (not recommended)
# envelope_sender,header_sender => Rewrite both senders
# An email has an "envelope" sender (indicating the sending server) and a
# "header" sender (indicating who sent it). More strict SPF policies may require
# you to replace both instead of just the envelope sender.
SRS_SENDER_CLASSES=envelope_sender

# empty => Envelope sender will be rewritten for all domains
# provide comma separated list of domains to exclude from rewriting
SRS_EXCLUDE_DOMAINS=

# empty => generated when the image is built
# provide a secret to use in base64
# you may specify multiple keys, comma separated. the first one is used for
# signing and the remaining will be used for verification. this is how you
# rotate and expire keys
SRS_SECRET=

# -----------------------------------------------
# --- Default Relay Host Section ----------------
# -----------------------------------------------

# Setup relaying all mail through a default relay host
#
# empty => don't configure default relay host
# default host and optional port to relay all mail through
DEFAULT_RELAY_HOST=

# -----------------------------------------------
# --- Multi-Domain Relay Section ----------------
# -----------------------------------------------

# Setup relaying for multiple domains based on the domain name of the sender
# optionally uses usernames and passwords in postfix-sasl-password.cf and relay host mappings in postfix-relaymap.cf
#
# empty => don't configure relay host
# default host to relay mail through
RELAY_HOST=

# empty => 25
# default port to relay mail
RELAY_PORT=25

# empty => no default
# default relay username (if no specific entry exists in postfix-sasl-password.cf)
RELAY_USER=

# empty => no default
# password for default relay user
RELAY_PASSWORD=

Now the interesting part, reverse DNS seems to be working just fine.

root@mail:/# dig -x 172.31.0.1

; <<>> DiG 9.16.27-Debian <<>> -x 172.31.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37429
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;1.0.31.172.in-addr.arpa.       IN      PTR

;; ANSWER SECTION:
1.0.31.172.in-addr.arpa. 0      IN      PTR     srv02.
1.0.31.172.in-addr.arpa. 0      IN      PTR     srv02.local.

;; Query time: 0 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Wed Aug 03 22:55:28 CEST 2022
;; MSG SIZE  rcvd: 96

Yet I have to add my docker networks IP to the /etc/hosts file to finally be able to send via an internal IP

127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.31.0.3      mail.example.com mail
fd00:123:4567::3        mail.example.com mail
172.26.0.3      mail.example.com mail
172.31.0.1 mail.example.com mail

Now everthing get's through.

mailserver-mailserver-1  | Aug  3 22:48:39 mail postfix/submission/smtpd[2582]: connect from mail.example.com[172.31.0.1]
mailserver-mailserver-1  | Aug  3 22:48:39 mail opendmarc[1310]: ignoring connection from mail.example.com
mailserver-mailserver-1  | Aug  3 22:48:39 mail postfix/submission/smtpd[2582]: Anonymous TLS connection established from mail.example.com[172.31.0.1]: TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256
mailserver-mailserver-1  | Aug  3 22:48:39 mail postfix/submission/smtpd[2582]: 2A5B936073C: client=mail.example.com[172.31.0.1], sasl_method=LOGIN, [email protected]
mailserver-mailserver-1  | Aug  3 22:48:39 mail postfix/sender-cleanup/cleanup[2752]: 2A5B936073C: message-id=<[email protected]>
mailserver-mailserver-1  | Aug  3 22:48:39 mail postfix/sender-cleanup/cleanup[2752]: 2A5B936073C: replace: header MIME-Version: 1.0 from mail.example.com[172.31.0.1]; from=<[email protected]> to=<[email protected]> proto=ESMTP helo=<mail.example.com>: Mime-Version: 1.0
mailserver-mailserver-1  | Aug  3 22:48:39 mail opendkim[1299]: 2A5B936073C: no signing table match for '[email protected]'
mailserver-mailserver-1  | Aug  3 22:48:39 mail opendkim[1299]: 2A5B936073C: no signature data
mailserver-mailserver-1  | Aug  3 22:48:39 mail postfix/qmgr[2290]: 2A5B936073C: from=<[email protected]>, size=12475, nrcpt=1 (queue active)
mailserver-mailserver-1  | Aug  3 22:48:39 mail postfix/submission/smtpd[2582]: disconnect from mail.example.com[172.31.0.1] ehlo=2 starttls=1 auth=1 mail=1 rcpt=1 data=1 quit=1 commands=8
mailserver-mailserver-1  | Aug  3 22:48:39 mail amavis[2345]: (02345-01) ESMTP [127.0.0.1]:10024 /var/lib/amavis/tmp/amavis-20220803T224839-02345-BdzQtSB3: <[email protected]> -> <[email protected]> SIZE=12475 Received: from mail.example.com ([127.0.0.1]) by localhost (mail.example.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP for <[email protected]>; Wed,  3 Aug 2022 22:48:39 +0200 (CEST)
mailserver-mailserver-1  | Aug  3 22:48:39 mail amavis[2345]: (02345-01) Checking: Y1JMpIymt1UZ [172.31.0.1] <[email protected]> -> <[email protected]>
mailserver-mailserver-1  | Aug  3 22:48:39 mail amavis[2345]: (02345-01) Open relay? Nonlocal recips but not originating: [email protected]
mailserver-mailserver-1  | Aug  3 22:48:40 mail amavis[2762]: (02345-01) SA info: util: setuid: ruid=112 euid=112 rgid=114 114 egid=114 114
mailserver-mailserver-1  | Aug  3 22:48:41 mail amavis[2345]: (02345-01) local delivery: <[email protected]> -> spam-quarantine, mbx=/var/lib/amavis/virusmails/Y/spam-Y1JMpIymt1UZ.gz
mailserver-mailserver-1  | Aug  3 22:48:41 mail postfix/smtpd-amavis/smtpd[2763]: connect from localhost[127.0.0.1]
mailserver-mailserver-1  | Aug  3 22:48:41 mail postfix/smtpd-amavis/smtpd[2763]: 084F136074E: client=localhost[127.0.0.1]
mailserver-mailserver-1  | Aug  3 22:48:41 mail postfix/cleanup[2764]: 084F136074E: message-id=<[email protected]>
mailserver-mailserver-1  | Aug  3 22:48:41 mail postfix/qmgr[2290]: 084F136074E: from=<[email protected]>, size=12678, nrcpt=1 (queue active)
mailserver-mailserver-1  | Aug  3 22:48:41 mail amavis[2345]: (02345-01) Y1JMpIymt1UZ FWD from <[email protected]> -> <[email protected]>, BODY=7BIT 250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as 084F136074E
mailserver-mailserver-1  | Aug  3 22:48:41 mail amavis[2345]: (02345-01) Passed SPAM {RelayedOpenRelay,Quarantined}, [172.31.0.1]:38962 <[email protected]> -> <[email protected]>, quarantine: Y/spam-Y1JMpIymt1UZ.gz, Queue-ID: 2A5B936073C, Message-ID: <[email protected]>, mail_id: Y1JMpIymt1UZ, Hits: 8.106, size: 12441, queued_as: 084F136074E, 1852 ms
mailserver-mailserver-1  | Aug  3 22:48:41 mail postfix/smtp-amavis/smtp[2753]: 2A5B936073C: to=<[email protected]>, relay=127.0.0.1[127.0.0.1]:10024, delay=1.9, delays=0.01/0.01/0.01/1.8, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as 084F136074E)
mailserver-mailserver-1  | Aug  3 22:48:41 mail postfix/qmgr[2290]: 2A5B936073C: removed
mailserver-mailserver-1  | Aug  3 22:48:41 mail postfix/smtp[2765]: Trusted TLS connection established to gmail-smtp-in.l.google.com[74.125.206.27]:25: TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256
mailserver-mailserver-1  | Aug  3 22:48:41 mail postfix/smtp[2765]: 084F136074E: to=<[email protected]>, relay=gmail-smtp-in.l.google.com[74.125.206.27]:25, delay=0.57, delays=0.01/0.01/0.14/0.42, dsn=2.0.0, status=sent (250 2.0.0 OK  1659559721 bz4-20020a056000090400b002186128ce71si1873092wrb.780 - gsmtp)
mailserver-mailserver-1  | Aug  3 22:48:41 mail postfix/qmgr[2290]: 084F136074E: removed

@polarathene
Copy link
Copy Markdown
Member

ipv6nat is using host network mode (I suspected a network was using this mode). This prevents generating it's own /etc/hosts internally and instead mounts the host systems /etc/hosts instead. It may be contributing to the issue?

Your DMS container is only aware of the default and mail network, so only those should show up containers in /etc/hosts I think (I can't quite recall the rules for how the container generates that). But it also looks like default is your ipv6nat host mode network?

@GoliathLabs
Copy link
Copy Markdown
Contributor Author

@polarathene But ipv6nat is only used when IPv6 addresses are involved. Why would it's /etc/hosts file have anything to do with the mail server container and its it's DNS? Why do you think that the default network be the ipv6nat host network? Aren't they two different things (e.g. the default network is created when we start the docker-compose deployment with its separate address space)?

Any recommendations for modifying my docker-compose file?

Thanks in advance 😄

@casperklein
Copy link
Copy Markdown
Member

casperklein commented Aug 4, 2022

I just gave it a try and added reject_unknown_client_hostname to my configuration. I was able to send mails from another container that is on another docker network. Relevant logs:

Details
Aug  5 00:30:48 mail postfix/postscreen[26516]: CONNECT from [192.168.80.1]:39076 to [192.168.80.2]:25
Aug  5 00:30:48 mail postfix/postscreen[26516]: WHITELISTED [192.168.80.1]:39076
Aug  5 00:30:48 mail postfix/smtpd[26517]: connect from unknown[192.168.80.1]
Aug  5 00:30:48 mail opendmarc[2561]: ignoring connection from [192.168.80.1]
Aug  5 00:30:48 mail postfix/smtpd[26517]: D51F628030F5: client=unknown[192.168.80.1]
Aug  5 00:30:48 mail postfix/cleanup[26521]: D51F628030F5: message-id=<1659652248.769693.24423.nullmailer@smokeping>
Aug  5 00:30:48 mail opendkim[2555]: D51F628030F5: no signing table match for '[email protected]'
Aug  5 00:30:48 mail opendkim[2555]: D51F628030F5: no signature data
Aug  5 00:30:48 mail postfix/qmgr[3806]: D51F628030F5: from=<[email protected]>, size=615, nrcpt=1 (queue active)
Aug  5 00:30:48 mail postfix/smtpd[26517]: disconnect from unknown[192.168.80.1] helo=1 mail=1 rcpt=1 data=1 quit=1 commands=5
Aug  5 00:30:50 mail postfix/smtpd-amavis/smtpd[26525]: connect from localhost[127.0.0.1]
Aug  5 00:30:50 mail postfix/smtpd-amavis/smtpd[26525]: 39CB828030F6: client=localhost[127.0.0.1]
Aug  5 00:30:50 mail postfix/cleanup[26521]: 39CB828030F6: message-id=<1659652248.769693.24423.nullmailer@smokeping>
Aug  5 00:30:50 mail postfix/qmgr[3806]: 39CB828030F6: from=<[email protected]>, size=789, nrcpt=1 (queue active)
Aug  5 00:30:50 mail postfix/smtpd-amavis/smtpd[26525]: disconnect from localhost[127.0.0.1] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5
Aug  5 00:30:50 mail amavis[3913]: (03913-04) Passed CLEAN {RelayedInbound}, [192.168.80.1]:39076 <[email protected]> -> <[email protected]>, Queue-ID: D51F628030F5, Message-ID: <1659652248.769693.24423.nullmailer@smokeping>, mail_id: lxosNWmEQxqN, Hits: -2.9, size: 581, queued_as: 39CB828030F6, 1360 ms
Aug  5 00:30:50 mail postfix/smtp-amavis/smtp[26522]: D51F628030F5: to=<[email protected]>, orig_to=<[email protected]>, relay=127.0.0.1[127.0.0.1]:10024], delay=1.4, delays=0.05/0.01/0/1.4, dsn=2.0.0, status=sent (250 2.0.0 from MTA(smtp:[127.0.0.1]:10025): 250 2.0.0 Ok: queued as 39CB828030F6)
Aug  5 00:30:50 mail postfix/qmgr[3806]: D51F628030F5: removed
Aug  5 00:30:50 mail dovecot: lmtp(26527): Connect from local
Aug  5 00:30:50 mail dovecot: lmtp([email protected])<26527><2UMGEppI7GKfZwAAdOYLmw>: msgid=<1659652248.769693.24423.nullmailer@smokeping>: saved mail to INBOX
Aug  5 00:30:50 mail postfix/lmtp[26526]: 39CB828030F6: to=<[email protected]>, relay=mail.example-destination.com[/var/run/dovecot/lmtp], delay=0.28, delays=0.05/0.01/0.01/0.22, dsn=2.0.0, status=sent (250 2.0.0 <[email protected]> 2UMGEppI7GKfZwAAdOYLmw Saved)
Aug  5 00:30:50 mail dovecot: lmtp(26527): Disconnect from local: Logged out (state=READY)
Aug  5 00:30:50 mail postfix/qmgr[3806]: 39CB828030F6: removed

Relevant main.cf lines:

mynetworks = 127.0.0.0/8 [::1]/128 [fe80::]/64 192.168.0.0/16
smtpd_sender_restrictions = reject_authenticated_sender_login_mismatch, permit_sasl_authenticated, permit_mynetworks, reject_unknown_sender_domain, reject_unknown_client_hostname

Real spam seems to be rejected:

postfix/smtpd[8187]: NOQUEUE: reject: RCPT from unknown[194.226.139.78]: 450 4.7.25 Client host rejected: cannot find your hostname, [194.226.139.78]; from=<[email protected]> to=<DELETED> proto=ESMTP helo=<mail.dugul.ru>
postfix/smtpd[15591]: NOQUEUE: reject: RCPT from unknown[45.113.162.2]: 450 4.7.25 Client host rejected: cannot find your hostname, [45.113.162.2]; from=<[email protected]> to=<DELETED> proto=ESMTP helo=<muyehuayi.com>
postfix/smtpd[26412]: NOQUEUE: reject: RCPT from unknown[103.187.147.155]: 450 4.7.25 Client host rejected: cannot find your hostname, [103.187.147.155]; from=<[email protected]> to=<DELETED> proto=ESMTP helo=<newsfast.uk.com>

@polarathene
Copy link
Copy Markdown
Member

Why would it's /etc/hosts file have anything to do with the mail server container and its it's DNS?

/etc/hosts gets populated by connected Docker networks and containers DNS if I recall correctly. Except when using network host mode, this instead copies /etc/hosts from the host system into the container.

Why do you think that the default network be the ipv6nat host network? Aren't they two different things (e.g. the default network is created when we start the docker-compose deployment with its separate address space)?

I could be wrong, it's been a while since I've messed around with Docker networks. You're probably right about ipv6nat container just using the host mode network as separate from the default network.

You've got a lot more going on in your setup, I would simplify it down to bare minimal for using DMS. Create a separate docker-compose.yml using DMS with your change here, that doesn't involve RoundCube, IPv6 and the like. If like @casperklein you no longer have issues, then slowly introduce more of your real config and containers to try find out when it breaks.


Yet I have to add my docker networks IP to the /etc/hosts file to finally be able to send via an internal IP

What was the before state of /etc/hosts?

This doesn't seem right..

172.31.0.3      mail.example.com mail
fd00:123:4567::3        mail.example.com mail
172.26.0.3      mail.example.com mail
172.31.0.1 mail.example.com mail

Doesn't that say mail.example.com should resolve to all those IP? That is not true though, this would be a hacky workaround.

The containers should be authorized to bypass the restriction instead.


mynetworks = 127.0.0.0/8 [::1]/128 [fe80::]/64 127.0.0.0/8 172.26.0.0/16 172.25.0.0/16

Here only 172.26.x.x is permitted, you have 172.31.x.x subnet too (was this originally 172.25.x.x?), and the IPv6 (which container is that?).

Note that you only want to permit IPs from your containers that should be allowed to send mail without auth, I assume ipv6nat is one you would want to specifically restrict such access to avoid an OpenRelay.

Likewise, be careful of proxies that don't carry over the original client info like IP/host, you don't want your container working around a restriction (although I don't think it matters with this rule, which checks client hostname based on mail headers?). There was one user who had an issue with RoundCube getting banned by Fail2Ban because all users were seen as from the same IP (the RoundCube container) when authenticating I think.

Ideally your containers would use SASL auth (587 or 465 port with user + password), not port 25 without auth. If that's acceptable, then mynetworks does not need to list those subnets.

@github-actions github-actions Bot added the meta/stale This issue / PR has become stale and will be closed if there is no further activity label Aug 26, 2022
@GoliathLabs
Copy link
Copy Markdown
Contributor Author

I'll try to do the debugging today

@casperklein
Copy link
Copy Markdown
Member

Update from my setup: Lots of rejected SPAM Mails with 0 false positives so far 👍

@casperklein casperklein removed the meta/stale This issue / PR has become stale and will be closed if there is no further activity label Aug 26, 2022
@docker-mailserver docker-mailserver deleted a comment from github-actions Bot Aug 26, 2022
@GoliathLabs
Copy link
Copy Markdown
Contributor Author

I think I got it. My temporary user-patches.sh script put reject_unkown_client_hostname in the first position in the smtpd_sender_restrictions, which made the internal IPs of the other container fail because of the missing DNS entry, since the reject was put in the main.cf before the permit.

smtpd_sender_restrictions = reject_unknown_client_hostname, reject_unknown_reverse_client_hostname, reject_authenticated_sender_login_mismatch, permit_sasl_authenticated, permit_mynetworks, reject_unknown_sender_domain
disable_vrfy_command = yes

@polarathene
Copy link
Copy Markdown
Member

I'll merge.

My current commitments are delaying time to spare for this project, so the feature PR I've been working on and holding up the next release with may arrive later this month.

If you'd like to release 11.2 before then, I'm ok with that. I'll prepare a release sometime this week as time permits 👍

@polarathene polarathene merged commit 8bc8fc8 into docker-mailserver:master Sep 5, 2022
@polarathene
Copy link
Copy Markdown
Member

Thanks @GoliathLabs for taking the time to look into this and contribute a PR! ❤️

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf
Copy link
Copy Markdown

hello there,

first off, thanks for this wonderful project.

after upgrading from v11.1.0 to v11.2.0 I have found myself unable to receive from google (which I previously have been able to), as represented by the following (irrelevant parts redacted):

Oct 13 18:20:57 host docker-compose[20080]: mailserver-mailserver-1  | Oct 13 18:20:57 mail postfix/smtpd[51726]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-lf1-x130.google.com>
Oct 13 19:30:11 host docker-compose[20080]: mailserver-mailserver-1  | Oct 13 19:30:11 mail postfix/smtpd[64354]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-ej1-x636.google.com>
Oct 13 21:12:56 host docker-compose[20080]: mailserver-mailserver-1  | Oct 13 21:12:56 mail postfix/smtpd[83201]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-ej1-x630.google.com>
Oct 13 22:31:38 host docker-compose[20080]: mailserver-mailserver-1  | Oct 13 22:31:38 mail postfix/smtpd[97655]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-lf1-x134.google.com>
Oct 13 23:57:05 host docker-compose[20080]: mailserver-mailserver-1  | Oct 13 23:57:05 mail postfix/smtpd[113362]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-ed1-x529.google.com>
Oct 14 02:25:33 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 02:25:33 mail postfix/smtpd[140705]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-ej1-x634.google.com>
Oct 14 04:57:48 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 04:57:48 mail postfix/smtpd[168707]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-lf1-x12f.google.com>
Oct 14 07:17:19 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 07:17:19 mail postfix/smtpd[194632]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-lf1-x134.google.com>
Oct 14 07:20:12 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 07:20:12 mail postfix/smtpd[195162]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-lj1-x22e.google.com>
Oct 14 07:26:57 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 07:26:57 mail postfix/smtpd[196407]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-lj1-x233.google.com>
Oct 14 07:47:51 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 07:47:51 mail postfix/smtpd[200275]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-lf1-x136.google.com>
Oct 14 08:29:05 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 08:29:05 mail postfix/smtpd[207832]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-lf1-x12b.google.com>
Oct 14 09:19:24 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 09:19:24 mail postfix/smtpd[217091]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-ej1-x629.google.com>
Oct 14 10:26:33 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 10:26:33 mail postfix/smtpd[229428]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-ej1-x634.google.com>
Oct 14 10:30:34 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 10:30:34 mail postfix/smtpd[230166]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-wr1-x42d.google.com>
Oct 14 11:28:54 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 11:28:54 mail postfix/smtpd[240837]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-ed1-x52d.google.com>
Oct 14 13:16:55 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 13:16:55 mail postfix/smtpd[260676]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-lf1-x131.google.com>
Oct 14 13:36:08 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 13:36:08 mail postfix/smtpd[264297]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-wr1-x434.google.com>
Oct 14 14:34:30 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 14:34:30 mail postfix/smtpd[275053]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-ej1-x62a.google.com>
Oct 14 16:10:13 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 16:10:13 mail postfix/smtpd[292589]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-lf1-x136.google.com>
Oct 14 16:53:46 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 16:53:46 mail postfix/smtpd[300552]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-lj1-x233.google.com>
Oct 14 17:56:03 host docker-compose[20080]: mailserver-mailserver-1  | Oct 14 17:56:03 mail postfix/smtpd[312053]: NOQUEUE: reject: RCPT from unknown[192.168.224.1]: 450 4.7.25 Client host rejected: cannot find your hostname, [192.168.224.1]; from=<from-address> to=<to-address> proto=ESMTP helo=<mail-ej1-x631.google.com>

I am aware it has been posted here earlier that communication with gmail worked for some users (so it did for me, before this change, apparently).

is there any quick way to remedy this?
btw, I have not modified main.cf.

@GoliathLabs GoliathLabs deleted the patch-1 branch October 14, 2022 16:38
@GoliathLabs
Copy link
Copy Markdown
Contributor Author

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf Seems like you are behind a NAT? Because the 192.168.224.1 IP address comes from a private address space and is not the public facing IP of Google's infrastructure

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf
Copy link
Copy Markdown

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf Seems like you are behind a NAT? Because the 192.168.224.1 IP address comes from a private address space and is not the public facing IP of Google's infrastructure

hey! thanks for a quick reply.

perhaps a "docker" kind of NAT? the mailserver is configured with proper public IPs, that's how I was able to receive email before, not sure I follow.
I am running a very simple compose setup.

I am aware the address comes from the private space, although there didn't appear to be any issues with it before. could I provide anything specific to help debug this?

btw I said to myself yolo and for the moment rolled back to the previous version (11.1.0), which immediately allowed me to receive mail from google again, even got some previously rejected messages finally delivered on retry.

@GoliathLabs
Copy link
Copy Markdown
Contributor Author

GoliathLabs commented Oct 14, 2022

That is correct. With this version we check if there is a valid hostname behind the IP. In the previous release, these checks were not executed. Can you provide your mailserver env file and your docker compose file? (omit sensitive values)

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf
Copy link
Copy Markdown

That is correct. With this version we check if there is a valid hostname behind the IP. In the previous release, these checks were not executed. Can you provide your mailserver env file and your docker compose file? (omit sensitive values)

sure:

mailserver.env:

ENABLE_SPAMASSASSIN=1
ENABLE_AMAVIS=0
# info loglevel
AMAVIS_LOGLEVEL=2

# SPAMASSASSIN_SPAM_TO_INBOX=1
SPAMASSASSIN_SPAM_TO_INBOX=0
# a third-party rule-set https://mcgrail.com/template/projects#KAM1, works properly since v11.0.0
ENABLE_SPAMASSASSIN_KAM=1
SA_SPAM_SUBJECT=""
# activate only if confident in bayes db for identifying spam/ham
# SA_SHORTCIRCUIT_BAYES_SPAM=1
# SA_SHORTCIRCUIT_BAYES_HAM=1

ENABLE_POSTGREY=0
# default is 300s
# POSTGREY_DELAY=120
# POSTGREY_DELAY=30
POSTGREY_DELAY=15

ENABLE_CLAMAV=0
ENABLE_FAIL2BAN=1
ENABLE_SASLAUTHD=0
ONE_DIR=1
# DMS_DEBUG=1 # replaced by LOG_LEVEL since v11.0.0
LOG_LEVEL=debug
SUPERVISOR_LOGLEVEL=info
SSL_TYPE=letsencrypt
TLS_TYPE=modern
DOVECOT_DEFAULT_PASS_SCHEME=ARGON2I
SPOOF_PROTECTION=0
ENABLE_SRS=0
ENABLE_MANAGESIEVE=1
ENABLE_UPDATE_CHECK=1
UPDATE_CHECK_INTERVAL=1d
# return 550 SMTP for rejects
# enabled 2022-09-15
POSTSCREEN_ACTION=enforce
# POSTSCREEN_ACTION=ignore
# daily postfix reports
PFLOGSUMM_TRIGGER=daily_cron
LOGWATCH_INTERVAL=weekly

compose file:

version: '3.8'

services:
  mailserver:
    # image: ghcr.io/docker-mailserver/docker-mailserver:latest
    # image: ghcr.io/docker-mailserver/docker-mailserver:10.4.0
    # image: ghcr.io/docker-mailserver/docker-mailserver:10.5.0
    # image: ghcr.io/docker-mailserver/docker-mailserver:11.0.0
    image: ghcr.io/docker-mailserver/docker-mailserver:11.1.0
	# 20220-10-14: issues with receiving from google, rolled back to 11.1.0.
    # image: ghcr.io/docker-mailserver/docker-mailserver:11.2.0
    mem_limit: 256m
    hostname: mail
    domainname: <domain name>
    # To avoid conflicts with yaml base-60 float, DO NOT remove the quotation marks.
    # More information about the mailserver ports:
    # https://docker-mailserver.github.io/docker-mailserver/edge/config/security/understanding-the-ports/
    ports:
      - "25:25"      # SMTP  (explicit TLS => STARTTLS)
      # - "143:143"    # IMAP4 (explicit TLS => STARTTLS)
      - "587:587"    # ESMTP (explicit TLS => STARTTLS)
      - "465:465"    # ESMTP (implicit TLS)
      - "993:993"    # IMAP4 (implicit TLS)
      - "4190:4190"  # sieve
      # - "127.0.0.1:10001:10001"  # SRS
      # - "127.0.0.1:10002:10002"  # SRS
    volumes:
      - /var/lib/mailserver-docker/data/maildata:/var/mail
      - /var/lib/mailserver-docker/data/mailstate:/var/mail-state
      - /var/lib/mailserver-docker/data/maillogs:/var/log/mail
      - /etc/localtime:/etc/localtime:ro
      - /etc/docker-mailserver/config/:/tmp/docker-mailserver/
      # necessary to copy the certs to their location when the below is used,
      # which is done by mailcrts.service regularly, triggered by
      # mailcrts.timer
      - /etc/docker-mailserver/letsencrypt/certs:/etc/letsencrypt/live/<maildomain>:ro
      - /etc/docker-mailserver/config/postfix-policyd-spf.conf:/etc/postfix-policyd-spf-python/policyd-spf.conf

    restart: always
    stop_grace_period: 1m
    # cap_add: [ "NET_ADMIN", "SYS_PTRACE" ]
    # sys_ptrace not needed as of 11.1.0
    cap_add: [ "NET_ADMIN", "SYS_PTRACE" ]
    env_file: /etc/docker-mailserver/mailserver.env

@casperklein
Copy link
Copy Markdown
Member

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf
Copy link
Copy Markdown

wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf commented Oct 15, 2022

Does your host have IPv6 connectivity? That might explain the NAT: https://docker-mailserver.github.io/docker-mailserver/edge/config/advanced/ipv6/

the host does indeed have IPv6 connectivity.

I will try to edit my compose file to have IPv6 work all the way through to the mailserver container, update again, test receiving from G and then report back (hopefully, all will be working then).

thanks for the pointer @casperklein

EDIT: didn't work, still got:

Oct 15 15:27:27 host docker-compose[1083430]: mailserver-mailserver-1  | Oct 15 15:27:27 mail postfix/smtpd[1668]: NOQUEUE: reject: RCPT from unknown[fd00:123:4567::1]: 450 4.7.25 Client host rejected: cannot find your hostname, [fd00:123:4567::1]; from=<[email protected]> to=<toaddress> proto=ESMTP helo=<mail-qk1-x72e.google.com>

may or may not be due to the fact that the host is not in fact using iptables but nftables, ipv6nat container is seen to exit 1 during compose bring-up.

@GoliathLabs
Copy link
Copy Markdown
Contributor Author

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf can you post the log of the ipv6nat container on startup?

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf
Copy link
Copy Markdown

wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf commented Oct 15, 2022

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf can you post the log of the ipv6nat container on startup?

sure, it's restarting ("restart: always"), it's heaps of this:

Oct 15 15:31:44 host docker-compose[1083430]: mailserver-ipv6nat-1     | 2022/10/15 13:31:44 running [/sbin/iptables-t nat -C OUTPUT -m addrtype --dst-type LOCAL -j DOCKER --wait]: exit status 2: iptables v1.8.7 (legacy): Couldn't load target `DOCKER':No such file or directory
Oct 15 15:31:44 host docker-compose[1083430]: mailserver-ipv6nat-1     |
Oct 15 15:31:44 host docker-compose[1083430]: mailserver-ipv6nat-1     | Try `iptables -h' or 'iptables --help' for more information.
Oct 15 15:31:44 host docker-compose[1083430]: mailserver-ipv6nat-1 exited with code 1

a more complete version (after compose restart) - it actually segfaults first:

Oct 15 15:37:09 host docker-compose[1089669]: Container mailserver-ipv6nat-1  Creating
Oct 15 15:37:09 host docker-compose[1089669]: Container mailserver-ipv6nat-1  Created
Oct 15 15:37:09 host docker-compose[1089669]: Container mailserver-mailserver-1  Creating
Oct 15 15:37:09 host docker-compose[1089669]: Container mailserver-mailserver-1  Created
Oct 15 15:37:09 host docker-compose[1089669]: Attaching to mailserver-ipv6nat-1, mailserver-mailserver-1
Oct 15 15:37:09 host docker-compose[1089669]: mailserver-ipv6nat-1     | Segmentation fault (core dumped)
Oct 15 15:37:09 host docker-compose[1089669]: mailserver-ipv6nat-1     | 2022/10/15 13:37:09 running [/sbin/iptables-t nat -C OUTPUT -m addrtype --dst-type LOCAL -j DOCKER --wait]: exit status 2: iptables v1.8.7 (legacy): Couldn't load target `DOCKER':No such file or directory
Oct 15 15:37:09 host docker-compose[1089669]: mailserver-ipv6nat-1     |
Oct 15 15:37:09 host docker-compose[1089669]: mailserver-ipv6nat-1     | Try `iptables -h' or 'iptables --help' for more information.
Oct 15 15:37:10 host docker-compose[1089669]: mailserver-ipv6nat-1 exited with code 0
Oct 15 15:37:10 host docker-compose[1089669]: mailserver-ipv6nat-1     | 2022/10/15 13:37:10 running [/sbin/iptables-t nat -C OUTPUT -m addrtype --dst-type LOCAL -j DOCKER --wait]: exit status 2: iptables v1.8.7 (legacy): Couldn't load target `DOCKER':No such file or directory
Oct 15 15:37:10 host docker-compose[1089669]: mailserver-ipv6nat-1     |
Oct 15 15:37:10 host docker-compose[1089669]: mailserver-ipv6nat-1     | Try `iptables -h' or 'iptables --help' for more information.
Oct 15 15:37:10 host docker-compose[1089669]: mailserver-ipv6nat-1 exited with code 1
Oct 15 15:37:10 host docker-compose[1089669]: mailserver-ipv6nat-1     | 2022/10/15 13:37:10 running [/sbin/iptables-t nat -C OUTPUT -m addrtype --dst-type LOCAL -j DOCKER --wait]: exit status 2: iptables v1.8.7 (legacy): Couldn't load target `DOCKER':No such file or directory
Oct 15 15:37:10 host docker-compose[1089669]: mailserver-ipv6nat-1     |
Oct 15 15:37:10 host docker-compose[1089669]: mailserver-ipv6nat-1     | Try `iptables -h' or 'iptables --help' for more information.
Oct 15 15:37:10 host docker-compose[1089669]: mailserver-ipv6nat-1 exited with code 1

@GoliathLabs
Copy link
Copy Markdown
Contributor Author

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf

Can you try this:

  ipv6nat:
    restart: always
    image: robbertkl/ipv6nat
    privileged: true
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /lib/modules:/lib/modules:ro
    network_mode: "host"

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf
Copy link
Copy Markdown

wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf commented Oct 16, 2022

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf

Can you try this:

  ipv6nat:
    restart: always
    image: robbertkl/ipv6nat
    privileged: true
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /lib/modules:/lib/modules:ro
    network_mode: "host"

thanks, tried it just now. sadly, the result appears to be the same:

Oct 16 22:07:42 host docker-compose[1754468]: Container mailserver-mailserver-1  Created
Oct 16 22:07:42 host docker-compose[1754468]: Attaching to mailserver-ipv6nat-1, mailserver-mailserver-1
Oct 16 22:07:42 host docker-compose[1754468]: mailserver-ipv6nat-1     | Segmentation fault (core dumped)
Oct 16 22:07:42 host docker-compose[1754468]: mailserver-ipv6nat-1     | 2022/10/16 20:07:42 running [/sbin/iptables -t nat -C OUTPUT -m addrtype --dst-type LOCAL -j DOCKER --wait]: exit status 2: iptables v1.8.7 (legacy): Couldn't load target `DOCKER':No such file or directory
Oct 16 22:07:42 host docker-compose[1754468]: mailserver-ipv6nat-1     |
Oct 16 22:07:42 host docker-compose[1754468]: mailserver-ipv6nat-1     | Try `iptables -h' or 'iptables --help' for more information.
Oct 16 22:07:42 host docker-compose[1754468]: mailserver-ipv6nat-1 exited with code 1
Oct 16 22:07:42 host docker-compose[1754468]: mailserver-ipv6nat-1     | 2022/10/16 20:07:42 running [/sbin/iptables -t nat -C OUTPUT -m addrtype --dst-type LOCAL -j DOCKER --wait]: exit status 2: iptables v1.8.7 (legacy): Couldn't load target `DOCKER':No such file or directory
Oct 16 22:07:42 host docker-compose[1754468]: mailserver-ipv6nat-1     |
Oct 16 22:07:42 host docker-compose[1754468]: mailserver-ipv6nat-1     | Try `iptables -h' or 'iptables --help' for more information.
Oct 16 22:07:43 host docker-compose[1754468]: mailserver-ipv6nat-1 exited with code 1
Oct 16 22:07:43 host docker-compose[1754468]: mailserver-ipv6nat-1 exited with code 1
Oct 16 22:07:44 host docker-compose[1754468]: mailserver-ipv6nat-1 exited with code 1
Oct 16 22:07:45 host docker-compose[1754468]: mailserver-ipv6nat-1 exited with code 1
Oct 16 22:07:45 host docker-compose[1754468]: mailserver-mailserver-1  | Restarted supervisord
Oct 16 22:07:45 host docker-compose[1754468]: mailserver-mailserver-1  | 2022-10-16 22:07:45,343 INFO Included extra file "/etc/supervisor/conf.d/saslauth.conf" during parsing
Oct 16 22:07:45 host docker-compose[1754468]: mailserver-mailserver-1  | 2022-10-16 22:07:45,343 INFO Included extra file "/etc/supervisor/conf.d/supervisor-app.conf" during parsing
Oct 16 22:07:45 host docker-compose[1754468]: mailserver-mailserver-1  | 2022-10-16 22:07:45,343 INFO Set uid to user 0 succeeded
Oct 16 22:07:45 host docker-compose[1754468]: mailserver-mailserver-1  | 2022-10-16 22:07:45,344 INFO RPC interface 'supervisor' initialized
Oct 16 22:07:45 host docker-compose[1754468]: mailserver-mailserver-1  | 2022-10-16 22:07:45,345 INFO supervisord started with pid 2
Oct 16 22:07:46 host docker-compose[1754468]: mailserver-mailserver-1  | 2022-10-16 22:07:46,348 INFO spawned: 'mailserver' with pid 25
Oct 16 22:07:46 host docker-compose[1754468]: mailserver-mailserver-1  | [   INF   ]  Welcome to docker-mailserver 11.1.0
Oct 16 22:07:46 host docker-compose[1754468]: mailserver-mailserver-1  | 2022-10-16 22:07:46,419 INFO success: mailserver entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
Oct 16 22:07:46 host docker-compose[1754468]: mailserver-mailserver-1  | [   INF   ]  Initializing setup
Oct 16 22:07:46 host docker-compose[1754468]: mailserver-mailserver-1  | [  DEBUG  ]  Registering functions
Oct 16 22:07:46 host docker-compose[1754468]: mailserver-mailserver-1  | [   INF   ]  Checking configuration
Oct 16 22:07:46 host docker-compose[1754468]: mailserver-mailserver-1  | [  DEBUG  ]  Checking that hostname/domainname is provided or overridden
Oct 16 22:07:46 host docker-compose[1754468]: mailserver-mailserver-1  | [  DEBUG  ]  Domain has been set to <domain redacted>

this is the setup without the mailserver container depending on the ipv6nat container, otherwise you wouldn't see the former starting up at all; but the result is still the same - ipv6nat refuses to work.

I said earlier I was using nftables - it's actually the iptables-compatible version of nftables (I had troubles getting docker working with pure nftables setup, hence this), which makes the whole thing even weirder - it should allow apps to use both "legacy" iptables (which get converted to nftables on the fly) and newer nftables at the same time.

One last thing that came to mind is I am running the compose setup using systemd and in the unit file under the [Service] section I have set the following hardening options, which I can imagine, could hamper what ipv6nat is trying to do:

CapabilityBoundingSet=
SystemCallFilter=~memfd_create
ProtectProc=invisible
ProtectHome=true
RestrictNamespaces=uts ipc pid user cgroup
NoNewPrivileges=True
#SecureBits=noroot-locked
PrivateTmp=true
DevicePolicy=closed
PrivateDevices=true
PrivateUsers=true
ProtectHostname=true
ProtectClock=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectKernelLogs=true
ProtectControlGroups=true
LockPersonality=true
MemoryDenyWriteExecute=true
RestrictRealtime=true
RestrictSUIDSGID=true
SystemCallArchitectures=native

EDIT: alright the issue is definitely not systemd or a lack of privileges - I am running another container that fiddles with iptables, too, and it has been working fine for some time now, it just took my focus in the wrong direction.

the issue is that ip6nat was not able to find the DOCKER target not because of insufficient privileges, but because perhaps there is no such target, really - as the dockerd's iptables calls have been translated to nftables on the fly to who knows what (actually, current ruleset could be viewed using nft list ruleset, but that doesn't necessarily tell us anything we'd need), it would appear that simply trying to manipulate the iptables target as it would under normal circumstances (pure iptables env) doesn't work.

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf
Copy link
Copy Markdown

would one of the solutions be disable ipv6 in postfix? I am willing to sacrifice ipv6 if that allows for a simpler way forward.
I assume that would require sed -i-ing main.cf with user-patches.sh.

@casperklein
Copy link
Copy Markdown
Member

No sed usage needed:

# Choose TCP/IP protocols for postfix to use
# **all** => All possible protocols.
# ipv4 => Use only IPv4 traffic. Most likely you want this behind Docker.
# ipv6 => Use only IPv6 traffic.
#
# Note: More details at http://www.postfix.org/postconf.5.html#inet_protocols
POSTFIX_INET_PROTOCOLS=all
# Choose TCP/IP protocols for dovecot to use
# **all** => Listen on all interfaces
# ipv4 => Listen only on IPv4 interfaces. Most likely you want this behind Docker.
# ipv6 => Listen only on IPv6 interfaces.
#
# Note: More information at https://dovecot.org/doc/dovecot-example.conf
DOVECOT_INET_PROTOCOLS=all

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf
Copy link
Copy Markdown

wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf commented Oct 20, 2022

No sed usage needed:

# Choose TCP/IP protocols for postfix to use
# **all** => All possible protocols.
# ipv4 => Use only IPv4 traffic. Most likely you want this behind Docker.
# ipv6 => Use only IPv6 traffic.
#
# Note: More details at http://www.postfix.org/postconf.5.html#inet_protocols
POSTFIX_INET_PROTOCOLS=all
# Choose TCP/IP protocols for dovecot to use
# **all** => Listen on all interfaces
# ipv4 => Listen only on IPv4 interfaces. Most likely you want this behind Docker.
# ipv6 => Listen only on IPv6 interfaces.
#
# Note: More information at https://dovecot.org/doc/dovecot-example.conf
DOVECOT_INET_PROTOCOLS=all

thanks, that's great.

one last question, though.
the domain that I am sending from/receiving at also works on its own and there exist both A and AAAA records for it.
Q: how will, e.g. Google's mailserver, know where to contact my mailserver without being confused when postfix/dovecot will simply be refusing ipv6?

I feel it would be best if the mail domain was solely used for sending email and not anything else, but I wanted an <address>@<domain> instead of <address>@mail.<domain>...

@casperklein
Copy link
Copy Markdown
Member

casperklein commented Oct 20, 2022

Q: how will, e.g. Google's mailserver, know where to contact my mailserver without being confused when postfix/dovecot will simply be refusing ipv6?

I can imagine, that google will try IPv6 first and if connections cannot be established, it falls back to IPv4. But that's not guaranteed and up to google how they configured their mailserver.

You can use address@domain, but still point your MX record for that domain to mail.domain. That's no problem. If that were not possible, you would need one separate mailserver per domain. That would be crazy.

E.g. you can additional configure address@some-complete-different-domain, and point that domains MX record also to mail.domain.

And for mail.domain just create an A record, to process mail only via IPv4.

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf
Copy link
Copy Markdown

wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf commented Nov 10, 2022

Q: how will, e.g. Google's mailserver, know where to contact my mailserver without being confused when postfix/dovecot will simply be refusing ipv6?

I can imagine, that google will try IPv6 first and if connections cannot be established, it falls back to IPv4. But that's not guaranteed and up to google how they configured their mailserver.

You can use address@domain, but still point your MX record for that domain to mail.domain. That's no problem. If that were not possible, you would need one separate mailserver per domain. That would be crazy.

E.g. you can additional configure address@some-complete-different-domain, and point that domains MX record also to mail.domain.

And for mail.domain just create an A record, to process mail only via IPv4.

thanks @casperklein, that's what I ended up doing in the end. also removed AAAA record for the mail domain and set postfix+dovecot to only work in ipv4 mode. it took a while for the new dmarc records to propagate but now it all works fine, I was even able to upgrade to the new version (11.2.0).
I am now running ipv4-only towards the future! :)

@GoliathLabs
Copy link
Copy Markdown
Contributor Author

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf keep in mind that IPv6 is becoming increasingly dominant across the web. It might be a good idea to look into supporting IPv6 (-only) servers in the future as well.

@wULLSnpAXbWZGYDYyhWTKKspEQoaYxXyhoisqHf
Copy link
Copy Markdown

It might be a good idea to look into supporting IPv6 (-only) servers in the future as well.

fair point, that's right, but until I find a way to run ipv6+nftables+docker that will most likely be a docker-less setup...
¯_(ツ)_/¯

@casperklein
Copy link
Copy Markdown
Member

There might be issues regarding this PR: #2970

@GoliathLabs
Copy link
Copy Markdown
Contributor Author

@casperklein can't replicate the issue on my side

@casperklein
Copy link
Copy Markdown
Member

casperklein commented Jan 4, 2023

Same here, I am just wondering because there are at least two people with same/similar issues. IPv6 may be a factor.
My setup is IPv4 only.

@GoliathLabs
Copy link
Copy Markdown
Contributor Author

Same here, I am just wondering because there are at least two people with same/similar issues. IPv6 may be a factor. My setup is IPv4 only.

But I think it depends on the network setup, as I also use IPv6, but in combination with an IPv6NAT container.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/configuration (file) kind/improvement Improve an existing feature, configuration file or the documentation priority/low service/postfix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FR] Add environment variable to add reject_unknown_reverse_client_hostname & reject_unknown_client_hostname to smtpd_sender_restrictions

5 participants