Docker: how to use postfix from host

Hello,

I’ve installed Nextcloud using the official docker image.
Now I want to use the postfix from the host to relay the mails from the docker container. I’ve used this guide to change configuration to expose postfix to the Docker network, but so far I haven’t been able to send mails from Nextcloud (fyi: It is working on the host).

This is what I’ve done:

/etc/postfix/main.cfg

mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 172.17.0.0/16 192.168.32.0/20
mailbox_command = procmail -a "$EXTENSION"
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = 172.17.0.1
inet_protocols = ipv4


# specify SMTP relay host
relayhost = smtp.mail.yahoo.com:587
# enable SASL authentication
smtp_sasl_auth_enable = yes
# disallow methods that allow anonymous authentication.
smtp_sasl_security_options = noanonymous
# where to find sasl_passwd
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
# Enable STARTTLS encryption
smtp_use_tls = yes
# where to find CA certificates
smtp_tls_CAfile = /etc/ssl/certs/ca-certificates.crt
# change sender mail address
sender_canonical_maps = regexp:/etc/postfix/sender_canonical

inet_interfaces = the IP address of docker0 interface using command ifconfig
mynetworks = 192.168.32.0/20 : the subnet used by my Nextcloud docker container

Here are the mail settings in config.php from Nextcloud:

  'mail_domain' => 'yahoo.com',
  'mail_from_address' => 'my.cloud',
  'mail_smtpmode' => 'smtp',
  'mail_sendmailmode' => 'smtp',
  'mail_smtpport' => '25',
  'mail_smtphost' => '127.0.0.1',

I’m having 2 questions:

  1. which IP should I use for mail_smtphost ? I’ve tried with localhost, private IP of nextcloud container, private IP of the host…

  2. Should I expose port 25 from the host to the container (e.g. docker run -p 25:25 )?

Any help is appreciated

thanks

FYI:I’ve also opened port 25 on the host in iptables

it doesn’t work this way -p 25:25 maps port 25 of the container to the port 25 of the host - which obviously doesn’t work as it is used already (most likely your container doesn’t start with such setting)

localhost and private IP/fqdn of the container are the same (settings are applied to the the container, so all IPs and hostnames are from the container point of view). the right setting would be IP/fqdn of the host. According to the tutorial you referenced:

Instead of providing the known SMTP server’s IP and host, one should use the IP of docker0, as explained above. In the case of many nodes in Kubernetes cluster with different docker0 IP, the Docker container of Jenkins master should reside only on one host and docker0’s IP on that host should be used.

you need to your 172.x.x.x address of the docker0 interface (previously configure postfix to listen on this interface as well) - see "Modified “/etc/postfix/main.cf” in your tutorial

inet_interfaces = localhost, 172.22.91.1

I remember there are restrictions in place when docker container talks to the host but don’t have any reference now… try searching for "docker container access host ip"or similar…

Indeed, I totally overlooked this. Oddly, I tried it before and my container did start without any warning that the port was already in use.

After some testing using nmap in the container I figured out I could use the IP address of docker0 to send mail (Note: you can also use the private IP of the host but for this you first need to add this IP to the inet_interfaces in main.cf - but it doesn’t make any difference)

Anyway I can now send test mails from my Nextcloud instance.
However: when sharing a file or adding a note I got the following error in mail.log:

Apr  8 15:47:28  postfix/smtpd[3227107]: connect from unknown[172.24.0.3]
Apr  8 15:47:28  postfix/smtpd[3227107]: 24BACFD9B4: client=unknown[172.24.0.3]
Apr  8 15:47:28  postfix/cleanup[3227111]: 24BACFD9B4: message-id=<32ced750fc384e5a246175adf17184dc@my.cloud>
Apr  8 15:47:28  postfix/qmgr[3227061]: 24BACFD9B4: from=<my.cloud@yahoo.com>, size=20673, nrcpt=1 (queue active)
Apr  8 15:47:28  postfix/smtpd[3227107]: disconnect from unknown[172.24.0.3] ehlo=1 mail=1 rcpt=1 data=1 quit=1 commands=5
Apr  8 15:47:30  postfix/smtp[3227112]: 24BACFD9B4: to=<recipient@gmail.com>, relay=smtp.mail.yahoo.com[74.6.228.44]:587, delay=2.2, delays=0.01/0.02/1.9/0.32, dsn=5.0.0, status=bounced (host smtp.mail.yahoo.com[74.6.228.44] said: 550 Request failed; Mailbox unavailable (in reply to end of DATA command))
Apr  8 15:47:30  postfix/cleanup[3227111]: 5DFB9FD9B6: message-id=<20220408134730.5DFB9FD9B6@.mynet.oraclevcn.com>
Apr  8 15:47:30  postfix/bounce[3227113]: 24BACFD9B4: sender non-delivery notification: 5DFB9FD9B6
Apr  8 15:47:30  postfix/qmgr[3227061]: 5DFB9FD9B6: from=<my.cloud@yahoo.com>, size=22894, nrcpt=1 (queue active)
Apr  8 15:47:30  postfix/qmgr[3227061]: 24BACFD9B4: removed

(FYI: 172.24.0.3 is the IP of the nextcloud container)

This is very similar to the error I got last year using the same mail provider (yahoo) but using SMTP directly to yahoo.

It does seems strange to my as an 550 error means that the mailbox of the recipient does not exist, but this is not the case here obviously. How can I solve this, or should I create a separate post for this?

I have no idea about postfix but the following log

looks for me like you postfix accepted the message and forwarded it to yahoo, which in turn rejected the message (most likely to avoid open relay). I assume your postfix tried to send the message to yahoo without authentication…

According to this post - yahoo doesn’t like certain Reply To headers.

I’ve compared my mail headers, see below:

Test mail (=OK)

Received: from mycloud.com (unknown [172.24.0.3])
	by myserver.oraclevcn.com (Postfix) with ESMTP id 008BAFD996
	for <nextcloudadmin@gmail.com>; Fri,  8 Apr 2022 16:19:29 +0200 (CEST)
Message-ID: <46a2ffd86aa4b51d6466488bc3e7f1d6@mycloud.com>
Subject: Mail test
From: My Cloud <my.cloud@yahoo.com>
To: admin <nextcloudadmin@gmail.com>
MIME-Version: 1.0
Content-Type: multipart/alternative;
 boundary="_=_swift_1649427569_1118be7e5e0306759d8028d78f8e50b2_=_"
X-SMTP-MAILFROM: my.cloud@yahoo.com
X-SMTP-RCPTTO: nextcloudadmin@gmail.com
References: <46a2ffd86aa4b51d6466488bc3e7f1d6.ref@mycloud.com>
X-Mailer: WebService/1.1.20001 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo
Content-Length: 15170

Share by mail (bounced with 550 error)

Return-Path: <my.cloud@yahoo.com>
Received: from mycloud.com (unknown [172.24.0.3])
	by myserver.oraclevcn.com (Postfix) with ESMTP id 24BACFD9B4
	for <user@gmail.com>; Fri,  8 Apr 2022 15:47:28 +0200 (CEST)
Message-ID: <32ced750fc384e5a246175adf17184dc@mycloud.com>
Date: Fri, 08 Apr 2022 13:47:28 +0000
Subject: "admin" voegde een notitie toe aan een bestand dat met jou is
 gedeeld
From: admin via My Cloud <my.cloud@yahoo.com>
Reply-To: admin <nextcloudadmin@gmail.com>
To: admin@gmail.com
MIME-Version: 1.0
Content-Type: multipart/alternative;
 boundary="_=_swift_1649425648_db2e47324bf516359e593dd241515197_=_"

In the failed mail I do see a Reply-To mailadres which is different than the mail that the mail is send from. Maybe this causes the 550 mailbox unavailable error?
If so, this could be possibly solved by adding a fixed Reply-To header with the nextcloud mailadres (in my example my.cloud@yahoo.com)?
(I don’t know whether this is possible but I assume it is)

Edit:
I’ve checked with my other Nextcloud instance which is installed natively and also uses postfix.
When sending a mail by share by mail I notice that the Reply-To is indeed the mailadres used by Nextcloud to send the mails (instead of the mailadres of the user sharing the file. Thus guess the solution is indeed to somehow change the Reply-To headers?

Date: Fri, 08 Apr 2022 18:26:57 +0000
Subject: share by mail
From: user via Other-Cloud <other.cloud@yahoo.com>
Reply-To: user <other.cloud@yahoo.com>
To: otheruser@hotmail.com
MIME-Version: 1.0
Content-Type: multipart/alternative;
 boundary="_=_swift_1649442417_0990c404215067f6fb0cde319f5552bb_=_"
References: <0de5c8a424b825165d7ef13378e1ba40.ref@wouter.servebeer.com>
X-Mailer: WebService/1.1.20001 mail.backend.jedi.jws.acl:role.jedi.acl.token.atz.jws.hermes.yahoo
Content-Length: 19904

Edit 2:
Seems that I was right. I used this to replace my Reply-To headers in my mail with the Nextcloud-mail address & now I don’t receive any 550 error anymore but 250 OK :slight_smile:
Only downside is that the mails are delivered to the spam box from the recipient, but guess this is due to the nature of the automatically send mail.

I’ll send another post with the full solution of my 2 problems, guess it can help others who are using free mail services.

kr

OK so here is what I’ve done to make postfix listen to my docker container:
add/change the following lines to /etc/postfix/main.cfg:

  • mynetworks = add the IP address range of your nextcloud docker container e.g. 172.24.0.0/16

Tip: add the folowing to your docker-compose.yml to add a static IP address subnet to your docker container:

networks:
  nextcloud_network:
    ipam:
      config:
       - subnet: 172.24.0.0/16
  • inet_interfaces = add the IP address of your docker0 interface e.g. 172.17.0.1
    (user ip addr show of ifconfig and note the IP address corresponding to docker0, you don’t need to enter the mask e.g. /16)

Then restart your postfix service (e.g. sudo service postfix restart). If you have a firewall like ufw or iptables active, make sure you add rules to accept connections from your Nextcloud container IP to port 25.

Now you can add add the following to your Nextcloud config.php:

  'mail_domain' => 'mail.com',
  'mail_from_address' => 'my.cloud',
  'mail_smtpmode' => 'smtp',
  'mail_sendmailmode' => 'smtp',
  'mail_smtpport' => '25',
  'mail_smtphost' => '172.17.0.1', //the IP address of docker0

For server address use the IP address of your docker0 interface and all should work