Chapter 20. Setting up E-Mail Part 4: End-to-End E-mail Routing

So far, we've been sending ourselves e-mail on the same server. Now, it's time to put it all together and have e-mail routed across the internet.

We'll set up mail.projreality.sam, and have e-mail exchanged between <sam@isp.sam> and <sam@projreality.sam>. First, clone mail-isp-sam.vdi to mail-projreality-sam.vdi, and create a VM called "mail.projreality.sam" using the cloned hard disk. Set Adapter 1 to Internal Network "projreality dmz".

Boot up mail.projreality.sam (the Network step will fail, since mail.isp.sam gets its IP address via DHCP, and mail.projreality.sam has a fixed IP). Once it's up, set the HOSTNAME to mail.projreality.sam, set the IP address to 172.16.211.15, and the default gateway to 172.16.211.1

Next, we'll need to tweak the Postfix SMTP settings for the new domain. Edit /etc/postfix/main.cf and change the line beginning with virtual_mailbox_domains to:

virtual_mailbox_domains = projreality.sam

Also, edit /etc/postfix/virtual_alias and change the line that says

root:		sam@isp.sam

to

root:		sam@projreality.sam

Since we've changed the virtual_alias file, we need to run postalias:

sudo postalias /etc/postfix/virtual_alias

Next, log into MySQL as postfixuser (recall the password was postfixpassword):

mysql -u postfixuser -p

Go to the postfix database, and change the domain entry for isp.sam to projreality.sam

use postfix

UPDATE domains SET domain = 'projreality.sam' WHERE domain = 'isp.sam';

Also, change the user entry for sam@isp.sam to sam@projreality.sam

UPDATE users SET email = 'sam@projreality.sam', domain = 'projreality.sam' WHERE email = 'sam@isp.sam';

Go ahead and reboot the VM to get a clean restart.

Now, repeat the SMTP tests done earlier, for this server:

telnet localhost smtp

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'
220 mail.projreality.sam ESMTP Postfix

ehlo projreality.sam

250-mail.projreality.sam
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN

mail from:<sam@projreality.sam>

250 2.1.0 Ok

rcpt to:<sam@projreality.sam>

250 2.1.5 Ok

data

354 End data with <CR><LF>.<CR><LF>

Testing

[empty line]

.

250 2.0.0 Ok: queued as [some ID]

quit

221 2.0.0 Bye

Now look in /home/vmailer/projreality.sam/sam@projreality.sam/new. You should see a file in there. If it's there, then the e-mail was successfully sent!

Go ahead and delete /home/vmailer/isp.sam

Next, we'll repeat the IMAP tests done earlier, for this server:

A LOGIN "sam@projreality.sam" "sampassword"

A OK LOGIN Ok.

B SELECT "Inbox"

* FLAGS (\Draft \Answered \Flagged \Deleted \Seen \Recen
t)
* OK [PERMANENTFLAGS (\* \Draft \Answered \Flagged \Deleted \Seen)] Limited
* 3 EXISTS
* 3 RECENT
* OK [UIDVALIDITY 1290482568] Ok
* OK [MYRIGHTS "acdilrsw"] ACL
B OK [READ-WRITE] Ok

Z LOGOUT

* BYE Courier-IMAP server shutting down
Z OK LOGOUT completed

Next, we need to tweak the settings for Apache. Edit /etc/httpd/conf/httpd.conf and change the line

Listen 172.16.152.15:80

to

Listen 172.16.211.15:80

Finally, we need to redo the certificate for this site. Follow the instructions in Chapter 19, but enter "mail.projreality.sam" as the Common Name when generating the CSR.

At this point, if you tried to restart Apache, it will fail. As a result of including the mod_unique_id module, Apache needs to be able to look up the domain name of itself. We have already created a resolver for projreality.sam's network, we just need the mail server to use it. Edit /etc/resolv.conf on the mail.projreality.sam VM and add the following line to set dns1.projreality.sam as the DNS server

nameserver 172.16.211.25

Since mod_unique_id needs to be able to do a DNS lookup on mail.projreality.sam, we would need rns, a.root-servers.sam, ns1.projreality.sam, and all of the VMs in between to be running, so we'll put off starting Apache until the end.

Finally, go to the firewall.projreality.sam VM and edit /etc/pf.conf - we'll need to allow outside access to the mailserver, and for the mailserver to be able to deliver mail out. Under the Servers section, add

mail = "172.16.211.15"

At the end of the file, just before the block log quick all line, add

pass in quick on $Ext inet proto tcp from any to $mail port { http, https, imap, smtp }
pass out quick on $DMZ inet proto tcp from any to $mail port { http, https, imap, smtp }

pass in quick on $DMZ inet proto tcp from $mail to any port smtp
pass out quick on $Ext inet proto tcp from $mail to any port smtp

At this point, we're ready to test end-to-end e-mail delivery. There's one catch, though, related to our setup. We will need to have 16 VMs running, including having the customer VM running X. That will take a lot of memory, more than most systems will handle. If you start swapping to disk, things will slow down tremendously. So, unless your computer has 2.5-3 GB of RAM, we'll need to cheat a bit here.

We'll take advantage of the fact that BIND in recursive resolver mode caches the results of lookups, so the next time to do a query for the same domain name, it returns the IP address without needing to do the whole recursive query again.

First, start up backbone1, backbone2, backbone3, rns, a.root-servers.sam, gateway.isp.sam, ns1.isp.sam, dns1.isp.sam - on my computer, this takes about 1.1 GB of RAM.

From dns1.isp.sam, do

dig mail.isp.sam

dig -t MX isp.sam

This simply has dns1.isp.sam ask itself for the IP address of mail.isp.sam, then caches it. It does the same for isp.sam's MX record (for the mailserver).

Now, shut down ns1.isp.sam, and start gateway.isp2.sam, router1.projreality.sam, firewall.projreality.sam, and ns1.projreality.sam - this increases memory usage to about 1.5 GB of RAM.

Now, from dns1.isp.sam, do

dig mail.projreality.sam

dig -t MX projreality.sam

Note - if you repeat the previous lookup for mail.isp.sam, you'll still get an answer, even though ns1.isp.sam is now down.

Now, start up dns1.projreality.sam - this increases memory to 1.7 GB of RAM.

From dns1.projreality.sam, do

dig mail.projreality.sam

dig -t MX projreality.sam

Now, shut down ns1.projreality.sam and let it completely shut down before restarting ns1.isp.sam - memory usage should remain about the same or possibly go down a bit.

Now, from dns1.projreality.sam, do

dig mail.isp.sam

dig -t MX isp.sam

If your computer survived so far memory-wise, we've got all we need, so go ahead and shut down ns1.isp.sam, rns, a.root-servers.sam, backbone2, backbone3, then start up mail.isp.sam, mail.projreality.sam, and customer

Now that the mailservers can look up their own addresses, we can start up Apache on both of them (if they weren't started earlier).

On the customer VM, start up X:

startx

After X starts up, start Firefox.

At this point, my computer is saying that 1.8 GB of RAM (out of 2 GB) is being used, and it is just starting to swap to disk.

In Firefox, navigate to https://mail.isp.sam/squirrelmail and log in as sam@isp.sam (the password we set was "sampassword").

Compose a new message to sam@projreality.sam, and write something distinctive in the title and/or contents.

Open up another tab in Firefox and navigate to https://mail.projreality.sam/squirrelmail - log in as sam@projreality.sam (same password as before). You should see the e-mail that you sent!

As a further test, you should be able to send a reply back to sam@isp.sam and see it in the Squirrelmail login for sam@isp.sam