Subject: postfix: Smarthost set up

From: Osamu Aoki <[email-masked]>
Date: Sun, 11 Nov 2007 01:25:03 +0900

Package: postfix
Version: 2.4.6-1
Severity: normal

Short report:
Please do not set 'myorigin = /etc/mailname' at least for 
"Internat with smarthost".  This may cause root mail etc. to be sent
outside unless user checks result of debconf carefully.

Long report:

"postfix/main_mailer_type" has 5 possible values:
  No configuration:
   Should be chosen to leave the current configuration unchanged.
  Internet site:
   Mail is sent and received directly using SMTP.
  Internet with smarthost:
   Mail is received directly using SMTP or by running a utility such
   as fetchmail. Outgoing mail is sent using a smarthost.
  Satellite system:
   All mail is sent to another machine, called a 'smarthost', for delivery.
  Local only:
   The only delivered mail is the mail for local users. There is no network.

So natuarally, except for "Satellite system", I expect no system mail to
be forwarded to smarthost in default set up.

Since policy states, /etc/mailname to be:
---
Such package should check for the existence of this file when it is being
configured. If it exists, it should be used without comment, although an MTA's
configuration script may wish to prompt the user even if it finds that this
file exists. If the file does not exist, the package should prompt the user for
the value (preferably using debconf) and store it in /etc/mailname as well as
using it in the package's configuration. The prompt should make it clear that
the name will not just be used by that package. For example, in this situation
the inn package could say something like:

     Please enter the "mail name" of your system.  This is the
     hostname portion of the address to be shown on outgoing
     news and mail messages.  The default is
     syshostname, your system's host name.  Mail
     name ["syshostname"]:

where syshostname is the output of hostname --fqdn. 
---

I expect the value in this /etc/mailname to be used for *outgoing* news
and mail messages.  For "Internet with smarthost", I expect to use such
address as ISP "pacbell.com" or forwarding address "debian.org".  All
local mail such as ones to root end up in local host.

When postfix "Template: postfix/mailname" asked me without *outgoing*:
---
Description: System mail name:
 The "mail name" is the domain name used to "qualify" mail addresses
 without a domain name.
 .
 This name will also be used by other programs. It should be the
 single, fully qualified domain name (FQDN).
 .
 Thus, if a mail address on the local host is [email-masked],
 the correct value for this option would be example.org.
---

I have only one account with matching my debian account name on this
machine where outgoing mail is generated.  Naturally I put "debian.org"
in this question instead of $(hostname --fqdn). This set up
/etc/mailname to "debian.org" and set 'myorigin = /etc/mailname'.  (This
is normal reaction by many home users without domain registration etc.
using smarthost set up behind the broad band router.)

Then, when "postfix/destinations" asked me:
---
Description: Other destinations to accept mail for (blank for none):
 Please give a comma-separated list of domains for which this machine
 should consider itself the final destination. If this is a mail
 domain gateway, you probably want to include the top-level domain.
---
Although "debian.org" was included in the list, I eliminated it since I do not 
want mails to my fellow DD end up in my machine as undelivarable.

Alas, this seemingly normal system end up with very bad situation.  Some cron
job message to root was sent out to my smarthost and to "[email-masked]".

I understand 
 * what you ask in debconf and 
 * what you setup as "myorigin = /etc/mailname" 
match up.  So I should have placed "localhost" or $(hostname --fqdn)
which was "snoopy.invalid" in my case into the query.  

I think postfix should follow policy for /etc/mailname.  I should be
able to set it to my ISP or debian.org wthout problem.

The valid return address is required to get mail delivered over spam
prevention.  (As everyone knows these days, such invalid mail address
will be rejected by many MTA.) For this end, generic(5) serves address
rewriting for outgoing mail for postfix.

I think, at least for "Internet site" and "Internet with smarthost",  we
should set up "myorigin" as either one of:
 # postconf -e "myorigin = $(hostname --fqdn)"
or
 # postconf -e 'myorigin = localhost'

Then in my case by manual configuration for postfix 2.3:
 # vim /etc/postfix/generic
 ... make table
 # postmap /etc/postfix/generic
 # postconf -e 'smtp_generic_maps = hash:/etc/postfix/generic'

Since this is a bit too complicated for installation script, I suggest
something along following script to generate /etc/postfix/generic after
setting /etc/mailname with policy compliant quesry with *outgoing* in
the postinst (after checking file alteration, main.cf sanity check etc.)
---
cat >/etc/postfix/generic <<EOF
# This is debconf generated address rewriting routine for outgoing mail
# If you want to set up more fine grained rewriting rule, please read
# generic(5).
# Please indicate below by substituting No to Yes if you edit this:
# Manual_change = No
/^\\([^@]*\\)\$/x \$1@$(cat /etc/mailname)
/^\\([^@]*\\)@.*\$/x \$1@$(cat /etc/mailname)
EOF
---
(I hope my escaping was OK for '\'s .)

Then set up postfix (main.cf) with:
 # postconf -e 'smtp_generic_maps = regrex:/etc/postfix/generic'

This is a bit complicated and I think there may be simpler way to
prevent local mail to go outside, this at least gave me sane system.

When you do this, please consider to include /etc/postfix/sasl_passwd
with dummy contents:
---
# Please read (postfix-doc package) /usr/share/doc/postfix/SASL_README.gz
# under "Enabling SASL authentication in the Postfix SMTP client" for
# details.  Run postmap(5) after updating this file.
# Format:
#[targetmailserver.example]      login:password
#[targetmailserver.example]:587  login:password
#
---

I think this smarthost fix is needed to get postfix to be real
alternative to exim4 :-)

FYI:
In case of exim4, they use /etc/email-addresses for fine grained
outgoing mail address rewrining.  But that was not needed if
/etc/mailname was set to some valid mail domain name as long as you use
one mail domain for all accounts.  All local mail was delivered without
problem.

-- System Information:
Debian Release: lenny/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: amd64 (x86_64)

Kernel: Linux 2.6.22-3-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages postfix depends on:
ii  adduser                  3.105           add and remove users and groups
ii  debconf [debconf-2.0]    1.5.16          Debian configuration management sy
ii  dpkg                     1.14.7          package maintenance system for Deb
ii  libc6                    2.6.1-6         GNU C Library: Shared libraries
ii  libdb4.6                 4.6.21-4        Berkeley v4.6 Database Libraries [
ii  libsasl2-2               2.1.22.dfsg1-16 Cyrus SASL - authentication abstra
ii  libssl0.9.8              0.9.8g-2        SSL shared libraries
ii  lsb-base                 3.1-24          Linux Standard Base 3.1 init scrip
ii  netbase                  4.30            Basic TCP/IP networking system
ii  ssl-cert                 1.0.14          Simple debconf wrapper for openssl

postfix recommends no packages.

-- debconf information:
* postfix/mailname: localhost
  postfix/tlsmgr_upgrade_warning:
* postfix/relayhost: [vsmtp.mb.point.ne.jp]:587
* postfix/procmail: true
  postfix/bad_recipient_delimiter:
* postfix/rfc1035_violation: false
* postfix/mynetworks: 127.0.0.0/8
* postfix/protocols: all
* postfix/recipient_delim: +
* postfix/main_mailer_type: Internet with smarthost
  postfix/kernel_version_warning:
* postfix/chattr: false
* postfix/root_address:
  postfix/mydomain_warning:
* postfix/destinations: snoopy.invalid, localhost.invalid, localhost
  postfix/not_configured:
* postfix/mailbox_limit: 0

---

From: Osamu Aoki <[email-masked]>
Date: Sun, 11 Nov 2007 03:06:14 +0900

Hi,

Just to follow up, ..

Frst, my script example used "cat" for /etc/mailname.  Since it may contain
comments, I guess 
$(grep -m1 -v -e '^#' -e '^ *$' /etc/mailname)
may have been better.

I checked how popular to assume /etc/mailname not being localhost but ISP or
debian.org like FQDN on debian system, I checked my system and found folowing
scrips uses it to get mailname and expect somethig more like debian.org there:

Binary file /usr/bin/mutt matches
/usr/bin/dch:   if (open MAILNAME, '/etc/mailname') {
/usr/bin/debchange:     if (open MAILNAME, '/etc/mailname') {
/usr/bin/dh_make:    if ( -e '/etc/mailname'){
/usr/bin/dh_make:      chomp($mailhost = `cat /etc/mailname`);
Binary file /usr/bin/makeinfo matches
/usr/lib/pbuilder/pbuilder-modules:     hostname -f > "$BUILDPLACE/etc/mailname"
/usr/lib/gettext/user-email:# Some Debian systems have a file /etc/mailname.
/usr/lib/gettext/user-email:if test -r /etc/mailname; then
/usr/lib/gettext/user-email:  hostmailname=`cat /etc/mailname`
/etc/emacs/site-start.d/00debian-vars.el:(defun debian-clean-mailname ()
/etc/emacs/site-start.d/00debian-vars.el:;; policy/ch4.html, 4.3 Mail processing on Debian systems, /etc/mailname
/etc/emacs/site-start.d/00debian-vars.el:(let ((mailname
/etc/emacs/site-start.d/00debian-vars.el:       (debian-file->string "/etc/mailname" (function debian-clean-mailname))))
/etc/emacs/site-start.d/00debian-vars.el:  (if (not mailname)
/etc/emacs/site-start.d/00debian-vars.el:      (message "No /etc/mailname. Reverting to default...")
/etc/emacs/site-start.d/00debian-vars.el:    (setq mail-host-address mailname)))
/etc/Muttrc:# set the default here. (better: fix /etc/mailname)

I am quite annoyed after changing /etc/mailname to "localhost" and now
changing "myorigin = localhost" and set /etc/mailname back to "debian.org"  
This way I can run devscripts as it used to be in exim4.

Now, I should get proper e-mail address in my changelog :-)

Osamu

---

From: LaMont Jones <[email-masked]>
Date: Fri, 4 Jan 2008 07:06:49 -0700

> outside unless user checks result of debconf carefully.

Postfix has no concept of whether mail is leaving the machine or not at
the point where address rewriting is being done.  That is, all mail is
_outgoing_ in postfix's opinion.

See sender_canonical_maps and recipient_canonical_maps for how to deal
with using some other domain as the default for the domain on outgoing
mail.

The bug here is quite possibly that postfix's install doesn't make
dealing with a machine that needs to tweak myorigin (usually because
it's not in the DNS for the rest of the internet) easier.

lamont

---

From: Michael Prokop <[email-masked]>
Date: Mon, 7 Mar 2022 16:00:51 +0100

Hi,

> it's not in the DNS for the rest of the internet) easier.

I recently stumbled upon a related issue, where a system had a
static IP configuration, but its search path wasn't configured.
systemd-resolved uses "search ." then, and installation of postfix
fails with such a setup.

Steps to reproduce:

| root@grml ~ # hostname
| grml
| root@grml ~ # hostname --fqdn
| grml
| root@grml ~ # grep '^search' /etc/resolv.conf
| search .
| root@grml ~ # apt install postfix
| [...]
| Creating /etc/postfix/dynamicmaps.cf
| Adding group `postdrop' (GID 125) ...
| Done.
| setting myhostname: grml..
| setting alias maps
| setting alias database
| mailname is not a fully qualified domain name.  Not changing /etc/mailname.
| setting destinations: $myhostname, grml, localhost.localdomain, , localhost
| setting relayhost: 
| setting mynetworks: 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
| setting mailbox_size_limit: 0
| setting recipient_delimiter: +
| setting inet_interfaces: all
| setting inet_protocols: all
| /etc/aliases does not exist, creating it.
| WARNING: /etc/aliases exists, but does not have a root alias.
|
| Postfix (main.cf) is now set up with a default configuration.  If you need to 
| make changes, edit /etc/postfix/main.cf (and others) as needed.  To view 
| Postfix configuration values, see postconf(1).
|
| After modifying main.cf, be sure to run 'systemctl reload postfix'.
|
| Running newaliases
| newaliases: warning: valid_hostname: misplaced delimiter: grml..
| newaliases: fatal: file /etc/postfix/main.cf: parameter myhostname: bad parameter value: grml..
| dpkg: error processing package postfix (--configure):
|  installed postfix package post-installation script subprocess returned error exit status 75
| [...]

The generated "grml.." setting for postfix's myhostname
configuration is invalid and rejected by e.g. postfix's newaliases.

This is caused by postfix's postinst script, which includes this:

| myfqdn() {
|     myhostname=$(hostname --fqdn 2>/dev/null || echo "")
|     # If we don't have a name with a dot (which includes ""), then we have work.
|     if [ $myhostname = ${myhostname%.*} ]; then
|         # If it's empty, and we have /etc/hostname, try that.
|         if [ -z $myhostname ] && [ -r /etc/hostname ]; then
|             myhostname=$(cat /etc/hostname)
|         fi
|         # If we are still lacking a domain component, then try resolv.conf.
|         if [ $myhostname = ${myhostname%.*} ]; then
|             if [ -f /etc/resolv.conf ]; then
|                 # The resolver uses the last one found, and ignores the rest
|                 mydom=$(sed -n 's/^search[[:space:]]*\.*\([^[:space:]]*\).*/\1/p;s/^domain[[:space:]]*\.*\([^[:space:]]*\).*/\1/p' /etc/resolv.conf | tail -1)
|                 myhostname="$myhostname${mydom:+.${mydom%.}}"
|             else
|                 myhostname="$myhostname.UNKNOWN"
|             fi
|         fi
|     fi
|     echo $myhostname
| }

regards
-mika-