LMTP back end TCPIP channel

From Messaging Server Technical Reference Wiki
Jump to: navigation, search

LMTP back end TCP/IP channel

On an LMTP back end Message Store host, the typical TCP/IP channels and servers are replaced instead by an LMTP server, defined in Unified Configuration as a tcp_lmtpss channel and corresponding LMTPSS service under the Dispatcher:

msconfig> show channel:tcp_*
role.channel:tcp_lmtpss.official_host_name = tcp_lmtpss-daemon
role.channel:tcp_lmtpss.flagtransfer (novalue)
role.channel:tcp_lmtpss.identnonenumeric (novalue)
role.channel:tcp_lmtpss.lmtp (novalue)
msconfig> show dispatcher.service:*MTP*
role.dispatcher.service:LMTPSS.image = IMTA_BIN:tcp_lmtp_server
role.dispatcher.service:LMTPSS.logfilename = IMTA_LOG:tcp_lmtpss_server.log
role.dispatcher.service:LMTPSS.parameter = CHANNEL=tcp_lmtpss
role.dispatcher.service:LMTPSS.stacksize = 2048000
role.dispatcher.service:LMTPSS.tcp_ports = 225
msconfig> show mapping:PORT_ACCESS
role.mapping:PORT_ACCESS.rule TCP|*|225|*|* $C$|INTERNAL_IP;$1|$Y$E
role.mapping:PORT_ACCESS.rule TCP|* $N500 Do not connect to this machine
msconfig> show mapping:INTERNAL_IP
role.mapping:INTERNAL_IP.rule internal-host-or-subnet $Y
role.mapping:INTERNAL_IP.rule another-internal-host-or-subnet $Y
role.mapping:INTERNAL_IP.rule ${::1} $Y
role.mapping.INTERNAL_IP.rule 127.0.0.l $Y
role.mapping:INTERNAL_IP.rule * $N

A recipe that creates this configuration would be:

description("Configure backend store accessible via LMTP");
keywords(["backend", "store", "LMTP"]);

# Back end's IP address
# Script will prompt for address if left black
#myIP = "";
myIP = "";

# List of frontend machines that access this store via LMTP
# Script will prompt for addresses if left blank
#feIPs = ["", ""];
feIPs = [];

# Prompt for myIP and feIP if needed
if (length(myIP) <= 0) {
  myIP = read("Enter the IP address of this host: ");

if (length(feIPs) <= 0) {
  loop {
    ip = read("Enter the IP address of a frontend machine (<RET> if no more): ");
    exitif (ip == "");
    push(feIPs, ip);

# Configure LMTP back end
if exists_channel("tcp_lmtpss") {
  warn("WARNING: tcp_lmtpss channel already exists, will not be added");
} else {
   print("INFO: Adding tcp_lmtpss channel\n");
              ["flagtransfer", "",
               "identnonenumeric", "",
               "lmtp", "",
               "official_host_name", "tcp_lmtpss-daemon"]);

if exists_group("dispatcher.service:LMTPSS") {
  warn("WARNING: Dispatcher.service:LMTPSS group already exists, will not be created");
} else {
  print("INFO: Creating dispatcher.service:LMTPSS group\n");
            ["image", "IMTA_BIN:tcp_lmtp_server",
             "logfilename", "IMTA_LOG:tcp_lmtpss_server.log",
             "parameter", "CHANNEL=tcp_lmtpss",
             "tcp_ports", "225",
             "stacksize", "2048000"]);

# Replace PORT_ACCESS mapping
print("INFO: Replace PORT_ACCESS mapping\n");
                ["TCP|*|225|*|*", "$C$|INTERNAL_IP;$1|$Y$E",
                 "TCP|*", "$N500 Do not connect to this machine"]);
# add PORT_ACCESS mapping entries
internal_ip = ["${::1}", "$Y",
               "", "$Y",
               "*", "$N"];

# list of IP addresses
ipaddrs = [feIPs];
push(ipaddrs, myIP);

loop {
  exitif (ipaddrs == []);
  ip = pop(ipaddrs);
  push(internal_ip, "$Y");
  push(internal_ip, ip);

print("INFO: Replace INTERNAL_IP mapping\n");
replace_mapping("INTERNAL_IP", internal_ip);

In legacy configuration, this would be defined as a tcp_lmtpss channel in the imta.cnf file:

tcp_lmtpss flagtransfer identnonumeric lmtp

and a Dispatcher definition of the LMTPSS server in the dispatcher.cnf file:

! rfc 2033 LMTP server - store
! Uncomment the following line and set INTERFACE_ADDRESS to an appropriate
! host IP (dotted quad) if the dispatcher needs to listen on a specific
! interface (e.g. in a HA environment).

and with PORT_ACCESS and INTERNAL_IP mapping tables in the mappings file:


 TCP|*|225|*|*   $C$|INTERNAL_IP;$1|$Y$E
 TCP|*           $N500 Do not connect to this machine 

  host's-own-public-IP                      $Y
  another-public-IP-for-host                $Y
  internal-host-or-subnet                   $Y
  another-internal-host-or-subnet           $Y
  ${::1}                                    $Y                                 $Y
  *                                         $N

Note that this configuration is only appropriate for back ends where delivery is only performed by LMTP. In particular, the PORT_ACCESS and INTERNAL_IP mapping mapping tables shown here would not be appropriate for back ends that also accept mail via SMTP.

See also: