Tag Archives: centos

One of the most common issues I see that affects my clients is the: “Yahoo/Gmail/Hotmail is sending all of my mail straight to the spam folder despite ‘insert usual DNS and config details here'” issues, so I spent some time researching a solution that would be relatively quick and painless to implement. I found it, but it only works with a straight postfix box. This will not work for Plesk servers, qmail, sendmail, etc. So if you’re running a centos or RHEL box with postfix and want DKIM/domainkeys signing? Here’s an article for you.

In particular, Yahoo seemed to be the most stringent defender of the DKIM/domainkeys/SPF rules (and thus a lot of spamming of mail going on), so…..Yahoo became sort of my “litmus” test for DKIM/domainkey/SPF configuration. If it works there, it is going to work everywhere else. This has also been generally true in my experience. Your mileage may vary.

Please note: This is NOT a cut and paste document. This is meant as a guide that should get you from point A to point B pretty painlessly. However, every dkimproxy install I’ve done has differed just slightly from one detail to another. So be prepared to do a little thinking on your feet. I’ve tried to include most of the “gotchas”, but there’s always something.

Prepare to install

This is actually the “hardest” part of the install for dkimproxy. It has varied for just about every system I’ve done to date and is purely a question of searching the DAG repositories for the RPMs you need to meet the base requirements of the required packages if it isn’t available via YUM.

So, to start with….you need to install the following RPMs:

perl-Crypt-OpenSSL-RSA
perl-Digest-SHA
perl-Error
perl-Mail-DKIM
perl-MailTools
perl-Net-Server
openssl-devel

As of May 30th, 2011 I found all of the above packages on yum for centos 5. RHEL 5 and earlier versions of both may still require a visit to DAG to get the packages that may not be available in those OS versions. Edit: 12/2011 – I just did this install on a RH ES5.6 server and all of the above perl rpms were in the epel-release. Edit: 8/2014 – I just did this on a Redhat 6.1, the packages were still there in both the base channel and epel-release for perl-Net-Server.

These installs could give you some dependency errors. As I said, it is a little different for each server (mostly due to a question of how long the server has been online and what has been installed on it and how old the OS is). Every requirement I’ve had to fill can be met by searching yum/up2date and/or the package list at DAG. Follow the chains and install the required packages. It is better for your system overall that you try to install any package from yum/up2date before you go trying to install a DAG rpm.

Once you have the base packages listed above installed (with no further dependency issues), you are ready to proceed onward.

 

Obtain and compile dkimproxy

Note! The wget statement below was current as of May 30th, 2011. It may have changed. Always go here and make sure you are downloading the most current version of DKIMproxy.

wget http://downloads.sourceforge.net/project/dkimproxy/dkimproxy/1.4.1/dkimproxy-1.4.1.tar.gz?r=http%3A%2F%2Fdkimproxy.sourceforge.net%2Fdownload.html&ts=1306808396&use_mirror=cdnetworks-us-1
tar -xvzf dkimproxy-1.4.1.tar.gz
cd dkimproxy-1.4.1
./configure –prefix=/usr/local/dkimproxy
make
make install

Then we place the init script:

cp sample-dkim-init-script.sh /etc/init.d/dkimproxy
chmod +x /etc/init.d/dkimproxy

and create the DKIM user:

useradd -d /usr/local/dkimproxy dkim
passwd -l dkim

From there, we create the Key:

cd /usr/local/dkimproxy/etc/
openssl genrsa -out domain.tld.key 1024
openssl rsa -in domain.tld.key -pubout -out domain.tld.pub

Obviously, replace domain.tld with the domain the client is wanting to sign. If they plan to sign multiple domains with a single key, this is fine and you may wish to make the key name more generic rather than domain specific.

Now create a DNS TXT record for mail._domainkey.domain.tld with the contents of domain.tld.pub. Your public key will span at least two lines, so combine all of the lines of the key together when putting it in your DNS record. The whole DNS record will look something like this:

k=rsa; t=s; p=MFwwDQYJ..(snipped for space)….0JMCAwEAAQ==

I’ve shorted the key here for space/display reasons. It will be pretty long.

You can test to see if the key is working like this:

# host -ttxt mail._domainkey.domain.tls
mail._domainkey.domain.tld descriptive text “k=rsa\; t=s\; p=MFwwDQYJ……0JMCAwEAAQ==”

Now to set up the config files. Tell dkimproxy about the key files, and configuration parameters. Create /usr/local/dkimproxy/etc/dkimproxy_out.conf with this content

# specify what address/port DKIMproxy should listen on
listen 127.0.0.1:10027

# specify what address/port DKIMproxy forwards mail to
relay 127.0.0.1:10028

# specify what domains DKIMproxy can sign for (comma-separated, no spaces)
domain domain.tld

# specify what signatures to add
signature dkim(c=relaxed)
signature domainkeys(c=nofws)

# specify location of the private key
keyfile /usr/local/dkimproxy/etc/domain.tld.key

# specify the selector (i.e. the name of the key record put in DNS)
selector mail

Please note, if you are doing a multiple domain set up with a single key, you can list each domain as “domain domain1,domain2,domain3” a comma separated list.

Now copy the sample inbound config to the real inbound config

cd /usr/local/dkimproxy/etc
cp dkimproxy_in.conf.example dkimproxy_in.conf

Start the service

/etc/init.d/dkimproxy start
chkconfig dkimproxy on

 

Configuring Postfix to use DKIMproxy

You must add the following entries to the bottom of the /etc/postfix/master.cf file:

# specify the location of the DKIM signing proxy
# Note: the smtp_discard_ehlo_keywords option requires a recent version of
# Postfix. Leave it off if your version does not support it.
dksign unix – – n – 10 smtp
-o smtp_send_xforward_command=yes
-o smtp_discard_ehlo_keywords=8bitmime,starttls

# service for accepting messages FROM the DKIM signing proxy
127.0.0.1:10028 inet n – n – 10 smtpd
-o content_filter=
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
-o smtpd_helo_restrictions=
-o smtpd_client_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks=127.0.0.0/8
-o smtpd_authorized_xforward_hosts=127.0.0.0/8

Then, depending on WHAT messages your client wants signed, you need to add the line

-o content_filter=dksign:[127.0.0.1]:10027

to that part of the service. So, for example, if they want anything submitted to port 25 signed:

smtp inet n – n – – smtpd
-o content_filter=dksign:[127.0.0.1]:10027

If they want script created mail to be signed:

pickup fifo n – n 40 1 pickup
-o content_filter=dksign:[127.0.0.1]:10027

Mail to port 587 to be signed:

submission inet n – n – – smtpd
-o smtpd_etrn_restrictions=reject
-o smtpd_sasl_auth_enable=yes
-o content_filter=dksign:[127.0.0.1]:10027
-o receive_override_options=no_address_mappings
-o smtpd_recipient_restrictions=permit_mynetworks,permit_sasl_authenticated,reject

Note: The spacing before the -o is being pulled out by the blog software, even with the code tag. Look at how the rest of the entries in your master.cf file look and emulate that where the -o lines are indented. That matters! And a lack of such indenting will prevent postfix from working properly.

There’s obviously more there than just the dksign line, due to the nature of that port in that last one.

From there, reload postfix (make sure it starts and continues to be able to send mail. I tend to do both command line tests as well as pop/imap checks for the rack user).

service postfix reload

 

Testing DKIM signing

Now that all of that is in place, you can now do some tests.

The easiest way to do this, if the server is not doing any sort of mail redirection, is to set up the testing@domain.com account in your mail client so you can both send the test messages as well as check and see the reply emails.

I use two primary tests. One, I send a mail (with any subject, any body) to dk@dk.crynwr.com. This returns 4 (at the moment) test results. You can pretty easily see from these 4 messages what is working and what isn’t.

The second test I use is to check the SPF record, because most services will fail dkim/domainkeys if the SPF record is invalid for the sent mail. So send a test message to spf-test@openspf.org. It will be rejected WITH the response, so watch the log file on the server to see if the SPF record passed correctly.

Finally, I create a php script to generate a mail to my yahoo account to see if it gets through with the DKIM/domainkey/SPF pass. You can use something like:

and invoke it via a browser or by the command line:

php /path/to/phpmail.php

Tweak and resolve any issues you came across in the testing until you get clean results for DKIM, Domainkeys, and SPF. At that point, I generally send an email to myself at my yahoo account. If you see the little key/lock icon on the “from” line of the email (and it isn’t in the spam folder)? You’ve successfully set up and configured DKIM/Domainkeys. If it IS in the spam folder? Check the header to see where to go next. As I said, the most common reason it fails is the SPF record in my experience.

Hopefully this article has been helpful at getting you to get your DKIMproxy install up and going.


Category: linux, mail

These days, I am finding it harder and harder to justify mod_php as the default behavior of an apache webserver over the advantages of mod_suphp. A lot of this has to do with my clients and their everyday needs, but I’ve become a pretty strong proponent of mod_suphp as the default for a server and only enabling mod_php if required.

It’s actually pretty easy to do, surprisingly. suPHP used to be a process that involved sacrificing chickens in the midnight hours to get to work correctly. Now? All it takes is the below. I’ve included instructions for centos and ubuntu both.

 

Centos

yum install mod_suphp
mv /etc/httpd/conf.d/php.conf /root/saved.conf/

Obviously the path /root/saved.conf/ can be wherever you want to put the original php.conf file. I suggest saving it somewhere in case you need it in the future to specifically enable mod_php for a site. Then you need to modify the file /etc/httpd/conf.d/mod_suphp.conf to look like:

# This is the Apache server configuration file providing suPHP support..
# It contains the configuration directives to instruct the server how to
# serve php pages while switching to the user context before rendering.

LoadModule suphp_module modules/mod_suphp.so

### Uncomment to activate mod_suphp
AddHandler x-httpd-php .php .php3 .php4 .php5
suPHP_AddHandler x-httpd-php

# This option tells mod_suphp if a PHP-script requested on this server (or
# VirtualHost) should be run with the PHP-interpreter or returned to the
# browser “as it is”.
suPHP_Engine on

# This option tells mod_suphp which path to pass on to the PHP-interpreter
# (by setting the PHPRC environment variable).
# Do *NOT* refer to a file but to the directory the file resists in.
#
# E.g.: If you want to use “/path/to/server/config/php.ini”, use “suPHP_Config
# /path/to/server/config”.
#
# If you don’t use this option, PHP will use its compiled in default path.
suPHP_ConfigPath /etc

and then modify /etc/suphp.conf to change this line:

x-httpd-php=php:/usr/bin/php

to:

x-httpd-php=php:/usr/bin/php-cgi

Restart apache and then check a phpinfo page. You should see that the Server API line now reads: “CGI/FastCGI”.

 

Ubuntu

Ubuntu was actually much easier, surprisingly:

aptitude install libapache2-mod-suphp
a2enmod suphp
a2dismod php5

Restart apache and check your phpinfo page.

To be honest, given the way web applications function these days, I’m truly surprised that this hasn’t become default behavior for php at this point…that they have not absorbed the suphp project into their own work. Until that day comes, that’s all that is required to start running with your own suphp install.

Edit: Also, I’ve not tested this on RHEL, but given the way fedora/centos/RHEL works, you should be able to follow these instructions for that OS as well.


Category: linux, php

Ran into an interesting issue earlier tonight where a customer wanted the levenshtein UDF module (user defined functions) compiled for mysql on a centos5 64 bit box. While it seemed the module built correctly, he was still getting errors in trying to create and use the functions:

mysql> CREATE FUNCTION levenshtein RETURNS INT SONAME ‘libmysqllevenshtein.so’;
ERROR 1026 (HY000): Error writing file ‘mysql.func’ (errno: 121)

mysql> select levenshtein(‘abc’, ‘bbc’);
ERROR 1547 (HY000): Column count of mysql.proc is wrong. Expected 20, found 16. The table is probably corrupted

After some poking around, this is what was done that ultimately led to a successful implementation of this module:

wget http://joshdrew.com/mysql_levenshtein_udf-1.0.tar.gz

tar -xzvf mysql_levenshtein_udf-1.0.tar.gz

gcc -I/usr/include/mysql -fPIC -O -pipe -o mysqllevenshtein.so -shared \
-L/usr/lib64/mysql -lmysqlclient mysqllevenshtein.cc

cp mysqllevenshtein.so /usr/lib64/libmysqllevenshtein.so

Once that module is in place, restart mysql and log into it. If it is loading correctly, you should be able to do the following:

mysql> CREATE FUNCTION levenshtein RETURNS INT SONAME ‘libmysqllevenshtein.so’;

mysql> select levenshtein(‘abc’, ‘bbc’);
+—————————+
| levenshtein(‘abc’, ‘bbc’) |
+—————————+
| 1 |
+—————————+
1 row in set (0.01 sec)

The ultimate key here was using the correct libs, since most of the instructions out there on the net (due to the age of this module) assume 32bit. The resulting module, when compiled the way those instructions indicated, would load but not be functional. The above resolved the problem. I figured I’d document this here for others that are trying to compile it and having issues, in case it saves them some time. I’m always happy when folks try to do things themselves and am a little sad when the documentation for a given software fails them somewhat. The difference in libs may seem like a no-brainer to some, but for those just learning… well. Let’s put this out there in case it helps the next guy. 🙂


Category: linux, mysql

Categories


gives good tech

tech.superhappykittymeow.com
Kale is one of the smartest people I know

Racker Hacker
Major is always good for leet deetz