CatchAll

Eine Lösung um nicht alle Adressen einer Domäne sondern nur unbekannte Adressen in ein Sammelpostfach zu werfen finden Sie auf Sink:CatchUnknown

Aufgrund der veränderten Struktur von Exchange 2007 kann der hier beschriebene SMTP-Eventsink nicht mit Exchange 2007 eingesetzt werden. Diese Funktion sollte aber durch einen Transportrule erzielt werden können. Allerdings müssen Sie aber auch hier Exchange 2007 so einstellen, dass er erst mal jede Adresse (auch ungültige) annimmt.
How to write Exchange 2007 transport agents http://msexchangeteam.com/archive/2006/12/04/431755.aspx

Ein Microsoft Entwickler hat einen Mustersink erstellt und auf Codeplex veröffentlicht:
http://catchallagent.codeplex.com/
http://www.petri.co.il/setting-up-a-catchall-mailbox-in-exchange-2007.htm

Per Transportregeln geht es aber auch
How to Configure a Catch-All Mailbox http://technet.microsoft.com/en-us/library/bb691132(EXCHG.80).aspx
Oder per Transport Agent: Catchall Agent auf Codeplex http://catchallagent.codeplex.com

Exchange kennt seine Benutzer und Postfächer und liest dazu die Adressen aus dem  Active Directory aus. Von Hause aus gibt es innerhalb einer Exchange Organisation aber kein Sammelpostfach. Folgende Gründe könnten ein Sammelpostfach aber wünschenswert werden lassen.

Auch wenn CatchAll möglich und interessant erscheint, so vertrete ich die Meinung, dass ein Mailsystem unzustellbare Nachrichten gar nicht erst annehmen sollte, sondern direkt beim SMTP-Handshake den Empfang ablehnen sollte. Dies spart Transfervolumen, der Anwender bekommt eine Unzustellbarkeitsmeldung und Spammer und Viren können ihren Schadanteil gar nicht erst senden.

Es gibt mehrere Wege eine Lösung mit einem Sammelpostfach zu schaffen. Aber es gibt natürlich auch Irrwege, die ich kurz aufzeigen will. Vielleicht haben Sie schon das ein oder andere versucht und sind erst dann hier gelandet. Alle drei Irrwege sollten Sie umgehend rückgängig machen:

Irrweg 1: *@firma.de

Es ist nicht möglich, einem Postfach, Verteiler oder öffentlichen Ordner eine Mailadresse in der Form "*@firma.de" zu geben.

Sie können dies zwar tatsächlich eintragen, aber Exchange macht kein Routing mit Platzhaltern.

Irrweg2: virtueller SMTP-Server

Sie können bei Exchange 2003 bzw. Windows 2003 im virtuellen SMTP-Server einen Host angeben, an den nicht zustellbare Mails weiter geleitet werden. Eine solche "Überlauffunktion" ist direkt auf dem SMTP-Server möglich oder innerhalb von Exchange selbst, durch nicht autoritative Empfängerrichtlinien.

Sie benötigen dazu aber immer einen weiteren SMTP-Server, z.B.: auf Basis von Windows oder UNIX; welcher dann die Mails annimmt und in seine eigenen Postfächer zustellt oder umschreibt und an Exchange sendet.

Irrweg 3: virtuelle SMTP-Server NDR-Adresse

Viele nutzen die Funktion, eine Kopie der Unzustellbarkeitsmeldung an ein Postfach zu senden. Dies bedeutet aber, dass der Absender tatsächlich eine Unzustellbarkeit erhalten hat. Sie als Administrator erhalten diese nur als Kopie und können dann reagieren. Sie könnten z.B.: dem Absender die korrekte Mailadresse mitteilen.

Das Problem vieler ungültig adressierter Mails durch Spam, Würmer und Viren wird sie aber sehr bald davon abbringen, diese Funktion zu aktivieren.

Lösung: EventSink für komplette Domain

Der einzig gangbare Weg ist ein System, welches vor der Namensauflösung von Exchange schon prüft, ob die Zieladresse erreichbar ist und wenn dies nicht der Fall ist, diese eben verändert. Dies ist genau die Aufgabe, die entweder ein vor Exchange geschaltetes Programm oder eben ein Exchange Transport Event Sink (siehe Exchange 2000/2003 Event Sinks) auf dem ersten Exchange Server der Organisation ausfüllt. Dass so ein Eventsink gar nicht schwer ist, zeigt folgender Code Schnipsel aus der TechNet (Aus Q324021 How to create a "catchall" mailbox sink for Exchange 2000)

Das Script besteht aus zwei Funktionen. Exchange ruft für jede empfangene Mail die Funktion "ISMTPOnArrival_OnArrival" an, welche eine Kopie (ByVal) der Mitteilung als Objekt übergibt und einen "EventStatus" am Ende zurück erwartet.

Dies Routine holt sich nun mit "msg.envelopeFields" die Informationen aus dem SMTP-Envelope. Zur Erinnerung: Der Envelope ist NICHT Bestandteil des Headers, sondern nur für den Mailserver von belang und enthält die Werte aus den SMTP-Befehlen "MAIL FROM" und "RCPT TO" (Siehe auch SMTP-Telnet). Interessant sind hiervon nur die Empfänger (RECIP_LIST) welche an die Funktion "FixupRecipList" übergeben und von dort verändert wieder zurück gegeben und geändert und gespeichert werden.

<SCRIPT LANGUAGE="VBSCRIPT">
'
' For information about this namespace, see
'   http://msdn.Microsoft.com/library/default.asp?
'           url=/library/en-us/cdosys/html/_cdosys_schema_smtpenvelope.asp
'
Const RECIP_LIST = "http://schemas.Microsoft.com/cdo/smtpenvelope/recipientlist"
'
' For information about the CdoEventStatus enumeration, see
'   http://msdn.Microsoft.com/library/default.asp?
'        url=/library/en-us/cdosys/html/_cdosys_cdoeventstatus_enum.asp
'
Const CDO_RUN_NEXT_SINK = 0
'
' OnArrival sink entry point
'
Sub ISMTPOnArrival_OnArrival(ByVal Msg, EventStatus)
  On Error Resume Next
  Dim objFields
  Set objFields = Msg.EnvelopeFields
  objFields(RECIP_LIST).Value = FixupRecipList(objFields(RECIP_LIST).Value)
  objFields.Update
  Msg.DataSource.Save ' Commit changes
  EventStatus = CDO_RUN_NEXT_SINK
End Sub
'
'  Change any @example.com recipient(s) to bob@company.com
'
Function FixupRecipList(strList)
  On Error Resume Next
  Dim strFixedList
  Dim nDomainPart
  Dim nNamePart
  Dim nNextAddress
  strFixedList = strList
  While (InStr(LCase(strFixedList),"@example.com"))
    nDomainPart = InStr(LCase(strFixedList),"@example.com")
    nNamePart = InStrRev(strFixedList,";",nDomainPart)
    nNextAddress = InStr(nDomainPart+Len("@example.com;"),strFixedList,"SMTP:")
    If (0 = nNamePart) Then
      ' @example.com is first name in recipient list
      If (0 = nNextAddress) Then
        ' @example.com is the last name in the recipient list
        strFixedList = "SMTP:bob@company.com;"
      Else
        ' @example.com is not the last name in the recipient list
        strFixedList = "SMTP:bob@company.com;" & _
                        Right(strFixedList,Len(strFixedList)-nNextAddress+1)
      End If
    Else
      ' @example.com is not the first name in recipient list
      If (0 = nNextAddress) Then
        ' @example.com is the last name in the recipient list
        strFixedList = Left(strFixedList,nNamePart) & "SMTP:bob@company.com;"
      Else
        ' @example.com is not the last name in the recipient list
        strFixedList = Left(strFixedList,nNamePart) & "SMTP:bob@company.com;" & _
                       Right(strFixedList,Len(strFixedList)-nNextAddress+1)
      End If
    End If
  Wend
  FixupRecipList = strFixedList
End Function

</SCRIPT>

Die Funktion "FixipRecipList" übernimmt nun den Part, alle Empfänger an "example.com" durch "bob@company.com" zu ersetzen. Mindestens diese Stellen müssen Sie daher anpassen.

Diese Funktion ist ein klassischer "CatchAll" Account, der alle Mails an diese Domäne in ein Postfach umleitet und eignet sich daher in der Form nur für einen Provider, der alle Mails einer Domain in ein Postfach legen will.

Für die meisten Firmen ist jedoch eine Anpassung erforderlich, bei der die Empfängerliste z.B. gegen das Active Directory geprüft wird und z.B.: nur ungültige Empfänger einer Domäne umgeleitet werden. Dies leistet dieses Script nicht. Die Funktion eines SMTP Transport Event Sink und dieses Scripts sollte aber hinreichend erklärt sein. Unter den Links finden Sie weitere SMTP-EventSinks, die in anderen Programmiersprachen geschrieben sind.

Weitere Links

Keywords: Disclaimer VBscript EventSink CatchAll POP3 Sammelpostfach