Hide Postfix SMTP Banner Software Name
Strip the software identity from the SMTP greeting by setting smtpd_banner = $myhostname ESMTP. The distribution default ($myhostname ESMTP $mail_name (Ubuntu)) announces the MTA product, and often the packaging, to every anonymous client that opens a connection to port 25: that is free reconnaissance, letting an attacker match your MTA against a list of known vulnerabilities before sending a single command.
Checked against the resolved running state (e.g. sshd -T, sysctl, systemctl show), catches drop-ins and Includes a file read would miss. Caveat: runtime ≠ persistence; a value correct now may not survive a reboot.
What Pavois checks
Pavois reads the effective banner with postconf -h smtpd_banner and fails if it still contains mail_name. postconf -h prints the value Postfix resolved, after main.cf and the built-in defaults, with the $mail_name variable left unexpanded: its mere presence in the template is what leaks the product name at connection time. When postconf is absent (Postfix not installed) the control returns ok.
describe command('if ! command -v /usr/sbin/postconf >/dev/null 2>&1; then echo ok; elif /usr/sbin/postconf -h smtpd_banner 2>/dev/null | grep -qi mail_name; then echo ko; else echo ok; fi') do
its('stdout.strip') { should eq 'ok' }
endHow to verify it is applied
Read the resolved template, then the greeting a real client sees:
postconf -h smtpd_banner # expected: $myhostname ESMTP
printf 'QUIT\r\n' | nc localhost 25
The greeting must read 220 host.example.org ESMTP, with no product name, version or distribution tag after ESMTP.
Inspect & investigate
journalctl -u postfix (or /var/log/mail.log, /var/log/maillog on RHEL) records the reload that applies the new banner, and every subsequent connect from line. Banner-grabbing scans show up there as a burst of connections that disconnect right after the greeting, without ever issuing MAIL FROM.
Remediation
Pavois runs the postfix-banner step: postconf -e 'smtpd_banner = $myhostname ESMTP', with a de-duplicating sed plus append as the fallback when postconf is missing, followed by a Postfix reload. A not_if guard skips the step once main.cf declares a banner free of mail_name, keeping confkit harden apply idempotent. $myhostname is deliberately kept: RFC 5321 expects the greeting to carry the server's fully qualified name, and several anti-spam checks reject a greeting that does not.
Pavois applies this with its own harden engine, the plan below, not a shell script:
| command | mkdir -p /etc/postfix; touch /etc/postfix/main.cf; if command -v postconf >/dev/null 2>&1; then postconf -e 'smtpd_banner = $myhostname ESMTP'; else sed -ri '/^smtpd_banner/d' /etc/postfix/main.cf; echo 'smtpd_banner = $myhostname ESMTP' >> /etc/postfix/main.cf; fi; systemctl reload postfix 2>/dev/null || true |
|---|---|
| name | postfix-banner |
| not_if | grep -qs '^smtpd_banner' /etc/postfix/main.cf && ! grep '^smtpd_banner' /etc/postfix/main.cf | grep -qi mail_name |
| resource | exec |
pavois harden plan localwhere the target is local, a user@host SSH alias, or a container , Docs
Impact & precautions
Defence in depth, not a fix: hiding the banner patches nothing, it only raises the cost of targeting. Operational risk is minimal, but check anything that parses the greeting: some monitoring probes, mail-relay tests and legacy anti-spam rules match on the product name and will need updating. The banner keeps its hostname and the ESMTP keyword, so protocol conformance and reverse-DNS checks are unaffected.