Archive for April, 2009

What is a DRD

Wednesday, April 29th, 2009

I have Google’d around asked a lot of smart people and still can’t come up with a solid answer. More specifically, the question I have is:

Why, when sending emails to certain domains, do I get the error: 451 Could not load DRD for domain

Because I deal with fairly large mailing lists, I see odd errors a lot. Most of them I can disregard. In any case in which I see an error over 1,000 times, I make it a policy to deal with it. I have seen one close to 9 million.

It appears to be an error from a Symantec appliance, but people write about it coming from Exchange servers as well.

If anyone has any idea what this, please email me, leave a comment, or post a link to somewhere.

Reminder Trick With Quicksilver

Tuesday, April 28th, 2009

I have a few tools for making and keeping myself more productive. One of those tools is Quicksilver. I know it is a widely used tool so I won’t spend time talking about everything it can do. However, from the Blacktree website, it is:

A unified, extensible interface for working with applications, contacts, music, and other data.

I like to be reminded of things, but I usually hate putting them into Entourage or Things (which I will definitely be covering in a future blog post). A shortcut using Quicksilver is to do the following:

  1. Initiate Quicksilver (in my case): CTRL-SPACE
  2. Type the ‘.‘ to enter text mode
  3. Enter your reminder message: Relax your eyes
  4. Press TAB and select Large Type
  5. Press CTRL-Enter and select a period
  6. For testing, use Run After Delay and Tab over to the third box
  7. Enter an element of time. Again for testing, we’ll use 5s (the ‘s‘ being seconds) and press enter.

And there you have it. It will appear before your eyes 5 seconds after pressing enter. Just remember, there is no stickiness with Quicksilver. If it closes for any reason (computer restart, Quicksilver crash, etc), your reminder is gone with it.

Recent Twitter Related Learning

Thursday, April 23rd, 2009

I’ve been using Twitter for a few weeks now and am starting to get used to some of the concepts. I have since also been reminded of a little of the RTFM concept mixed with the takes the experts with a grain of salt.

I started out reading some information given by Brent Ozar on his blog. These are 3 articles that kicked me off in the right direction:

  1. Twitter 101
  2. Top 10 Reasons I’m Not Following You On Twitter
  3. Top 10 Reasons I’m Following You On Twitter

That’s when I was reminded by Ryan Maplethat sometimes, depending on the people, those may be the opposite reasons. To be more specific, Ryan won’t follow people if they are consistently tweeting the fact that they have just put up a new blog post. (Although I am guilty of this every so often).

But I think the biggest element of Twitter that has since caught me off guard is the massive amount of information at ones disposal. For instance the yellow pages or wefollow.com can provide you with people to follow based on your interests. I have learned so much about things in my field just by following links that people re-tweet.

So if you are like I was and being a Twitter luddite, you may want to rethink it. I am consistently looking for more ways to make it useful too. So if you have something, let me know.

Setting Up DKIM and Postfix on CentOS 5.2

Monday, April 20th, 2009

I spent a while trying to set up DKIM with Postfix on CentOS 5.2. I read the HOWTOs on HOWToForge written by Andrew Colin Kissa (aka TopDog) who subsequently helped me towards getting this setup working.

My setup is that I have a mail spooler and multiple mail senders. This is to say that the emails are created on spooler.domain.com and sent via sender1.domain.com and sender2.domain.com. I will walk through how to setup DKIM on the sender machines so that all mail spooled from the spooler still gets signed.

First start out by installing DKIM. At the time the HOWTO was published, I downloaded the RPM from Topdog.

1
2
3
4
5
6
[root@sender1 dkim]# wget http://www.topdog-software.com/oss/dkim-milter/dkim-milter-2.8.2-0.$(uname -i).rpm
...
[root@sender1 dkim]# rpm -Uvh dkim-milter-2.8.2-0.x86_64.rpm
warning: dkim-milter-2.8.2-0.x86_64.rpm: Header V3 DSA signature: NOKEY, key ID 990dd808
Preparing...                ########################################### [100%]
   1:dkim-milter            ########################################### [100%]

Once you have installed DKIM you have to create the public and private keys. Do this using the dkim-genkey.sh shell script.

1
[root@sender1 dkim]# sh /usr/share/doc/dkim-milter-2.8.2/dkim-genkey.sh -r -d yourdomain.com

By running this script, 2 files will be generated; default.txt: the public key which gets published via DNS; default.private: private key used for signing the emails.

Move the private key to the dkim directory and secure it.

1
2
3
[root@sender1 dkim]# mv default.private /etc/mail/dkim/default.key.pem
[root@sender1 dkim]# chmod 600 /etc/mail/dkim/default.key.pem
[root@sender1 dkim]# chown dkim-milt.dkim-milt /etc/mail/dkim/default.key.pem

Now create the DNS entries. The p= section is the public key created using the dkim-genkey.sh script. Don’t forget to increment the SOA and reload DNS.

1
2
_ssp._domainkey.yourdomain.com      TXT t=y; o=-
default._domainkey.yourdomain.com   TXT v=DKIM1; g=*; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GWETBNiQKBgQC5KT1eN2lqCRQGDX+20I4liM2mktrtjWkV6mW9WX7q46cZAYgNrus53vgfl2z1Y/95mBv6Bx9WOS56OAVBQw62+ksXPT5cRUAUN9GkENPdOoPdpvrU1KdAMW5c3zmGOvEOa4jAlB4/wYTV5RkLq/1XLxXfTKNy58v+CKETLQS/eQIDAQAB

The reason for this peer_list file is so that the senders know that its ok for them to sign emails relayed via the spooler.

1
2
3
4
5
6
7
8
9
[root@sender1 dkim]# cat /etc/mail/dkim/peer_list
mail.yourdomain.com
spooler.yourdomain.com
sender2.yourdomain.com
1.2.4.7
1.2.4.5
localhost
localhost.localdomain
127.0.0.1

Onto the configuring of the system. It should look something like the following. I chose to have the port be a local port, but it could be done via a network connection as well. Ensure you change the SIGNING_DOMAIN variable and be sure to note the EXTRA_ARGS variable and where PEER_LIST is used.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@sender1 dkim]# cat /etc/sysconfig/dkim-milter
# Default values

USER="dkim-milt"
PORT="local:/var/run/dkim-milter/dkim.sock"
SIGNING_DOMAIN="yourdomain.com"
SELECTOR_NAME="default"
KEYFILE="/etc/mail/dkim/default.key.pem"
SIGNER=yes
VERIFIER=yes
CANON=simple
SIGALG=rsa-sha1
REJECTION="bad=r,dns=t,int=t,no=a"

PEER_LIST="/etc/mail/dkim/peer_list"

EXTRA_ARGS="-h -l -D -i ${PEER_LIST} -I ${PEER_LIST}"

Let’s start up dkim. Since it is a daemon running separately from Postfix, running it and restarting it won’t affect mail (yet).

1
[root@sender1 dkim]# /etc/init.d/dkim-filter start

And it’s finally time for Postfix. You need to add 2 simple lines to your Postfix main.cf. These 2 lines should match the PORT variable in the dkim-milter.conf sysconfig file.

1
2
smtpd_milters = local:/var/run/dkim-milter/dkim.sock
non_smtpd_milters = local:/var/run/dkim-milter/dkim.sock

Now you’re asking yourself, how do I test this? The easy answer is to use a Gmail account. When you receive an email, click on the show details link on the right hand side of the screen (to the left of the time). If you have performed this sequence correctly, you will see a line that says:

1
signed-by   yourdomain.com

Another way to test the success of this is to view the source of the email. You should have some lines that look similar to this:

1
2
3
4
5
6
7
8
9
X-DKIM: Sendmail DKIM Filter v2.8.2 sender1.yourdomain.com 75866730012
DKIM-Signature: v=1; a=rsa-sha1; c=simple/simple; d=yourdomain.com;
    s=default; t=1239981026; bh=+NNkD6jOlYKtY2AIGNRToH2tkm0=;
    h=Date:List-Help:List-Subscribe:List-Unsubscribe:List-Owner:
     List-Post:From:Reply-To:To:Subject:MIME-Version:Content-Type:
     Message-Id;
    b=MrjXBShjNexWy62fC4Uu7xS3Hxav+cHtqIBzwMlcufadsffLtW9KmF5sO58+yHjyy
     I3SiX0TNyEbvXtSHvRKm9z630zDiN0dxVXGqhgEfdklaj4jlkfhR6GrsRgzW2YOW6/9
     sKFnz214AkhAPrFBD30hNmZfRfY75v5q94FnGDUo=

Congratulations, you have a working DKIM installation.

Testing For A Number

Thursday, April 16th, 2009

Although you generally don’t have to worry about types in Perl, it is occasionally necessary to ensure that you are working with numbers. Your test cases should notify you that something is amiss when you didn’t get a number (when you were expecting one). Thankfully Scalar::Util provides a method to deal with this.

1
2
3
4
5
6
7
use Scalar::Util qw( looks_like_number );

my @possibleNumbers = qw(1 5.25 word 4);

foreach my $nums (@possibleNumbers) {
       print "$nums is", looks_like_number($nums) ? '' : ' not', " a number\n";
}

This will print:

1
2
3
4
1 is a number
5.25 is a number
word is not a number
4 is a number

This neat little method takes advantage of Perl C API’s looks_like_number() function. Since this is virtually native, it will be pretty fast.

Cleaning Up Long Conditionals With Grep

Tuesday, April 7th, 2009

Every so often I am faced with testing a few conditionals before dropping into another control structure. If you have to test out a few conditionals, then its likely a dispatch table won’t be useful. If you have a lot of conditionals to test, you’ll likely not want to deal with an ugly expression like the following:

1
2
3
4
5
6
if ( (defined $SITE{$partner}{'foo'} && ($SITE{$partner}{'foo'} > 0) ) and
        ( (defined $assoc{'foo'} && ($assoc{'foo'} > 0)) or
          (defined $assoc{'bar'} && ($assoc{'bar'} > 0)))
   ) {
print "We're here!\n";
}

One of the ways to deal with it to to use grep. Since grep returns the number of elements in the array that evaluate to true (when called in a scalar context), I can do the following to make it work:

1
2
my @foo = [ $SITE{$partner}{'foo'}, $assoc{'foo'}, $assoc{'bar'} ];
if ( (grep {defined($_) and $_ > 0} @foo) > 2) { print "We're here!\n"; }

The reason this works is that when called in the scalar context, grep only returns the number of elements that evaluate to true. Since there are 3 elements in the array, the return value is greater than 2, then the entire expression evaluates to true. This is not only a lot easier to read and a lot cleaner to write, but it makes for easy additions to the conditional testing if necessary. Although changing the context in which functions are called is common, it is easily forgotten. Grep called in scalar context can be easily manipulated (as above) to add readability to your program.

Counting Email Addresses By Domain in MySQL

Wednesday, April 1st, 2009

Every so often I find some statistical need that although Perl program would be easy to write for it, its probably something the database should just handle. So I have a column in an email management table that has just the email addresses in the format user@domain.tld.

I want to know which domains make up the majority of the users. (The numbers have been changed to protect the innocent):

mysql> SELECT SUBSTRING_INDEX(email, '@', -1) as Domain, count(*) as Total
      FROM email_list
GROUP BY Domain
ORDER BY Total DESC
       LIMIT 15;
+----------------+---------+
| Domain         | Total   |
+----------------+---------+
| yahoo.com      | 1304000 | 
| hotmail.com    |  908400 | 
| aol.com        |  800000 | 
| msn.com        |  168000 | 
| gmail.com      |  161000 | 
| comcast.net    |  143000 | 
| sbcglobal.net  |  110000 | 
| bellsouth.net  |   62000 | 
| cox.net        |   58000 | 
| verizon.net    |   56000 | 
| earthlink.net  |   52000 | 
| charter.net    |   46000 | 
| juno.com       |   30000 | 
| optonline.net  |   22000 | 
| netzero.com    |   17000 | 
+----------------+---------+