Description
Most systems only need a mail transfer agent (MTA) to send local notifications (cron output, security alerts) to an administrator. Such an MTA must listen on the loopback interface only, on the SMTP ports 25, 465 and 587.
On Ubuntu the MTA is usually Postfix (inet_interfaces in /etc/postfix/main.cf) or exim4
(dc_local_interfaces in /etc/exim4/update-exim4.conf.conf).
Sendmail, harder to configure safely, must not be installed.
The control applies only when an MTA is installed (/usr/sbin/sendmail exists): Ubuntu installs
none by default. Postfix installed with the "Internet Site" answer listens on every interface;
the exim4 default configuration listens on loopback only. The fix restarts exim4 or Postfix
itself, and only when it changed their configuration.
Rationale
An MTA reachable from the network can be turned into an open relay for spam or phishing, and exposes a complex parser to remote attackers. Local notifications work just as well through the loopback interface.
Impact
The system no longer receives mail from other hosts. Mail servers and relays must exclude this
control in their tailoring file. Removing sendmail-bin also removes packages that depend on
it; install exim4 or Postfix first if the system must still send mail.
Applies when
Detected: when: A mail transfer agent is installed A scanner reports the control not applicable when one is false.
Audit
- Run
ss -Hltn. No socket on port 25, 465 or 587 may be bound to an address other than127.0.0.0/8or::1. - Run
dpkg-query -W -f='${Status}\n' sendmail-bin. It must not printinstall ok installed.
Automated: every check must pass. Scanners report each check by its id.
loopback-only
SMTP ports are bound to loopback addresses only.
script: |
command -v ss >/dev/null 2>&1 || { echo "ss not found"; exit 3; }
o=$(ss -Hltn 2>/dev/null | awk '{ print $4 }' | grep -E ':(25|465|587)$' |
grep -Ev '^(127\.[0-9.]+(%[a-z0-9]+)?|\[::1\]|\[::ffff:127\.[0-9.]+\]):')
if [ -n "$o" ]; then
echo "SMTP listening on:" $o
exit 1
fi
echo "no SMTP port bound outside loopback"
sendmail
Sendmail MTA package.
name: sendmail-bin
state: absent
Remediation
- exim4: set
dc_local_interfaces='127.0.0.1 ; ::1'in/etc/exim4/update-exim4.conf.conf, then runupdate-exim4.confandsystemctl restart exim4. - Postfix: run
postconf -e 'inet_interfaces = loopback-only'thensystemctl restart postfix. - Sendmail: install exim4 or Postfix, then
apt purge sendmail-bin.
| Restart | none |
| Disruption | low |
Rollback
Restore the configuration file from the backup directory, then run update-exim4.conf and
restart the MTA.
loopback-only
# Bind the local MTA (exim4 or Postfix) to the loopback interface only.
# Idempotent: each MTA is changed and restarted only when its setting differs.
rc=0
f=/etc/exim4/update-exim4.conf.conf
want="dc_local_interfaces='127.0.0.1 ; ::1'"
if [ -f "$f" ] && ! grep -qxF "$want" "$f"; then
cb_backup "$f"
if grep -q '^dc_local_interfaces=' "$f"; then
sed -i "s/^dc_local_interfaces=.*/$want/" "$f"
else
printf '%s\n' "$want" >>"$f"
fi
if update-exim4.conf; then
systemctl try-restart exim4.service || rc=1
else
cb_restore "$f"
echo "update-exim4.conf failed, reverted $f" >&2
rc=1
fi
fi
if command -v postconf >/dev/null 2>&1 && [ -f /etc/postfix/main.cf ] &&
[ "$(postconf -h inet_interfaces)" != loopback-only ]; then
cb_backup /etc/postfix/main.cf
postconf -e 'inet_interfaces = loopback-only' || rc=1
systemctl try-restart postfix.service || rc=1
fi
exit "$rc"
sendmail
Generated from check sendmail: the engine writes the fix for every output, it sets the expected value and the check runs again after.
Handwritten code reads parameters from CB_<NAME> environment variables. Each release turns these fixes into remediate.sh and an Ansible role per profile: dry run by default, a fix runs only when its check fails.
References
- update-exim4.conf(8), Ubuntu manual pages Canonical, vendor-doc, accessed 2026-10-19
- postconf(5), Ubuntu manual pages Canonical, vendor-doc, accessed 2026-10-19
- Ubuntu Server documentation - How to install and configure Postfix Canonical, vendor-doc, accessed 2026-10-19
- ANSSI-BP-028 v2.0 - Recommandations de configuration d'un système GNU/Linux (R62, R74) ANSSI, guide, accessed 2026-10-19
Mappings
| Framework | ID | Relation | Note |
|---|---|---|---|
| ANSSI-BP-028 - Recommandations de configuration d'un système GNU/Linux2.0 | R74 | equivalent | |
| ANSSI-BP-028 - Recommandations de configuration d'un système GNU/Linux2.0 | R62 | partial | Covers the removal of Sendmail only. |
| NIST SP 800-53 Rev. 55.1.1 | CM-7 | partial |
How this control relates to the other framework's: equivalent, stricter, looser, partial or related.
Threats mitigated
| Taxonomy | ID |
|---|---|
| MITRE ATT&CK | T1210 |
| MITRE ATT&CK | T1090 |
People and lifecycle
| Authors |
|
| Verified | 2026-10-19 by Sn0wAlice on 20.04, Proxmox VM, Ubuntu 20.04 cloud image, kernel 5.4.0-216-generic. Not applicable on the stock image (no MTA); Postfix installed as Internet Site listens on 0.0.0.0:25 and fails, fix sets inet_interfaces = loopback-only and restarts it, audit passes after reboot. |
| Verified | 2026-10-19 by Sn0wAlice on 22.04, Proxmox VM, Ubuntu 22.04 cloud image, kernel 5.15.0-198-generic. Not applicable on the stock image (no MTA); Postfix installed as Internet Site listens on 0.0.0.0:25 and fails, fix sets inet_interfaces = loopback-only and restarts it, audit passes after reboot. |
| Verified | 2026-10-19 by Sn0wAlice on 24.04, Proxmox VM, Ubuntu 24.04 cloud image, kernel 6.8.0-147-generic. Not applicable on the stock image (no MTA); Postfix installed as Internet Site listens on 0.0.0.0:25 and fails, fix sets inet_interfaces = loopback-only and restarts it, audit passes after reboot. |
| Verified | 2026-10-19 by Sn0wAlice on 26.04, Proxmox VM, Ubuntu 26.04 cloud image, kernel 7.0.0-38-generic. Not applicable on the stock image (no MTA); Postfix installed as Internet Site listens on 0.0.0.0:25 and fails, fix sets inet_interfaces = loopback-only and restarts it, audit passes after reboot. |
| Introduced in | v0.1.0 |
| Created, updated | 2026-10-19, 2026-10-19 |
| Translations | fr |