How to setup a trivial forwarding mail server on a VPS

Switching to a virtual private server (VPS) from shared webhosting is a great way to improve performance, stability and security. For the most part, setting up the webserver and database is fairly routine and straightforward. However, setting up an email server is non-trivial.

It’s a lot of work to run a full mailserver (and which is why some webhosting companies recommend that you use a dedicated email service) but there are ways to setup a trivial mailserver that requires minimal maintenance. It simply accepts mail to various domains and then forwards them on to an actual mailserver.

For this example, we’ll have two domains running on our VPS: xxx.com and yyy.com

We’ll also have an “info” address at each domain that will be forwarded to xxx@gmail.com and yyy@yahoo.com

First, install a mailserver. I use the CentOS distribution which has the yum package manager. It’s as easy as:

  yum install exim

We need to create a file for each domain that we’ll be servicing.

Create a directory to hold our virtual hosts:

  mkdir /etc/exim/vhosts

Create a configuration file for each domain. Use the same format as the /etc/aliases format.

  # file:/etc/exim/vhosts/xxx.com
  info: xxx@gmail.com
  # file:/etc/exim/vhosts/yyy.com
  info: yyy@yahoo.com

We need to tell exim to use these files when delivering mail. Near the top of /etc/exim.conf there will be a domainlist line.

  # change...
  domainlist local_domains = @ : localhost : localhost.localdomain
  # to...
  domainlist local_domains = @ : localhost : localhost.localdomain : dsearch;/etc/exim/vhosts

Now exim will accept mail for our domains. To have it forward the mail correctly, add the following “router”. Look for begin routers. The first router is probably “dnslookup”. After this, add the following:

virtual:
  driver = redirect
  domains = dsearch;/etc/exim/vhosts
  data = ${lookup{$local_part}lsearch{/etc/exim/vhosts/$domain}}
  no_more

Restart (or start) exim to have these changes take effect.

  /etc/init.d/exim restart

MX Records for your domains

You have have a trivial mailserver. However, you need to specify that your server handles the mail for your domains. This is defined in the MX (Mail eXchange) record. To view the current setting:

  dig -t mx xxx.com

If the wrong address is returned (or no address) then you need to update your domain name servers. (Whoever provides you with domain name servers - typically your VPS provider or domain registrar - they should be able to set up MX records for you, or provide you with a tool so you can do this yourself.)

Testing and Debugging

If you view the exim log file, you can watch mail being processed.

  tail -f /var/log/exim/main.log

If mail is not being routed directly, or you want to see more info, the debugging feature of exim is helpful. You can activate this by passing in ‘-v’ flag when starting exim.

  exim -v -bd

The process will not disconnect from the terminal, so you can see how exim processes mail as it arrives.

Starting mailserver automatically

To make sure that exim is started as part of the boot process, you can mess with the symbolic links under /etc/rc.d or use this helper tool:

  chkconfig exim on


If you’re looking for a good VPS, I highly recommend Slicehost. Their 256MB slice is $20USD/month is amazing. I love it.

No Comments »

Posted by Jason Moore on Wednesday, 5-Nov-2008 at 9:41 and is filed under Tips.

Paypal Alternatives – Courtesy of Paypal!

It seems that Paypal has realized that they could be doing a much better job. Recently, they send me a developer survey to find out what they could improve. Maybe they already know that it is incredibly difficult and frustrating for an average person to make a payment with paypal, and simply want to get developers to verify this? Anyways, it was a typical survey, but one question stood out. They wanted to know how much experience developers had with other payment processors, and they listed them!

There were lots of companies I hadn’t heard of. Here they are, courtesy of Paypal:

Amazon Flexible Payment Service
Google Checkout
Bill Me Later
Authorize.net
2checkout
Nochex
CyberSource
WorldPay
Bibit
Protx
SecPay
Secure Trading
Datacash

So, if you’re looking for Paypal alternatives, this is a great list to start with.

1 Comment »

Posted by Jason Moore on Friday, 20-Jun-2008 at 8:10 and is filed under Tips.

Tips for configuring Apache’s mod_rewrite

Nice URLs are good interface design. But, it can be a struggle to get nice-looking urls with Apache.

I just spent a frustrating hour fighting with Apache’s mod_rewrite. There doesn’t seem to be a way to add commentary to the documentation, so I thought I would document a few tips here.

TIP #1: Check that .htaccess is being read and mod_rewrite is available

All of the apache configuration directives are contained in files named .htaccess. To check that Apache has been configured to read these files, add the following to the .htaccess in your webserver’s document root directory.

RewriteEngine On
RewriteRule ^foo$ rewriting-is-working

Go to the url http://site.com/foo and you should get a 404 error message like, “The requested URL /rewriting-is-working was not found on this server.” That’s good. mod_rewrite is installed and activated. It just needs to be configured.

If you only see a “Not Found” error message with no mention of “rewriting-is-working”, then it might be that your .htaccessfile is not being read at all.

An easy way to check if the .htaccess files are being parsed is to put an invalid entry in the file at the root level. If you get a server error, then we know the file is in use.

# the next line is not valid. We should get a 500 Server Error.
Foo

If you don’t get an error, then you need to allow the webserver to be configured with .htaccess files. This is done in the main server config (usually /etc/httpd.conf or /etc/apache/httpd.conf) and if you are on a shared webhost, you will have to ask the administrator to set this up. It will look something like…

# file: /etc/httpd.conf
#
<Directory "/public_html">

AllowOverride FileInfo
# or if you want to do anything in .htaccess:
# AllowOverride All
</Directory>

(And of course, after any httpd.conf change, restart the webserver. sudo apachectl restart )

TIP 2: Redirects must have different names than files and directories

This was a huge stumbling block for me. The filesystem takes precedence over the URL rewriting. Consider this example:

FILE:
public_html/about/us.html

URL:
http://site.com/about/us.html

DESIRED URL:
http://site.com/about

HTACCESS:
public_html/.htaccess

This is not possible. Apache will go into the “about” directory and will never see the Rewrite directive at the root level.

The best solution is to rename “about” something like “_about” and then add the following rewrite rules:

RewriteEngine On
RewriteRule ^about$ /_about/us.html
# - and if you need the old URL to work...
# RewriteRule ^about/us.html$ /about/us.html
# - or if there are other files under /about ...
# RewriteRule ^about/(.+)$ /_about/$1

TIP 3: The URL your pattern sees is relative to the current directory

If your .htaccess is in a subdirectory, the Rewrite rule cannot see the entire URL. Consider this example:

FILE:
public_html/content/news.php

URL:
http://site.com/content/news.php

DESIRED URL:
http://site.com/content/latest

HTACCESS:
public_html/content/.htaccess

The rewrite rule in the .htaccess file doesn’t “see” the “content” part of the URL. To get the desired URL, the pattern is ^latest$ (Not: ^content/latest$!)

RewriteEngine On
RewriteRule ^latest$ news.php

TIP 4: use minimal options

When nothing is working, it’s tempting to just start sticking various options to RewriteRule to see what happens.

The options that you can pass to RewriteRule are a bit cyptic. They are:

[L] = Last rule. If there is a match then stop processing further Rewrite rules.
[QSA] = Query String Append. Useful for scripts that receive parameters via a GET (foo.php?id=123&name=joe) and you simply want to pass them on.
[PT] = Pass through. Mostly used in combination wiAfter a match, pass through to the other handlers. U
[R] = Redirect. Send the rewritten URL back to the browser, which the browser automatically loads. The new URL is visible to end-user.

The [L]ast rule is a nice optimization if you have several rules, since the server won’t continue to match rules that you don’t need or want. Having rules that call other rules seems like a recipe for spaghetti code. For example, this is possible:

RewriteEngine On
RewriteRule ^xxx$ yyy
RewriteRule ^yyy$ zzz
RewriteRule ^zzz$ news.php

“xxx”, “yyy” or “zzz” would all take you to “news.php”. Useful? Maybe. It’s certainly convoluted.

Here’s how you add an options to your rule.

RewriteEngine On
RewriteRule ^latest$ news.php [L]

[QSA] is only useful if you have a script that receives input multiple variables via a GET request. Assuming that news.php takes several parameters…

RewriteEngine On
RewriteRule ^latest$ news.php [QSA,L]

[PT] is only useful if you want mod_alias to process the URL afterwards. (But why not just write the URL correctly the first time?)

TIP 5: Use simple patterns

The regexp operator \d which normally matches all digits, doesn’t work! I figured this was a fairly basic to any regular expression engine, but it must be a perl extension. Anyways, keep it simple. If your regexp doesn’t work, simplify it to the basics.

URL:
http://site.com/_item.php?id=123

DESIRED URL:
http://site.com/item/123

# Bad: Does NOT work!
RewriteRule ^item/(d+) _item.php?id=$1

# Good
RewriteRule ^item/([0-9]+) _item.php?id=$1

No Comments »

Posted by Jason Moore on Saturday, 2-Feb-2008 at 18:36 and is filed under Tips.

Ontario Air Quality Index (AQI) Widget

A few years ago the Ontario government built a website to inform people about the quality of air in their region. I remember reading about it and thinking that this type of information would be the perfect for displaying using an ambient interface. Then I forgot all about it.

Yesterday, I stumbled onto a Dashboard widget that scrapes the Air Quality Index (AQI) from the government website and displays it in a lovely, shiny gel tile. But it didn’t work.

So, I poked around and found that Apple’s Widgets are just like Konfabulator’s widgets, which I had messed around with ages ago. It is just a directory that contains some images, css and javascript. I changed the widget to scrape the RSS feed instead of the webpage, simplified the pattern matching and made a few layout tweaks so a pollution source like “Fine Particulate Matter” still fits on the screen.

I sent a copy back to the original author, but since I’m not sure if or when I’ll hear back from them, I’m posting my new version here.

AQI Widget screenshot

Ontario Air Quality Index widget

(For Dashboard, which is part of Mac OS X 10.4 or 10.5)

7 Comments »

Posted by Jason Moore on Wednesday, 23-Jan-2008 at 9:23 and is filed under Toronto, UI.

Protected: Browser Activity: When to provide explicit status feedback

This post is password protected. To view it please enter your password below:

Enter your password to view comments

Posted by Jason Moore on Thursday, 25-Oct-2007 at 10:16 and is filed under General.