Friday, September 26, 2008

Quickie Mail Server Setup - Part II

We'll continue were we left off from Part 1, make sure that the www.exampledns.com and the "mx" record for the "exampledns.com" domain is resolving properly. We'll be setting up a secure IMAP server accessible either through any of the mail user agents (ie. Thunderbird, Evolution, etc) or a Web-based email system.

We'll be using OpenSSL package (should be installed by default) in our mail server setup. OpenSSL comes with a versatile tool for generating private/public keys and certificates. The idea is to encrypt (and sign) our data packets using OpenSSL cryptographic libraries before sending them over the network . OpenSSL is an implementation of SSL/TLS functionality, it mostly gained prominence for securing transaction for e-commerce web sites (ie. banks and web retailers like Amazon) but can also be use for host of other services.

SSL/TLS protocol works by means of PKI (Public Key Infastructure). Basically, in PKI, you have a private key and certificate/public key, PKI enables users to exchange these keys and certificates securely (the server initially send a certificate to the user to be authenticated, usually via third-party Certificate Authority CA). Once both sides have verified and exchange keys, communication is encrypted using these certificates.

NOTE: When dealing with PKI setup and to fully appreciate how SSL/TLS works, make sure that you have a passing familiarity on how asymmetric cryptography works.

There a 3 ways we can setup PKI
  • Using commercial Certificate Authority (CA) such as VeriSign, Thawte (there's free trial version available from VeriSign if you want to use one).
  • Web of Trust popularize by PGP/GnuPG. You can get free certificates from organization such as CAcert, a community-driven CA. If you don't mind the hassle (ie. users are verified) this is a good alternative to commercial CA.
  • Generate our self-signed certificate. Since this is the most convenient for us, we'll simply generate our own certificate.
With those out of the way, we'll now setup an encrypted mail service:

Step 1: Generate a self-signed certificate. We have two option here. We can use the Dovecot script /usr/libexec/dovecot/mkcert.sh or the Fedora /etc/pki/tls/certs/Makefile config (both script uses openssl behind the scene). Both automate the whole process of creating self-signed certificate for us but the Fedora Makefile script gives us more flexibility in creating certificates.
  cd /etc/pki/tls/certs
make dovecot.pem
Using make utility, we generated the dovecot.pem file that contains the private key and the certificate.

Step 2: Dovecot Configuration. Edit the /etc/dovecot.conf file and add the path for your private key and your certificate.
protocols = imaps pop3s
ssl_cert_file = /etc/pki/tls/certs/dovecot.pem
ssl_key_file = /etc/pki/tls/certs/dovecot.pem

Save and exit and then restart the Dovecot service. That's it!

Step 3: Test your encrypted IMAP service. Point your email client to your newly encrypted mail server, and that's it. I used claws-mail, it auto-negotiate the exchange of certificates. If you're using Thunderbird, Evolution or Kmail, you might need to manually enable the settings for SSL/TLS.

Step 4: Setting up Web-Mail. This is one of the few times that we'll install from the source rather than 'yum' install the package from Fedora repo (I still get a kicked out of installing from the source from time to time).
  • Get the Squirrelmail source here.
  • Install the Squirrelmail source.
Setup the Squirrelmail directory:
  mkdir /usr/local/src/squirrelmail
cd /usr/local/src/squirrelmail
mkdir data temp
chgrp apache
Note: Traditionally, /usr/local/src/ directory is where you install 'source' programs. The 'data' and 'temp' directory is where Squirrelmail will place your data and email attachment. And finally, 'apache' should be set as the group owner of the these directories.

Unpack the Squirrelmail source and run the Squirrelmail config tool:
  mv squirrelmail-X.Y.Z-tar.gz /usr/local/squirrelmail
cd /usr/local/squirrelmail
tar -xzvf squirrelmail-X.Y.Z-tar.gz
mv squirrelmail.X.Y.Z www
cd www/config
./conf.pl

Step 5: Setup Apache. In your /etc/httpd/conf/httpd.conf file, add the following settings:
  Alias /webmail  /usr/local/src/squirrelmail/www

<Directory /usr/local/src/squirrelmail/www>
Options Indexes
AllowOverride none
Order allow,deny
allow from all
</Directory>
Restart the Apache httpd service. Fire up your browser, point it to http://www.exampledns.com/webmail website and log in.

Note 1: Squirrelmail is written in Php . If you're encountering Php-related errors, check if Php package is installed.

Note 2: To avoid overly-complex, error-prone, multiple certificate-enabled server, revert Dovecot daemon back to using simple imap/pop3 protocol before setting-up an "https://" web server.

Step 6: Generate a server key and certificate for your web server (mod_ssl module handle the encryption for Apache and is normally bundled in).

But first, note that Fedora already comes with it own private key and certificate for Apache out of the box. And also Makefile generate them in pre-define directory (ie. /etc/pki/tls/{private/certs}/ ). If you would like to generate a new key/cert, you either have to rename/delete/move these old files.

rm -f /etc/pki/tls/certs/localhost.crt
rm -f /etc/pki/tls/private/localhost.key
cd /etc/pki/tls/certs
make genkey
cd /etc/pki/tls/private
By default, when you created the localhost.key it will prompt you for a pass phrase which is very annoying when you need to restart your Apache. To remove this pass phase after generating a new localhost.key,

cd /etc/pki/tls/private
cp localhost.key localhost.key-copy
openssl rsa -in localhost.key-copy -out localhost.key
We then create the certificate:
cd /etc/pki/tls/certs
make testcerts
A new localhost.crt will be generated. Restart you Apache and that's it! Point your browser to your new certificate-enabled web server and your browser should prompt you whether to accept

In Part III, we'll setup SpamAssassin and Anti-Virus using Clamav and Mimedefang.

Saturday, September 6, 2008

Quickie Mail Server Setup Tutorial using Sendmail, Dovecot, SquirrelMail, SpamAssassin on Fedora 8 (Part I)

Note: Make sure to check the conventions I use before going through the tutorial.

Hullo world! For this post, we'll setup a quickie mail server. The idea here as with most other post, is to setup basic mail server to get you going, so you can spend your time fiddling with advance setting rather than groping your way on how setup mail server. Note that a critical component (that we won't tackle here) is a working DNS setup. It's crucial that you have an MX record pointing to working domain. If you haven't setup one up yet, check this quickie post. Otherwise, you need to set one up before proceeding.

Also, we'll use the "exampledns.com" previously setup as example domain. Hostname of the machine that you working on is "node1.exampledns.com". You also have local user 'gene' and 'user1'

For this series of post, we'll setup the following:
- Sendmail
- Dovecot
- SquirrelMail
- SpamAssassin

Basic Setup of Sendmail:

Step 1: Log in as root and install all the necessary packages:

# yum -y install M4 sendmail sendmail-cf sendmail-doc dovecot

Step 2: By default, Sendmail only accept connection from loopback device or 127.0.0.1, you need to enable Sendmail to accept connection to your other network interface. To do this, edit /etc/mail/sendmail.mc (make sure to create a backup first), look for the following entry,

DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl

And change it to,

dnl DAEMON_OPTIONS(`Port=smtp,Addr=127.0.0.1, Name=MTA')dnl

Step 3: Edit /etc/mail/local-host-names and list all hostnames in your network that is acting as MX recipient. In my case, I have the following:

exampledns.com
node1.exampledns.com
mail.exampledns.com

Note that you might have a different settings here.

Step 4: Update the sendmail.cf config file and restart Sendmail service and then send test mail.

# m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
# service sendmail restart
# su - gene
[gene]$ echo | mail -s "test email from gene" user1@exampledns.com
[gene]$ su - user1
[user1]$ mail

Note: From local user gene, you should be able to see emails from root account.

Step 5a: By default, Sendmail doesn't use 'write' your domain name to outgoing email. The above email from gene would show on user1 as coming from gene@localhost.localdomain. To write the '@exampledns.com' domain to outgoing emails, edit /etc/mail/sendmail.mc and find the following settings:

dnl MASQUERADE_AS(`domain-name.com')dnl
dnl FEATURE(masquerade_entire_domain)dnl
dnl FEATURE(masquerade_envelope)dnl

Step 5b: Remove the prefix dnl, so you have something similar below. And specify the domain name you wish that your outgoing emails will use. Edit /etc/mail/sendmail.mc and add the following settings:

MASQUERADE_AS(`exampledns.com')dnl
FEATURE(masquerade_entire_domain)dnl
FEATURE(masquerade_envelope)dnl

Step 5c: Update sendmail config file and restart your Sendmail service

# m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
# service sendmail restart

Your outgoing mail should now look like gene@exampledns.com.

Miscellaneous Setup of Sendmail:

Step 6a: Set-up your aliases. For example, all inquiries sent to inquiry@exampledns.com will be forwarded to gene@exampledns.com. Edit /etc/aliases file and add the following entry at the bottom of the file:

inquiry: gene@exampledns.com

Note: To refer to a filename for a list of user that will resolve to an alias (ie. mailing list setup), use the following format:

alias: :include:/path/to/file

So you could have something like:

company-announcement: :include:/etc/mail/staff-list

Step 6b: Restart Sendmail:

# service sendmail restart
or
# newaliases

Step 7a: To accept or reject mails coming from selected users or domain, edit the /etc/mail/access file and add something along the lines of:

spammer@spam.com REJECT
192.168.3.200 DISCARD
sendmail.com REJECT

(RELAY reject the sender or recipient with general purpose error message. DISCARD drop the mail without any error message or notification to the sender or recipient.)

Step 7b: Rebuild the access file database and restart the Sendmail program:

# makemap hash /etc/mail/access.db < /etc/mail/access
# service sendmail restart

Step 8a: Set a cap the size of email attachment. Add the following entries to sendmail.mc

define(`confMAX_MESSAGE_SIZE', `size-in-bytes')dnl

Step 8b: Update sendmail config file and restart your Sendmail service

# m4 /etc/mail/sendmail.mc > /etc/mail/sendmail.cf
# service sendmail restart

Step 9: Setup your imap server using Dovecot. Log in as root, edit /etc/dovecot.conf and add the following:

# cp /etc/dovecot.conf /etc/dovecot.conf-original
# vi /etc/dovecot.conf

protocols = imap pop3

# service dovecot start

Note: In future post, we'll setup a more secure IMAP server using certificates.

Step 10: Test your imap server using your email client (ie. kmail, thunderbird, evolution, etc)

Watch out for the continuation of this Quickie Mail Server Setup Tutorial using Sendmail, Dovecot, SquirrelMail, SpamAssassin on Fedora 8.

Thursday, September 4, 2008

Creating Yum Repository on Fedora 9

Note: Make sure to check the conventions I use before going through the tutorial.

Creating your own private yum repository is useful especially if you wish to conserve bandwidth or you have your own packages you wish to distribute through yum (I used it for my class since Internet access it always available). Creating one in Fedora is fairly straight-forward.

Step 1 (server side): Log in as root and install the necessary packages (these can also be found on your F9 DVD or iso) , and start the httpd service.

# yum -y install createrepo httpd
# rpm -q createrepo httpd
# service httpd start
# chkconfig --level 35 httpd on

Step 2 (server side): Log in as root and assuming that you've already downloaded the official Fedora 9 iso image, then mount the iso and copy the rpm packages in iso image to your Apache directory.

# mkdir /var/www/html/f9repo
# mkdir /mnt/iso
# mount -o loop Fedora-9-i386-DVD.iso /mnt/iso
# cp -av /mnt/iso/Packages/* /var/www/html/f8repo
# cd /var/www/html/f9repo
# createrepo -v .
# service httpd restart

Note: You can also check your yum repo via web by visiting http://localhost/f8repo

Step 3 (client side): Log in as root, and create private.repo file to point your Fedora 9 client to the local yum repository server.

# cd /etc/yum.repo.d/
# vi private.repo

[LocalRepo]
name=Local Yum Repository
baseul=http://192.168.0.2/f9repo
enabled=1
gpgcheck=0

Note: For testing purposes, also edit /etc/yum.repo.d/fedora.repo file. Look for "enabled=1" and change it to "enabled=0". This would disable yum from fetching packages from Fedora repository (Internet).

Step 4: Log in as root and test your local yum repository. By default, 'nano' text editor is installed. Remove this package and try to install them again.

# yum -y remove nano
# yum -y install nano

Note: You should see a message where is getting it's package from the LocalRepo.

Optional package I find useful on the client side (but you need to download the Internet):

# yum -y install yumex yum-fastestmirror yum-skip-broken

I hope you find this post "Creating Yum Repository on Fedora 9" useful!

Wednesday, September 3, 2008

Fedora 8 Quickie Apache Server Setup (Part II)

Note: Make sure to check the conventions I use before going through the tutorial.

Hello! For second part of our web server setup, we'll setup CGI script and Virtual Hosting. As with previous post you can use http://localhost for testing if you haven't setup local DNS from here

Running CGI Scripts

CGI scripts are a way for you to run external program and dynamic content on your Apache web server. For this post, we'll only run very basic BASH shell script but note that there are a number of scripting language you can use. Perl (forever classic way to run cgi), Php (popular but on it's way out), Python (slowly inching it's way to being the de-facto scripting language of choice among the geeky crowd), Ruby (distant cousin of Python) and host of other non-open-source languages.

By default, all CGI scripts are place in /var/www/cgi-bin directory. This is sufficient for our testing. However, if you need to change them, then look for following parameters in /etc/httpd/conf/httpd.conf file and change them to your preferred settings:

ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"

<Directory "/var/www/cgi-bin">
AllowOverride None
Options None
Order allow,deny
Allow from all
</Directory>

Step 1: Log in as root, and create a basic cgi BASH script.

# cd /var/www/cgi-bin/
# nano test.sh

#!/bin/bash
echo Content-Type: text/html
echo
echo "<pre>"
echo "Hello, this is test cgi script and my username is `whoami`"
echo "My id is `id`"
echo "Today is `date`"
echo "</pre>"

Step 2: Set the execute permission for the script

# chmod 755 test.sh

Step 3: Log in as local user (ie. gene) and test the cgi script

$ firefox http://localhost/cgi-bin/test.sh
or
$ firefox http://www.exampledns.com/cgi-bin/test.sh

Setting Virtual Host

Virtual Hosting refers to the feature of Apache to host multiple domain from a single web server. So you have something like a www.company1.com and ww.company2.com hosted on a single server. There are two way to implement virtual hosting, IP-based and Name-based. For our setup, we'll use Name-based as it's generally more straight-forward.

Note: Before taking it for a test drive, make sure to setup a domain for www.company1.com and www.company2.com. We'll use these for our virtual domain. You can follow a quick DNS setup here.

Step 1: Do a quick dig if the test domains are properly resolving.

$ dig www.company1.com
$ dig www.company2.com

Step 2: Log in as root and create the appropriate subdirectory and test page for "www.company1.com" and "www.company2.com".

# cd /var/www
# mkdir virtual
# mkdir virtual/company1
# mkdir virtual/company2
# echo "Welcome to Company1" > virtual/company1/index.html
# echo "Welcome to Company2" > virtual/company2/index.html

Step 2: As root, edit /etc/httpd/conf/httpd.conf file and add the following settings at bottom of of the file.

NameVirtualHost *:80

<VirtualHost *:80>
ServerName www.company1.com
DocumentRoot /virtual/company1
ErrorLog logs/company1_error_log
CustomLog logs/company1-access_log common
</VirtualHost>

<VirtualHost *:80>
ServerName www.company2.com
DocumentRoot /virtual/company2
ErrorLog logs/company2_error_log
CustomLog logs/company2-access_log common
</VirtualHost>

Step 3: Restart the Apache web server and point your web browser to the virtual domain.

# service httpd restart
# firefox http://www.company1.com
# firefox http://www.company2.com

You now should have a rudimentary virtual hosting setup, enough to get you started.