none
Sender Based Routing 554 5.4.4 SMTPSEND.DNS.NonExistentDomain

    Question

  • Hi,

    I am configuring Sender Based Routing following this Article (http://www.tuescher.net/Exchange-Sender-Based-Routing/e13.html#chapter6 ), but what i see that is happening is that when i configure to reroute all mails from ms_admin@domain.com.uy to domain.sbr, it looks like is using domain.sbr domain to do the dns checking and of course it does not exist, so i get a undeliverable message in return.

    If i try sending an email from any other user that will use the regular Send Connector it will work perfectly. Even if i change the configuration file to another user, the user with the dns problem, will start using the "Default" send connector and will work fine.

    How can i configure it so it will not do the dns cheking with the Changed domain.

    Delivery has failed to these recipients or groups:

    testmail@gmail.com (testmail@gmail.com)
    The domain name in the email address is incorrect. Check the address.






    This is the email that is getting bouced:


    Diagnostic information for administrators:

    Generating server: EXCH2013.domain.com


    testmail@gmail.com
     Remote Server returned '554 5.4.4 SMTPSEND.DNS.NonExistentDomain; nonexistent domain'


    Original message headers:
    Received: from EXCH2013.domain.com.uy (2002:900:f9::900:f9) by
     EXCH2013.domain.com.uy (2002:900:f9::900:f9) with Microsoft SMTP Server (TLS)
     id 15.0.1210.3; Wed, 26 Oct 2016 17:32:44 -0300
    Received: from EXCH2013.domain.com.uy ([fe80::54e:cad4:d1ff:a8da]) by
     EXCH2013.domain.com.uy ([fe80::54e:cad4:d1ff:a8da%12]) with mapi id
     15.00.1210.000; Wed, 26 Oct 2016 17:32:44 -0300
    From: Name Lastname <ms_admin@domain.com.uy>
    To: "testmail@gmail.com" <testmail@gmail.com>
    Subject: prueba con ABP
    Thread-Topic: prueba con ABP
    Thread-Index: AQHSL8gatvRIUOVqj06h8wCfqoMLsQ==
    Date: Wed, 26 Oct 2016 20:32:43 +0000
    Message-ID: <1477513963759.71004@domain.com.uy>
    Accept-Language: en-US
    Content-Language: en-US
    X-MS-Has-Attach:
    X-MS-TNEF-Correlator:
    x-ms-exchange-transport-fromentityheader: Hosted
    x-originating-ip: [::1]
    Content-Type: multipart/alternative;
          boundary="_000_147751396375971004domaincomuy_"
    MIME-Version: 1.0

    Any Ideas?

    Thanks in advanced !!

    MS

    Wednesday, October 26, 2016 8:48 PM

Answers

All replies

  • You should probably ask the person who wrote that transport agent since its not something built it or supported directly by Microsoft.


    Blog:    Twitter:   

    Wednesday, October 26, 2016 9:49 PM
  • Yes i have asked, but i havent gotten a response yet, in the meanwhile i wanted to ask the community if theres anything i could do, or maybe some setting that i have missed, that could be changed to solve this issue

    Thursday, October 27, 2016 7:05 PM
  • The Other option is if anybody could help spot the error or show me an example of the code that is known to be working.

    http://www.tuescher.net/Exchange-Sender-Based-Routing/resources/CustomSBRRoutingAgent-E13.cs.txt 

    // This is an Exchange 2013 custom transport agent for sender based re-routing, created by Martin Tuescher
    // As it is here, it needs a Send Connector configured to route mails to override domains that has equal or
    // lower costs than the Default Send Connector for "*".

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Configuration.Install;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Text;
    using Microsoft.Win32;

    using Microsoft.Exchange.Data.Transport;
    using Microsoft.Exchange.Data.Transport.Email;
    using Microsoft.Exchange.Data.Transport.Smtp;
    using Microsoft.Exchange.Data.Transport.Routing;
    using Microsoft.Exchange.Data.Common;

    namespace Microsoft.Exchange.SBR
    {
        /// <summary>
        // Run when installing the assembly, this function sets up the required application event logging registry keys
        /// </summary>
        [RunInstaller(true)]
        public class SbrRoutingAgentEventLogInstaller : Installer
        {
            private EventLogInstaller SbrEventLogInstaller;

            public SbrRoutingAgentEventLogInstaller()
            {
                SbrEventLogInstaller = new EventLogInstaller(); // Create an instance of an EventLogInstaller.
                SbrEventLogInstaller.Source = "Microsoft.Exchange.SBR"; // Set the source name of the event log.
                SbrEventLogInstaller.Log = "Application"; // Set the event log that the source writes entries to.
                Installers.Add(SbrEventLogInstaller); // Add routingeventLogInstaller to the Installer collection.

                RegistryKey newRegKey = Registry.LocalMachine.CreateSubKey("System\\CurrentControlSet\\Services\\MSExchangeSbrAgent\\Diagnostics");
                newRegKey.SetValue("General", 0);
            }
        }

        public sealed class SbrRoutingAgentFactory : RoutingAgentFactory
        {
            public override RoutingAgent CreateAgent(SmtpServer server)
            {
                RoutingAgent myAgent = new OwnRoutingAgent();
                return myAgent;
            }
        }

        public class OwnRoutingAgent : RoutingAgent
        {
            private int eventLogLevel = -1;     // Don't log if the proper keys aren't setup because this could cause problems later.
            private RegistryKey eventLogRegKey;

            private Dictionary<String, String> _RoutingTable;
            private String OverrideSettingsFileName = Environment.GetEnvironmentVariable("ExchangeInstallPath", EnvironmentVariableTarget.Machine) + @"TransportRoles\agents\Custom\Microsoft.Exchange.SBR.OverrideSettings.config";

            private String[] _InternalDomains;
            private String InternalDomainsFileName = Environment.GetEnvironmentVariable("ExchangeInstallPath", EnvironmentVariableTarget.Machine) + @"TransportRoles\agents\Custom\Microsoft.Exchange.SBR.InternalDomains.config";

            private String[] _IgnoreAuthAsValues;
            private String IgnoreAuthAsFileName = Environment.GetEnvironmentVariable("ExchangeInstallPath", EnvironmentVariableTarget.Machine) + @"TransportRoles\agents\Custom\Microsoft.Exchange.SBR.IgnoreAuthAs.config";

            public OwnRoutingAgent()
            {
                // Read EventLogLevel from Registry
                this.eventLogRegKey = Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\services\\MSExchangeSbrAgent\\Diagnostics");
                if (this.eventLogRegKey != null)
                {
                    if (eventLogRegKey.GetValue("General") != null)
                    {
                        this.eventLogLevel = ((int)eventLogRegKey.GetValue("General"));

                        if (eventLogLevel >= 6) EventLog.WriteEntry("Microsoft.Exchange.SBR", "Event logging set to level " + this.eventLogLevel.ToString() + ".");
                    }
                }

                //subscribe to different events
                base.OnResolvedMessage += new ResolvedMessageEventHandler(ownRoutingAgent_OnResolvedMessage);

                _IgnoreAuthAsValues = File
                                      .ReadAllLines(IgnoreAuthAsFileName)
                                      .Where(line => !String.IsNullOrEmpty(line))
                                      .Where(line => !line.StartsWith("#"))
                                      .Select(line => line.ToLower())
                                      .ToArray();   // assumes line has 1 element, no error check
                
                _InternalDomains = File
                                   .ReadAllLines(InternalDomainsFileName)
                                   .Where(line => !String.IsNullOrEmpty(line))
                                   .Where(line => !line.StartsWith("#"))
                                   .Select(line => line.ToLower())
                                   .ToArray();

                _RoutingTable = File
                                .ReadAllLines(OverrideSettingsFileName)
                                .Where(line => !String.IsNullOrEmpty(line))
                                .Where(line => !line.StartsWith("#"))
                                .Select(line => line.ToLower())
                                .Select(line => line.Split(';'))
                                .ToDictionary(items => items[0], items => items[1]); // assumes line has 2 elements, no error check
            }

            private void ownRoutingAgent_OnResolvedMessage(ResolvedMessageEventSource source, QueuedMessageEventArgs e)
            {
                try
                {
                    var routingOverrideDomainPart = "";
                    var senderFullEmailAddress = e.MailItem.FromAddress.ToString().ToLower(); // get full sender email address
                    var senderOnlyDomainPart = e.MailItem.FromAddress.DomainPart.ToLower(); // get domain part of sender email address
                    var emailMessageId = e.MailItem.Message.MessageId.ToString();
                    var emailMessageSubject = e.MailItem.Message.Subject.ToString();
                    Microsoft.Exchange.Data.Mime.Header emailMessageOrgAuthAs;
                    emailMessageOrgAuthAs = e.MailItem.Message.MimeDocument.RootPart.Headers.FindFirst("X-MS-Exchange-Organization-AuthAs");

                    if (eventLogLevel >= 5) EventLog.WriteEntry("Microsoft.Exchange.SBR", "Entering OnResolved for message " + emailMessageId + " (\"" + emailMessageSubject + "\").", EventLogEntryType.Information, 1);

                    if (!_IgnoreAuthAsValues.Contains(emailMessageOrgAuthAs.Value.ToString().ToLower()))
                    {
                        // X-MS-Exchange-Organization-AuthAs value not found in ignore table (typically "Internal") so we start processing the mail
                        if (!_RoutingTable.ContainsKey(senderOnlyDomainPart) && !_RoutingTable.ContainsKey(senderFullEmailAddress))
                        {
                            // Nothing to reroute, quit
                            if (eventLogLevel >= 5) EventLog.WriteEntry("Microsoft.Exchange.SBR", "Exiting OnResolved for message " + emailMessageId + " (\"" + emailMessageSubject + "\"):\nSender email domain or address not found in rerouting table.\nSBR agent is not processing this mail.", EventLogEntryType.Information, 8);
                            return;
                        }

                        int rerouteCount = 0;

                        if (_RoutingTable.ContainsKey(senderOnlyDomainPart))
                        {
                            // sender email domain is in rerouting table
                            if (eventLogLevel >= 3) EventLog.WriteEntry("Microsoft.Exchange.SBR", "Sender email domain " + senderOnlyDomainPart + " for message " + emailMessageId + " (\"" + emailMessageSubject + "\") is in rerouting table.", EventLogEntryType.Information, 2);
                            routingOverrideDomainPart = _RoutingTable[senderOnlyDomainPart];
                        }

                        if (_RoutingTable.ContainsKey(senderFullEmailAddress))
                        {
                            // sender email address is in rerouting table
                            if (eventLogLevel >= 3) EventLog.WriteEntry("Microsoft.Exchange.SBR", "Sender email address " + senderFullEmailAddress + " for message " + emailMessageId + " (\"" + emailMessageSubject + "\") is in rerouting table.", EventLogEntryType.Information, 2);
                            routingOverrideDomainPart = _RoutingTable[senderFullEmailAddress];
                        }

                        var myRoutingOverride = new RoutingDomain(routingOverrideDomainPart);
                        var recipientsToOverride = e.MailItem
                                                    .Recipients
                                                    .Where(rec => !_InternalDomains.Contains(rec.Address.DomainPart.ToLower()));

                        foreach (EnvelopeRecipient recp in recipientsToOverride)
                        {
                            if (eventLogLevel >= 2) EventLog.WriteEntry("Microsoft.Exchange.SBR", "Overriding recipient " + recp.Address.ToString() + " on " + emailMessageId + " (\"" + emailMessageSubject + "\").", EventLogEntryType.Information, 4);
                            RoutingOverride newRoute = new RoutingOverride(myRoutingOverride, DeliveryQueueDomain.UseOverrideDomain);
                            source.SetRoutingOverride(recp, newRoute);
                            rerouteCount++;
                        }

                        if (eventLogLevel >= 1) EventLog.WriteEntry("Microsoft.Exchange.SBR", "Statistics for message " + emailMessageId + " (\"" + emailMessageSubject + "\"):\n" + rerouteCount.ToString() + " recipients  were rerouted.", EventLogEntryType.Information, 5);
                        if (eventLogLevel >= 4) EventLog.WriteEntry("Microsoft.Exchange.SBR", "Exiting OnResolved for message " + emailMessageId + " (\"" + emailMessageSubject + "\").", EventLogEntryType.Information, 8);
                    }
                    else
                    {
                        // X-MS-Exchange-Organization-AuthAs value found in ignore table
                        if (eventLogLevel >= 4) EventLog.WriteEntry("Microsoft.Exchange.SBR", "Exiting OnResolved for message " + emailMessageId + " (\"" + emailMessageSubject + "\"):\nX-MS-Exchange-Organization-AuthAs header \"" + emailMessageOrgAuthAs.Value.ToString().ToLower() + "\" found in ignore table.\nSBR agent is not processing this mail.", EventLogEntryType.Information, 8);
                        return;
                    }
                }
                catch (Exception except)
                {
                    if (eventLogLevel >= 3) EventLog.WriteEntry("Microsoft.Exchange.SBR", "Exception (OnResolved): " + except.Message + "\n" + except.StackTrace, EventLogEntryType.Information, 10);
                }
            }
        }
    }
    Friday, October 28, 2016 4:47 PM
  • Hi el pibe,

    Exchange isn't really designed to route email based on the sender, it routes based on the recipient. For the script code, you may get more help from the script forum:

    Script forum: https://social.technet.microsoft.com/Forums/scriptcenter/en-US/home?forum=ITCG

    It’s recommended to read the following articles:

    https://social.technet.microsoft.com/Forums/exchange/en-US/3d5bc57e-dd13-4a90-9e14-cc7bcd22c808/scoped-send-connector-or-configure-sender-based-routing-smarthost-conundrum-based-on-internal?forum=exchangesvrsecuremessaginglegacy

    Multiple Tenancy Multiple smart hosts Exchange 2013

    Please note: Since the website is not hosted by Microsoft, the link may change without notice. Microsoft does not guarantee the accuracy of this information. And the changes made in the above blog is not supported officially by Microsoft.

    Thanks for your kindly understanding and hope it helps.

    BR.


    Jason Chao
    TechNet Community Support


    Please remember to mark the replies as an answer if they help and unmark them if they provide no help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com

    Monday, October 31, 2016 3:13 AM
    Moderator
  • Thanks a lot for the response, i will look into it. Even though i believe it counld be done. its just a little tricky the coding part, specially since i known nothing about coding hehehe. But maybe with a little help from the Scrip Community i get something.

    Regards

    Tuesday, November 1, 2016 2:17 PM