'block_bad_helo' benötigt 'delay_checks' oder auch nicht

Veröffentlicht: Mittwoch, 10. September 2014 20:28

Neulich kam vom Kunden die Frage, ob 'block_bad_helo' vielleicht nicht so ganz richtig funktioniert. Seit Sendmail 8.14.0 blockt das Feature Zustellversuche von Gegenstellen, die im HELO "unseren" oder unqualifizierte Namen angeben.

Der Kunde hatte 'block_bad_helo' in der sendmail.mc aktiviert

FEATURE(`block_bad_helo')dnl

 und erhielt auch entsprechende Logzeilen,

Sep 5 19:37:51 mailin sendmail[10839]: s85HbhIZ010834: ruleset=check_rcpt, arg1=<user@domain.com>;, relay=out.domain.com [xxx], reject=550 5.7.1 <user@domain.com>;... bogus HELO name used: 127.0.0.1

vermutete aber bald, dass Sendmail das Feature recht launenhaft verwendet. Mittels Telnet bestätigte sich der Verdacht, die Testmail wurde trotz Bad Helo akzeptiert:

ray:~ $ telnet mailin 25
Trying 192.168.30.10...
Connected to mailin.
Escape character is '^]'.
220 mailin ESMTP Sendmail 8.14.4/8.14.4; Thu, 6 Sep 2014 10:48:08 +0200
helo test
250 mailin Hello ray [192.168.200.11], pleased to meet you
mail from:<>
250 2.1.0 <>... Sender ok
rcpt to:<user@sendmaid.org>;
250 2.1.5 <user@sendmaid.org>;... Recipient ok

Die kurze Antwort (siehe auch Sendmail-Doku ab Version 8.14.1): 'block_bad_helo' benötigt zusätzlich das Feature 'delay_checks'.

Der Grund hierfür liegt in der Platzierung der Regeln für 'block_bad_helo' im Ruleset 'Relay_ok', welcher erst am Ende der Recipient Checks aufgerufen wird. Bei erlaubter Empfänger-Adresse gibt 'Rcpt_ok' ein RELAY zurück, so dass 'Basic_check_rcpt' vor dem Aufruf des Bad Helo Checks mit RELAY verlassen wird. Gleiches gilt für eine erlaubte Gegenstelle, die in 'Relay_ok' vor den Bad Helo Checks ein RELAY erzeugt.

SBasic_check_rcpt
[...]
R$* $: $1 $| @ $>"Rcpt_ok" $1
R$* $| @ $#TEMP $+ $: $1 $| T $2
R$* $| @ $#$* $#$2
R$* $| @ RELAY $@ RELAY
R$* $| @ $* $: O $| $>"Relay_ok" $1
[...]

An dieser Stelle sind die Regeln also wirkungslos. Lediglich wenn eine Mail sowieso nicht angenommen wird, führt ein Bad Helo Name zu einem Logeintrag und sorgt damit für zusätzliche Verwirrung, da der Admin annehmen darf, dass das Feature funktioniert:

Sep  9 09:10:57 popc sendmail[3470]: s897AXso003470: ruleset=check_rcpt, arg1=<user@not-accepted.org>;, relay=pop.fritz.box [10.10.10.145], reject=550 5.7.1 <user@not-accepted.org>;... bogus HELO name used: m

Mit 'delay_checks' werden die MAIL und RELAY Checks erst nach dem RCPT Check durchgeführt. Ein RELAY aus dem RCPT Check führt nicht zu einem Ausstieg aus dem Ruleset, weil die MAIL und RELAY Checks noch durchgeführt werden müssen, um evtl. dort auftretende Ablehnungen einer Mail berücksichtigen zu können.

Scheck_rcpt
[...]
R$+ $: $1 $| $>checkrcpt $1
[...]
R$* $: $1 $| $>checkmail <$&f>
R$* $| $#$* $#$2
R$* $| $* $: $1 $| $>checkrelay $&{client_name} $| $&{client_addr}
R$* $| $#$* $#$2
[... Rules des Features block_bad_helo ...]
R$* $| <$*> [$*] $#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
R$* $| $* $: $1

Dadurch werden die Bad Helo Regeln auch akzeptierte Mails durchlaufen und blockieren die betreffenden Zustellversuche.

So funktioniert 'block_bad_helo' auch ohne 'delay_checks'

Nun ist aber nicht jede Sendmail-Konfiguration für den Einsatz von 'delay_checks' geeignet. Wer nicht auf 'delay_checks' umstellen möchte, kann statt der Features die Regeln für 'block_bad_helo' an geeigneter Stelle in der sendmail.mc einbauen, z.B. in 'Local_check_rcpt'. Dann wird 'delay_checks' nicht benötigt, weil 'Local_check_rcpt' im Recipient Check vor dem obigen 'Basic_check_rcpt' ausgeführt wird und damit Zustellversuche mit einem Bad Helo ablehnen kann.

Hinweis: Der folgenden kleinen Anleitung nach sollte nur handeln, wer sie dank ausreichender Kenntnisse bzgl. Sendmail Rulesets genau versteht und damit einzuschätzen vermag, was dies für die eigene Konfiguration bedeutet und ob die Erweiterung abgeändert eingebaut werden muss.

Zur Ermittlung der Regeln für 'block_bad_helo' kopiert man die eigene sendmail.mc, fügt der Kopie das Feature hinzu, erstellt daraus eine temporäre cf-Datei und difft diese gegen die eigene laufende sendmail.cf. Das Ergebnis des Diffs kann man wie folgt in der eigenen sendmail.mc verwenden:

[...]
LOCAL_CONFIG

C{R}127.0.0.1
C{w}[127.0.0.1]
C{R}IPv6:::1
C{w}[IPv6:::1]

LOCAL_RULESETS

SLocal_check_rcpt
R$* $: $1 $| <$&{auth_authen}> Get auth info
R$* $| <$+> $: $1 skip if auth
R$* $| <$*> $: $1 $| <$&{client_addr}> [$&s] Get connection info
R$* $| <$=R $*> [$*] $: $1 skip if local client
R$* $| <0> [$*] $: $1 skip if sendmail -bs
R$* $| <$*> $=w $#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
R$* $| <$*> [$=w] $#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
R$* $| <$*> [$+.$+] $: $1 qualified domain ok
R$* $| <$*> [$*] $#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
R$* $| $* $: $1