Configuring Citrix NetScaler to load balance Exchange SMTP inbound connections

I’ve recently been involved with configuring a client’s Citrix NetScalers to load balance inbound SMTP connections to Exchange and thought I’d take this opportunity to blog the process.

#1 – Configure Exchange Server Objects

Begin by creating the Exchange Server objects in Traffic Management > Load Balancing > Servers:

image

#2 – Create SMTP Monitor

Create an SMTP monitor object by navigating to Traffic Management > Load Balancing > Monitors:

Name: EXCH_MONITOR_SMTP

Type: SMTP

Interval: 5 second

Response Time-out: 2 second

Destination Port: Bound Service

Down Time: 30 second

image

image

Click on the Special Parameters tab and configure the following:

Script Name: nssmtp.pl

Dispatcher IP: 127.0.0.1

Dispatcher Port: 3013

image

Note that the nssmtp.pl script bundled with the NetScaler will go as far as attempting to open a connection to confirm that the service is up.  The script and the actual code can be found in the following directory of the NetScaler:

/netscaler/monitors

image

#!/usr/bin/perl -w

################################################################

##

## Copyright 1998-2016 Citrix Systems, Inc. All rights reserved.

## This software and documentation contain valuable trade

## secrets and proprietary property belonging to Citrix Systems, Inc.

## None of this software and documentation may be copied,

## duplicated or disclosed without the express

## written permission of Citrix Systems, Inc.

##

################################################################

## This is a netscaler supplied script. Please dont modify this as it will be overwritten during

## reboot. If you want to modify, please make a copy of this script and modify.

## This script is used to do smtp monitoring using KAS feature.

use strict;

use Net::SMTP;

use Net::SMTP6;

use Netscaler::KAS;

sub is_ipv4_address

{

my $address = $_[0];

if ($address =~ m/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/) {

return 1;

}

return 0;

}

## This function is a handler for performing smtp probe in KAS mode

sub smtp_probe

{

## There must be at least 4 arguments to this function.

## 1. First argument is the IP that has to be probed.

## 2. Second argument is the port to connect to.

## 3. Timeout, it is present in index 3

if(scalar(@_) < 2)

{

return (1,”Invalid number of arguments”);

}

## Try to connect to the server

my $smtp;

if (is_ipv4_address($_[0])) {

$smtp=Net::SMTP->new($_[0].”:”.$_[1],Timeout=>$_[3])

or return (1,”Unable to connect to server – $!”);

## Probe succeeded

$smtp->quit;

return 0;

}

else { #IPV6 adress

$smtp=Net::SMTP6->new($_[0], PeerPort => $_[1], Timeout=>$_[3])

or return (1,”Unable to connect to server – $!”);

## Probe succeeded

$smtp->quit;

return 0;

}

}

## Register smtp probe handler, to the KAS module.

probe(&smtp_probe);

image

#3 – Configure Service Group

Proceed to configure the Service Group object by navigating to Traffic Management > Load Balancing > Service Groups:

Name: Exchange_2016_SMTP

Protocol: TCP

Cache Type: SERVER

image

image

Click on the No Service Group Member to add the Exchange server objects that were created in Step #1:

image

Click on the Monitors option on the right to add the SMTP monitor created in Step #2:

image

image

Complete the creation of the Service Group and you should now see the group listed with the State and Effective State as being up:

image

Step #4 – Create the Load Balancing Virtual Server

Continue to configure the load balancing virtual server object by navigating to Traffic Management > Load Balancing > Virtual Servers:

image

image

Add the Service Group created in Step #3:

image

Complete the creation of the load balancing virtual server and you should see State and Effective State listed as being up:

image

Step #5 – Lockdown Open Relay for Exchange Receive Connector

One of the common mistakes often overlooked when configuring SMTP load balancing via the NetScaler is inadvertently allowing open relay on the Exchange Server’s receive connector traffic coming from the NetScaler would appear to be an internal IP to the Exchange server.  One of the ways to test whether the receive connector allows for open relay is to execute the following commands via telnet:

telnet exchangeServerFQDN 25

220 EXMB02.contoso.com Microsoft ESMTP MAIL Service ready at Thu, 1
2 Jan 2017 14:20:03 -0400
ehlo bogus.com
250-EXMB02.contoso.com Hello [10.21.1.32]
250-SIZE 37748736
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-8BITMIME
250-BINARYMIME
250 CHUNKING
mail from:bogus@bogus.com
250 2.1.0 Sender OK
rcpt to:validperson@domain.com
250 2.1.5 Recipient OK

image

Note that the mail from email address has a domain that is not hosted on the Exchange server and the rcpt to address is meant to be an email address that is also not hosted on the Exchange server.  If the response to these commands is Recipient OK then your receive connect is allowing open relay.  To correct this, ensure that the receiving connector has the Externally secured (for example, with IPsec) setting disabled:

image

Once the connect has been locked down, the following response is what the telnet commands would yield:

220 EXMB01.contoso.com Microsoft ESMTP MAIL Service ready at Thu, 1
2 Jan 2017 14:15:47 -0400
ehlo bogus.com
250-EXMB01.contoso.com Hello [10.21.1.32]
250-SIZE 37748736
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-8BITMIME
250-BINARYMIME
250 CHUNKING
mail from:bogus@bogus.com
250 2.1.0 Sender OK
rcpt to:validperson@google.com
550 5.7.54 SMTP; Unable to relay recipient in non-accepted domain

image

Step #6 – Lockdown SMTP Load Balancing Virtual Server Connectivity

Another often overlooked issue that load balancing SMTP requests through a NetScaler creates is that the Exchange server’s receive connectors no longer see the true source IP address because all of the requests now originate form the NetScaler’s NSIP address which means a malicious or unauthenticated internal device could potentially relay mail off of the load balancing virtual server and be able to successfully have the Exchange server deliver the email.  This could be addressed by either configuring the Direct Server Return (DSR) feature on the NetScaler or simply locking down which IP addresses can connect to the load balancing virtual server.  I won’t cover the configuration of DSR and will point to one of my previous blog posts to demonstrate how to lock down the load balancing virtual server:

Filtering a Citrix NetScaler load balancing virtual server access based on source IP address
https://blog.terenceluk.com/2017/01/filtering-citrix-netscaler-load.html