Zusammenspiel der Sendmail Connection Timeouts

Seit gefühlt ewigen Zeiten (seit V8) kennt Sendmail einzelne Timeouts für jede erdenkliche Situation des SMTP-Dialogs, drei ('iconnect', 'connect' und 'aconnect') davon alleine für den Verbindungsaufbau als Client zu einem SMTP-Server.

Die Default-Werte der Timeouts können in der laufenden sendmail.cf nachgeschlagen werden:

[root@popc mail]# grep "O Timeout" sendmail.cf
#O Timeout.initial=5m
#O Timeout.connect=5m
#O Timeout.aconnect=0s
#O Timeout.iconnect=5m
#O Timeout.helo=5m
O Timeout.mail=5m
#O Timeout.rcpt=1h
[...]

Alle mit dem Kommentarzeichen "#" versehenen Timeouts sind Defaults, die in Sendmail deutlich großzügiger sind, als die in RFC 5321 (siehe Abschnitt 4.5.3.2) empfohlenen Minimalwerte. Auffällig ist bspw. der Timeout für die Bestätigung jedes einzelnen Empfängers durch die Gegenstelle ('Timeout.rcpt'), auf die Sendmail geduldig eine Stunde wartet. Verständlich also, dass insb. bei Outgoing MTAs an den Timeouts gedreht wird.

Wer die Connection Timeouts heruntersetzen will, muss das spezielle Verhältnis zwischen 'connect' und 'aconnect' beachten!

'Timeout.connect' ist die Zeit, die Sendmail versucht, die Verbindung zu einer Gegenstelle herzustellen, während 'Timeout.aconnect' die Zeit bezeichnet, die Sendmail für den gesamten Zustellversuch zur Verfügung hat, z.B., um mehrere MX Hosts zu probieren, wenn die höher priorisierten nicht erreichbar sind. Ist dieser Timeout abgelaufen, wird der Zustellversuch abgebrochen und der nächste für die Mail erst im folgenden Queuerun wieder unternommen. 'Timeout.initial' verhält sich wie 'Timeout.connect', bezieht sich aber nur auf den allersten Versuch, eine Mail zuzustellen. Für alle weiteren Versuche kommt 'Timeout.connect' zum Einsatz.

Wird nun 'Timeout.aconnect' gleich 'Timeout.connect' gesetzt, kann Sendmail bei jedem Zustellversuch immer nur den ersten MX Server nehmen, so dass betroffene Mails bis zu dessen Wiedererreichbarkeit in der Queue verbleiben. Im Log ist das Phänomen daran zu erkennen, dass nicht der MX Server mit der niedrigsten Priorität in der Fehlermeldung steht, sondern in diesem Fall der mit der höchsten, nämlich der, den Sendmail aufgrund seiner Timeouts gerade noch versuchen durfte.

Seien die MX Records einer Test-Domain wie folgt:

test.de. 86400 IN MX 100 mx01.test.de.
test.de. 86400 IN MX 200 mx02.test.de.
test.de. 86400 IN MX 300 mx03.test.de.

Nur zur Demonstration setzen wir in sendmail.mc:

define(`confTO_CONNECT', `15s')dnl
define(`confTO_ACONNECT', `15s')dnl

Versuchen wir, eine bereits in der Queue befindliche Mail an user@test.de zu versenden, wobei keiner der eingetragenen MX Server erreichbar ist, finden wir anschließend im Log:

Jun  4 12:54:37 popc sendmail[6523]: t51Lbkus006376: to=<user@test.de>;, delay=2+13:16:48, xdelay=00:00:15, mailer=esmtp, pri=210354, relay=mx01.test.de. [172.22.2.150], dsn=4.0.0, stat=Deferred: Connection timed out with mx01.test.de.

Sendmail hat für unseren Zustellversuch genau 15 Sekunden ('Timeout.aconnect') aufgebracht und konnte es in der Zeit nur bei mx01.test.de versuchen, weil er auf diesen Connect 15 Sekunden ('Timeout.connect') gewartet hat.

Erhöhen wir 'Timeout.aconnect' um nur eine Sekunde, setzen also:

define(`confTO_CONNECT', `15s')dnl
define(`confTO_ACONNECT', `16s')dnl

kann Sendmail immerhin schon versuchen, den zweiten MX Server zu erreichen:

Jun  4 12:56:19 popc sendmail[6586]: t51Lbkus006376: to=<user@test.de>;, delay=2+13:18:30, xdelay=00:00:30, mailer=esmtp, pri=300354, relay=mx02.test.de. [172.22.2.151], dsn=4.0.0, stat=Deferred: Connection timed out with mx02.test.de.

Da 'Timeout.aconnect' nach dem Verbindungsversuch zum ersten MX Server noch nicht abgelaufen war, wurde auch der zweite MX Server versucht, so dass der gesamte Zustellversuch 30 Sekunden (2mal 'Timeout.connect') in Anspruch genommen hat.

Für 'Timeout.aconnect' sollte also der erwählte 'Timeout.connect' mit der Anzahl der sinnvollerweise zu erwartenden MX Server multipliziert werden.

Der Einfluss der 'FallbackMXhost's

Die Server des evtl. konfigurierten 'FallbackMXhost's müssen dabei nicht berücksichtigt werden, da diese nicht in 'Timeout.aconnect' eingehen, wie sich mit folgendem einfachen Experiment nachweisen lässt:

Mittels der Konfiguration

define(`confFALLBACK_MX', `test.com')dnl

stellen für den Fall der Nichterreichbarkeit der für die Empfänger-Domain eigentlich zuständigen MX Server die der Domain test.com zur Verfügung, hier:

test.com. 86400 IN MX 300 mx03.test.com.
test.com. 86400 IN MX 100 mx01.test.com.
test.com. 86400 IN MX 200 mx02.test.com.

Die Timeouts bleiben unverändert:

define(`confTO_CONNECT', `15s')dnl
define(`confTO_ACONNECT', `16s')dnl

Versuchen wir nun, unsere Mail zuzustellen, probiert Sendmail wie vorher nur zwei der MX Server der Empfänger-Domain, aber alle unsere 'FallbackMXhost's:

[root@popc mail]# sendmail -C sendmail.cf -v -qIt51Lbkus006376
Running /var/spool/mqueue/t51Lbkus006376 (sequence 1 of 1)
<user@test.de>;... Connecting to mx01.test.de. via esmtp...
<user@test.de>;... Connecting to mx02.test.de. via esmtp...
<user@test.de>;... Connecting to mx01.test.com. via esmtp...
<user@test.de>;... Connecting to mx02.test.com. via esmtp...
<user@test.de>;... Connecting to mx03.test.com. via esmtp...
<user@test.de>;... Deferred: Connection timed out with mx03.test.com.

Im Logeintrag erkennen wir, dass auch für jeden der drei zusätzlichen 'FallbackMXhost's offensichtlich 'Timeout.connect' von 15 Sekunden gilt:

Jun  4 13:07:22 popc sendmail[6790]: t51Lbkus006376: to=<user@test.de>;, delay=2+13:29:33, xdelay=00:01:15, mailer=esmtp, pri=750354, relay=mx03.test.com. [172.22.3.152], dsn=4.0.0, stat=Deferred: Connection timed out with mx03.test.com. 

Referenzen:

1. Costales, Jansen, Aßmann with Shapiro. sendmail 4th Edition. S. 1097-1110

2. https://tools.ietf.org/html/rfc5321#section-4.5.3.2