My email setup
It all started when I graduated from CMU. I had four months before my computer account (and email address) would be terminated. Knowing that this would cause huge amounts of pain, I made the decision that this would be the last email-address-change of my life and used clickngo to buy megacz.com.
I wanted to host mail and www services on this domain, as well as have a shell account that I could access to do random hacking (not cracking, you dimwit, get it straight). I also wanted to be able to ssh to megacz.com and read my mail from there, so that even if my personal network connection went down, I could find the nearest alternate net connection and still get to my mail. I also wanted my own IP address for megacz.com in case I wanted to run miscellaneous services in the future. Last of all, the host for megacz.com had to be reliable.
I used eggdrops.com, shellaccounts.com and various other resources to shop for shells. Eventually I settled on tasam.com due to their excellent reputation and long history in the business. I pay $20/month for all the features mentioned above on a FreeBSD box that comes with a highly skilled and patient admin team.
My first order of business was to get CMU'sn Cyrus Server working so I could use it to read my mail. I've become very attached to this server since it's blazingly fast (due to a heirarchical mailbox format instead of the crufty outdated /var/mail/ format), and it supports pretty much every feature mentioned in the RFC.
Unfortunately, cyrus makes the assumption that you have root on your machine in order to install it. Furthermore, unless you plan on setting up your own kerberos realm or a custom sasl database, it assumes that you're using /etc/passwd as a list of users and passwords. Tasam uses shadow passwords, and cyrus wouldn't be setuid root, so it can't read the passwd file.
So, over the course of four painful days, I hacked cyrus-imapd and cyrus-sasl into a form that could be installed by a non-root user, run as a non-root user, and would accept a login only from a single user (with the password hardcoded into the csource code). I then wrote a perl script that will download, patch, and compile cyrus and sasl, and then install it in your home directory. It will also download inetd and set it up to run imapd on the mmcc port (port 5050), since non-root users can't run services on priviledged ports (<1024). You can find that script here. Just run it for instructions.
Finally, I put the lines:
in my .procmailrc. This runs all my email through fixdeliver.pl, which strips off the first line (a header that sendmail tacks on for the /var/mail mailbox format) and then pipes the mail into cyrus' “deliver” command. The “c” on the :0 line makes sure that a copy of each mail is ALSO delivered to my /var/mail mailbox, just in case I somehow goof things up with my cyrus configuration.
My admin was kind enough to install emacs for me – sadly the rest of the users on tasam are more-or-less microsoft-loving-gatesworshipers, and none of them ever asked for emacs. Heathens.
I use gnus with the nnimap mode to read imap folders as if they were newsgroups. This affords me an easy-to-use unified mail-and-news setup with built-in mailing list filtering (puts my mailing lists in their own folders), PGP integration, and the full power of emacs when composing my emails.
Inbound mail handling for the megacz.com domain
Now I needed a way to implement mailing lists and redirection for megacz.com. I wanted to give out addresses to my family (as email@example.com), and additionally create an alias as a mailing list that would send to all four of us. Plus I wanted to be able to give out random accounts to my friends.
The Right Way ™ to do this is to set things up in sendmail. Unfortunately, I don't have root on the machine, so I can't do that. And I don't want to bug the admin every time I need a change. So the admin set it up so that all mail for megacz.com got delivered to my local shell userid, and advised that I use procmail.
I quickly discovered that if you try to match on the headers of an email, you run into a few problems. These problems are detailed in the advanced section of the Procmail FAQ. I strongly recommend that you read at least that section if you're interested in doing stuff like this.
Briefly, here are the problems with using procmail to do stuff like what I was trying to do (also see Why Headers Don't Matter:
My first attempt at fixing this was the approach that fetchmail uses, which I found here. I had the admin add the following line to his sendmail.cf file:
I then put this lines like this in my .procmailrc:
This worked for a while, until ran into a problem. Sendmail will set $u to the empty string if a message's envelope (MAIL FROM) specifies two users on the same system. This is to prevent a mail sent to one user and BCC'd to another user from arriving with the BCC'd user's userid on it. A more complete description of the problem can be found in this post to comp.mail.sendmail.
So I finally broke down and researched sendmail's mailertables – it's a way to get mail for a given domain to completely bypass sendmail and be forwarded to a program of your choice, including the envelope. To do this, we had to add these two lines to our sendmail.mc file
Then execute this command (note that it only works if you have an echo command that interprets \t as a tab character when the -e option is enabled.)
echo -e "megacz.com\tprocmail:/home/adam/.procmailrc" | makemap btree mailertable
Finally, you can now filter based on the envelope sender and reciever like this:
SENDER = $1
RECIPT = $2
* RECIPT ?? ^joe$
! -f $SENDER firstname.lastname@example.org
I just colocated a machine in Baltimore, so I now have full control over the mail server config. In the interest of simplicity, I took a vanilla RedHat 7 install and:
Added a pair of lines to my /etc/mail/mailertable for each domain I host:
NOTE that's a TAB, not a space on those lines!
Finally, this is how to get sendmail to invoke procmail.
I'll put a better description in here when I have time (ie never).