Proxying email to different mailservers on different domains on one public IP address

I have a Proxmox machine with 2 virtual machines running on it, and also two domains, let's say domainA.com and domainB.com. Both domains are pointing to the Proxmox public address and also I have set up nginx to reverse http traffic based on incoming domain name to each of the VMs.

network looks like this :

proxmox with nginx = #public IP# and 192.168.1.1, domainA.com = 192.168.1.2, domainB.com=192.168.1.3)

I also want to set up mail server on each of the VM and route incoming mail communication based on the domain name. For example when I receive mail with recipient [email protected] I want to forward the communication to 192.168.1.2, when I receive mail with recipient [email protected] I want to forward the communication to 192.168.1.3.

How can I achieve this? I was having trouble doing this with nginx and I am not sure this is going to work


Solution 1:

Mail protocols don't have any equivalent of HTTP's Host header on which the virtual hosting and reverse proxying is based.

Any "virtual mail hosting" is based on the simple fact you can integrate domain name into username of mail user. It is not possible to differentiate users by mail server hostname to which they connect, say, via SMTP or IMAP or anything; there is no place in the protocol other than username where domain name may be put into. A reverse proxy is therefore needs to know username, i.e. to perform authentication; but then this is not just a reverse proxy anymore.

Also I don't know any solutions which do analogous to SNI for mail protocols, so all mail "virtual hosts" could only use the same single SSL certificate of hosting server. This means, there is no way at all to use different mail server hostnames for different hosted domains, other that exist in the certificate (in the CN or SAN field).


For SMTP, a limited mimicking of reverse proxy is possible. With Postfix that might be done like this:

  1. Set up a "reverse proxy" system which will consider itself as a relay for both domains. For that, you need to add them into relay_domains setting in the main.cf. Of course, internet senders for both domains must be directed to that system (i.e. MX of all domains must be set to this relay host name).

You'd better give your relay a way to filter out undeliverable destinations. In other words, relay must always know the actual list of mailboxes on target servers. This is to reduce spam load and a probability of the backscatter (this is much more important than you might think!). For example, synchronize mailbox databases of end servers with it periodically and configure relay_recipient_maps on relay host. Remember what I said about "not just a reverse proxy"?

  1. Set up transport maps on this "reverse proxy", which will direct mail for each domain to appropriate settings. This includes adding lines to the /etc/postfix/transport file:
domainA.com smtp:[192.168.1.2]
domainB.com smtp:[192.168.1.3]

Square brackets direct Postfix to not to do MX lookup and use the specified address directly; it'll just connect there to port 25 to deliver mail. Then specify this file as transport_maps in main.cf (see Postfix docs how to do that correctly)

  1. Setup an MTA on the target hosts. They are configured as usual, except that you should specify the relay host as trusted, for antispam systems of those MTAs to trust its Received: header (you must not trust any Received: headers which were added by systems not under your control).