I am a novice SuSE Linux user. While I begun to use Redhat Linux at the first time I was trying to use Linux operating system, the Redhat didn't remain free. So, I had to find a new Linux distribution. SuSE got my attention instantly, 'cause I was told it came with an automated configuration program called YaST which is easy to use. This happened like 2 or 3 years ago. But the funny thing was a year after I switched to SuSE, the german SuSE company was acquired by Novell, and the new owner changed it to be a commercial product. This time I didn't want to switch to another distribution for the same reason. Besides they also launched a community based Linux project website http://www.opensuse.org/ with which people like me can still have the lastest open source software edition of SuSE Linux for free; They name it SuSE Linux OSS as opposed to their retail product SuSE Linux. This is a brief story of how I chose SuSE Linux, and why I stick with it. Linus himself has the same thought as me. :)

Software is like sex; it's better when it's free.
                                                                              -- Linus Torvalds
I found most Korean Linux users somehow stick with Redhat Linux at work. So it is not very easy to find any SuSE Linux guru around here in Korea. I am no expert myself but with this writing, you may also find something worthy of reading. cause I want it to be my future reference. Remember this writing assumes you are using SuSE Linux OSS 10.0 released, which is the lastest at the moment.

You may want to bookmark the following links as you use SuSE Linux 10.0.

installation sources;
ftp://suse.inode.at/opensuse/distribution/SL-10.0-OSS/inst-source/
ftp://ftp.gwdg.de/pub/opensuse/distribution/SL-10.0-OSS/inst-source/
rpm package list;
http://www.novell.com/products/linuxpackages/professional/index_all.html

I have chose the following rpms for my current Apache configuration;

apache2
apache2-mod_php4
apache2-prefork

Before we get into the virtualhost specific settings, I'd like to make a simple change to avoid meaningless traces in /var/log/apache2/access_log by warms like Nimda. Follow the instructions:

# Optional Warm Log Protection Setup
#
# based on an article at
# http://mandrake.vmlinuz.ca/bin/view/Main/ApachelogManagement
#

#make sure we log legit requests
SetEnvIf Request_Method "(GET)|(POST)|(PUT)|(DELETE)|(HEAD)" log
# SEARCH is not a legit method in Apache and the objective of a current
# worm. So I am going to send it to oblivion. It creates broken log
# files if I don't
SetEnvIf Request_Method "(SEARCH)" worm

# RegEx's to trap a number of windows worms I know of. Send them to
# the worm logfile and not the one I mine for data.

SetEnvIf Request_URI "_vti_inf\.html$" worm !log
SetEnvIf Request_URI "^/_mem_bin/" worm !log
SetEnvIf Request_URI "^/_vti_bin/" worm !log
SetEnvIf Request_URI "^/c/" worm !log
SetEnvIf Request_URI "^/d/" worm !log
SetEnvIf Request_URI ^/scripts/ worm !log
SetEnvIfNoCase Request_URI "^/msadc/" worm !log

#Code Red
SetEnvIf Request_URI "default\.ida" worm !log
SetEnvIfNoCase Request_URI "null\.ida" worm !log

#NIMDA
SetEnvIf Request_URI "cmd\.exe" worm !log
SetEnvIf Request_URI "root\.exe" worm !log
SetEnvIf Request_URI "Admin\.dll" worm !log

# These are optional
# This sets it so that requests for your images aren't logged.
SetEnvIf Request_URI "(\.gif|\.jpe?g|\.png|\.css|\.js)$" !log

# this makes it so that requests from my home lan aren't logged.
SetEnvIf Remote_Addr "^192\.168\." !log

# If I'm on the box testing I don't want that logged.
SetEnvIf Remote_Addr "^127\.0\." !log

# This is an example of how to not log XXX referrer.
# SetEnvIf referer "somedangsite\.com" !log

# Now set where the logs are. I'm sending worms to /dev/null but
# it could be any full path.
CustomLog /var/log/apache2/access_log vhost_combined env=log
CustomLog /dev/null combined env=worm


Here's the virtualhost settings.

A few notes;

I usually change the default directory of user "webmaster" in /etc/password to /srv/www/vhosts, and `chown webmaster:users -R /srv/www/vhosts/`, but it's up to you.

By default, SuSE doesn't enable the mod_rewrite rewrite module. It's installed, but not enabled. If you want to enable it, refer http://enarion.net/web/apache/htaccess/mod_rewrite-on-suse/.

You'd read an complain about No SSLSessionCache in your log file. You can ignore it cause there's no SSL defined in our configuration.

IP-based virtual setting is needed to use both HTTP and HTTPS at the same time. This is what I read. so, don't ask me why.

The following is the way I partitioned my 200GB hard drive.

primary1 30MB /boot ext2 FS
primary2 1GB swap swap FS
extended
.5GB /tmp ext2 FS
30GB /var reiser FS
30GB /var2 reiser FS
30GB /srv reiser FS
30GB /srv2 reiser FS
20GB /home reiser FS
10GB /usr reiser FS
10GB /opt reiser FS
rest / reiser FS

As you know, Webalizer is one of the best apache log analyzers available in Linux community. The way I configure is somewhat related to my current settings. So your discretion is advised. http://www.mrunix.net/webalizer/faq.html was enough to gratify my curiosity. So you should check it out first. Here's what I did.

1. Created /etc/webalizer
2. Moved /etc/webalizer.conf to /etc/webalizer/ssazio.conf
3. Edited it as follows (note that I removed all the comment lines)

LogFile       /var/log/apache2/www.ssazio.com.log

OutputDir      /srv/www/vhosts/ssazio.com/webalizer

HostName       ssazio.com

PageType htm*
PageType cgi
PageType php

DNSCache dns_cache.db

DNSChildren 10

HideURL  *.gif
HideURL  *.GIF
HideURL  *.jpg
HideURL  *.JPG
HideURL  *.png
HideURL  *.PNG
HideURL  *.ra

SearchEngine google.com q=
SearchEngine yahoo.com p=
SearchEngine altavista.com q=
SearchEngine eureka.com q=
SearchEngine lycos.com query=
SearchEngine hotbot.com MT=
SearchEngine msn.com  MT=
SearchEngine infoseek.com qt=
SearchEngine webcrawler searchText=
SearchEngine excite  search=
SearchEngine netscape.com search=
SearchEngine naver.com query=
SearchEngine nate.com query=
SearchEngine daum.net q=
SearchEngine empas.com q=

4. Used the .conf file as a template for whatever domain's .conf file(s)
5. For a batch process, created a file named /usr/local/bin/weblog and write it as follows.

#!/bin/bash
#
# weblog: web log analyzer for statistics using webalizer
#
cat /var/log/apache2/access_log | /usr/bin/split-logfile2
for i in /etc/webalizer/*.conf; do webalizer -c $i; done
rm /var/log/apache2/*.log

6. Run weblog whenever I want to update the log analyzed data of all the domains I have on this server.

Among many FTP servers, my favorite is vsftpd. Here's what I've done with it. There's an online article you may want to read.

http://www.novell.com/coolsolutions/feature/14689.html

With default setting that came with vsftp rpm, it is configured to run by xinetd, and use PAM for user authentication. For more information on vsftpd authentication, check out /etc/pam.d/vsftpd. As I prefer to keep the number of running services low, I'd rather want vsftpd to run in stand-alone mode. Details are explained in the above article. So I'll put my /etc/vsftpd.conf and /etc/init.d/vsftpd for your reference. Here goes /etc/vsftpd.conf.

# vsftpd config file: /etc/vsftpd.conf
# for SuSE Linux 10.0 OSS
#
# Based on SUSE default configuration file
#
# Last updated: March 10 2006
# Written by Ginsirg C. Au
#

# General Settings
#
write_enable=YES
dirmessage_enable=YES
#nopriv_user=ftpsecure
ftpd_banner="Welcome to Science Integration (TM) FTP service."
ls_recurse_enable=YES
#deny_email_enable=YES
#banned_email_file=/etc/vsftpd.banned_emails
#hide_ids=YES

# Local FTP user Settings
#
local_enable=YES
local_umask=022
chroot_local_user=YES
#chroot_list_enable=YES
#chroot_list_file=/etc/vsftpd.chroot_list
#local_max_rate=7200

# Anonymus FTP user Settings
#
anonymous_enable=YES
anon_world_readable_only=YES
#anon_upload_enable=YES
#anon_umask=022
#anon_mkdir_write_enable=YES
#anon_other_write_enable=YES
#chown_uploads=YES
#chown_username=whoever
#anon_max_rate=7200

# Log Settings
#
syslog_enable=YES
#log_ftp_protocol=YES
#xferlog_enable=YES
#vsftpd_log_file=/var/log/vsftpd.log
#xferlog_std_format=YES
#xferlog_file=/var/log/xferlog
#dual_log_enable=YES
#setproctitle_enable=YES

# Transfer Settings
#
max_clients=2
max_per_ip=1
connect_from_port_20=YES
idle_session_timeout=1200
data_connection_timeout=1200
#async_abor_enable=YES
#ascii_upload_enable=YES
#ascii_download_enable=YES
#pasv_enable=NO
pam_service_name=vsftpd
listen=YES

/etc/init.d/vsftpd reads like this;

#!/bin/sh
# vsftpd for SuSE Linux 10.0 OSS
#
# Written by Chuck Au
#
### BEGIN INIT INFO
# Provides: vsftp
# Required-Start:
# X-UnitedLinux-Should-Start:
# Required-Stop:
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Description: vsftp server
### END INIT INFO

. /etc/rc.status

case "$1" in
start)
echo -n "Starting vsftpd "
/usr/sbin/vsftpd &
rc_status -v
;;
stop)
pid=`pgrep -f -u root /usr/sbin/vsftpd`
if [ $pid ]
then
echo -n "Shutting down vsftpd "
kill -9 $pid
fi
rc_status -v
;;
*)
echo "Usage: 'basename $0' {start|stop}" >&2
exit 64
;;
esac
exit 0

This will do the same work as one in the above article. It is more consistent with other scripts in the same directory though.

Finally, you have to enable FTP service port in the YaST firewall setup as it is disabled by default. Under the Security and Users > Firewall > Allowed Services menu, select [Advanced...] item, and add port 21.

Basically, my explanation here is a step-by-step gude to setup mail service with SuSE Linux. SuSE's default choice of MTA is Postfix, so I'd stick with it. Check out if the following rpms are installed on your computer.

postfix
postfix-mysql
courier-authlib
courier-imap

In YaST, choose System Services (Runlevel) sub-menu under System menu, and turn on the following services.

courier-authdaemon
courier-imap
courier-imap-ssl
fam
postfix

Note that Courier IMAP rpm package in SuSE Linux was compiled with File Alteration Monitor (FAM), so FAM-Server should be running to avoid a certain error log.

Before exit out of YaST, Go to Firewall menu, and check if the following services are enabled.

Mail Server
IMAP Server
IMAPS Server

Okay, you are now ready to go deeper.

Keep in mind that a certain level of background knowledge on postfix is required to understand the following configuration. I found the following book is very helpful;

O'Reilly's Postfix - The Definitive Guide By Kyle D. Dent

Among other online resources, you don't wanna miss the official homepage of Postfix at http://www.postfix.org. There're many useful howto docs, which I also found useful.

1. Postfix configuration.

If you read
http://postfix.state-of-mind.de/patrick.koetter/smtpauth/index.html, you can easily configure Postfix with SASL/TLS. If you don't want to TLS, it would be even easier. To configure Postfix supporting local users only with SASL/TLS, open /etc/postfix/main.cf and put in the following;

#
# Global Postfix configuration file 210.97.250.57
# Written by Chuck Au
# Last updated: March 9th 2006
#

#
# Local Path Name
#
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
config_directory = /etc/postfix
daemon_directory = /usr/lib/postfix

#
# Queue and Process Ownership
#
mail_owner = postfix

#
# Internet Host and Domain Names
#
myhostname = mail.$mydomain
mydomain = handate.com

#
# Message Size
#
message_size_limit = 10240000

#
# Sending Mail
#
myorigin = $mydomain

#
# Receiving Mail
#
inet_interfaces = $myhostname, localhost
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain

#
# Rejecting Mail for Unknown Local Users
#
unknown_local_recipient_reject_code = 550

#
# Trust and Relay Control
#
mynetworks_style = subnet
#mynetworks = 210.97.250.0/26, 127.0.0.0/8

#
# Internet or Intranet
#
relayhost =

#
# Alias Database
#
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases

#
# Delivery to Mailbox
#
home_mailbox = Maildir/
mail_spool_directory = /var/mail
mailbox_command =
mailbox_size_limit = 0
mailbox_transport =

#
# Junk Mail Controls
#
disable_vrfy_command = yes
smtpd_sender_restrictions = hash:/etc/postfix/access
#smtpd_helo_required = yes
#smtpd_helo_restrictions = reject_invalid_hostname, reject_unknown_hostname
header_checks = regexp:/etc/postfix/header_checks

#
# Debugging Control
#
debug_peer_level = 2

#
# Install-time Configuration Information
#
sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
setgid_group = maildrop
html_directory = /usr/share/doc/packages/postfix/html
manpage_directory = /usr/share/man
readme_directory = /usr/share/doc/packages/postfix/README_FILES
sample_directory = /usr/share/doc/packages/postfix/samples

#
# IPv4 or IPv6
#
inet_protocols = all

#
# Masquerading
#
masquerade_classes = envelope_sender, header_sender, header_recipient
masquerade_domains =
masquerade_exceptions = root

#
# SASL settings
#
broken_sasl_auth_clients = yes
smtp_sasl_auth_enable = no
smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
smtpd_sasl_auth_enable = yes
smtpd_sasl_authenticated_header = yes
smtpd_sasl_local_domain =
smtpd_sasl_security_options = noanonymous

#
# TLS settings
#
smtp_use_tls = no
smtpd_use_tls = yes
smtpd_tls_auth_only = yes
smtpd_tls_key_file = /etc/postfix/mailkey.pem
smtpd_tls_cert_file = /etc/postfix/mail_signed_cert.pem
smtpd_tls_CAfile = /etc/postfix/cacert.pem
smtpd_tls_loglevel = 3
smtpd_tls_received_header = yes

#
# Maps
#
canonical_maps = hash:/etc/postfix/canonical
sender_canonical_maps = hash:/etc/postfix/sender_canonical
relocated_maps = hash:/etc/postfix/relocated
transport_maps = hash:/etc/postfix/transport

#
# XVERP Command
#
#smtpd_authorized_verp_clients = $mynetworks

#
# Others
#
biff = no
defer_transports =
disable_dns_lookups = no
smtpd_client_restrictions =
strict_rfc821_envelopes = no

#
# Email Notification Settings
#
notify_classes = 2bounce, delay, policy, protocol, resource, software


And, additionally, update /etc/postfix/header_checks for Korean spam controls as follows;

/^Subject:.*\[±¤[ _\.\*\-]*°í\]/ DISCARD
/^Subject:.*\(±¤[ _\.\*\-]*°í\)/ DISCARD
/^Subject: \[±¤[ _\.\*\-]*°í\]/ DISCARD
/^Subject: \(±¤[ _\.\*\-]*°í\)/ DISCARD
/^Subject: =\?euc-kr\?q\?\(=B1=A4=B0=ED\)*/ DISCARD
/^Subject: =\?euc-kr\?q?\[=B1=A4=B0=ED\]*/ DISCARD
/^Subject: =\?ks_c_5601-1987\?B\?KLGksO0p*/ DISCARD
/^Subject: =\?ks_c_5601-1987\?B\?W7GksO1d*/ DISCARD


If you are going to use TLS, open /etc/postfix/master.cf, and uncomment the following line;

tlsmgr unix - - n 1000? 1 tlsmgr

It will eliminate"no entropy for TLS key generation" warning.

2. How to configure Courier IMAP

Open /etc/authlib/authdaemonrc, and change the line that starts with "authmodulelist" to read:

authmodulelist="authpam"

3. How to configure Cyrus SASL

First, run YaST to check if the following rpms are already installed;

cyrus-sasl
cyrus-sasl-plain

If you want to use /etc/sasldb2 for SASL authentication, the password file should contain all of our email accounts.

chown postfix:root /etc/sasldb2
chmod 440 /etc/sasldb2
saslpasswd2 -c -u `postconf -h myhostname` username
(or saslpasswd2 -c -u mail.handate.com chuck, for example.)
sasldblistusers2 (to check content of /etc/sasldb2)

/usr/lib64/sasl2/smptd.conf should read as follows;

pwcheck_method: auxprop
mech_list: plain login

Postfix configuration with virtual user enabled is little more complex than this. I couldn't find any SuSE Linux specific howto docs yet. So, I'll post a crude form of howto for SuSE Linux users next time.

This howto is based on the following references;

http://forums.bsdnexus.com/viewtopic.php?id=61.
http://www.marlow.dk/site.php/tech/postfix
http://www.phparchitecture.com/howto_show.php?id=2
http://genco.gen.tc/postfix_virtual.php#courierimap
http://www.firstpr.com.au/web-mail/RH90-Postfix-Courier-Maildrop-IMAP/

So at least skim through them first. Please note I may update this writing as I update the configuration setup of my server at any time.

Suppose you have fresh installed MySQL from rpm, run the following command.

mysqladmin -u root -p password 'rootpass'

Then, run the followings;

mysql -u root -p
mysql> GRANT ALL ON maildb.* TO 'mailuser'@'localhost' IDENTIFIED BY 'mailpass';
mysql> FLUSH PRIVILEGES;
mysql> QUIT;

We are now ready to setup maildb database using the following file. If you name it a.sql,

mysql -u mailuser -p < a.sql

should take care of the database setup.

--
-- create database `maildb`
--

CREATE DATABASE maildb;
USE maildb;

--
-- table structure for `transport`
--

CREATE TABLE `transport` (
  `domain` varchar(128) NOT NULL default '',
  `transport` varchar(128) NOT NULL default '',
  UNIQUE KEY `domain` (`domain`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

--
-- table dump data for `transport`
--

INSERT INTO `transport` VALUES ('ssazio.com', 'virtual:');
INSERT INTO `transport` VALUES ('sazio.com', 'virtual:');
INSERT INTO `transport` VALUES ('handate.com', 'local:');

--
-- table structure for `users`
--

CREATE TABLE `users` (
  `id` varchar(128) NOT NULL default '',
  `address` varchar(128) NOT NULL default '',
  `crypt` varchar(128) NOT NULL default '',
  `clear` varchar(128) NOT NULL default '',
  `name` varchar(128) NOT NULL default '',
  `uid` smallint(5) unsigned NOT NULL default '5000',
  `gid` smallint(5) unsigned NOT NULL default '5000',
  `home` varchar(128) NOT NULL default '/home/vmail',
  `domain` varchar(128) NOT NULL default '',
  `maildir` varchar(255) NOT NULL default '',
  `imapok` tinyint(3) unsigned NOT NULL default '1',
  `bool1` tinyint(3) unsigned NOT NULL default '1',
  `bool2` tinyint(3) unsigned NOT NULL default '1',
  PRIMARY KEY  (`id`),
  UNIQUE KEY `id` (`id`),
  UNIQUE KEY `address` (`address`),
  KEY `id_2` (`id`),
  KEY `address_2` (`address`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

--
-- table dump data for `users`
--

INSERT INTO `users` VALUES ('admin@ssazio.com', 'admin@ssazio.com', '', 'password', 'ssazio.com Administrator', 5000, 5000, '/home/vmail', 'ssazio.com', 'ssazio.com/admin/', 1, 1, 1);
INSERT INTO `users` VALUES ('admin@sazio.com', 'admin@sazio.com', '', 'password', 'sazio.com Administrator', 5000, 5000, '/home/vmail', 'sazio.com', 'sazio.com/admin/', 1, 1, 1);

--
-- table structure for `virtual`
--

CREATE TABLE `virtual` (
  `address` varchar(255) NOT NULL default '',
  `goto` varchar(255) NOT NULL default '',
  UNIQUE KEY `address` (`address`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

--
-- table dump data for `virtual`
--

INSERT INTO `virtual` VALUES ('admin@ssazio.com', 'admin@ssazio.com');
INSERT INTO `virtual` VALUES ('admin@sazio.com', 'admin@sazio.com');

Now, we need to set up a user account whose reponsibility is to take care of virtual email delivery. and a directory to use as a virtual mailbox home on /home/vmail.

with Yast, or command line commands,
add a group with gid of 5000 and name it vmail
add a user with uid of 5000 and name it vmail
and his home directory should be /home/vmail.
enabling shell login is up to you.

make virtual mailbox home with;

# cd /home
# mkdir vmail
# cd vmail

create virtual domain's directory as many as you want with;

# mkdir domain1.tld
# mkdir domain2.tld
:

change the ownership of all of the newly created directories with vmail:vmail;

# cd /home/vmail
# chown -R vmail:vmail /home/vmail

now for convenience, let's create our template Maildir directories;

# maildirmake /home/vmail/.templateDir
# maildirmake -f Spam /home/vmail/.templateDir
# chown vmail:vmail -R /home/vmail/.templateDir

good, now you can create new account's Maildirs with this template with;

cp -pR /home/vmail/.templateDir/ /home/vmail/domain1.tld
mv /home/vmail/domain1.tld/.templateDir /home/vmail/domain1.tld/thisguy.

congrats, you have just created a user's Maildir. repeat it until you create all the virtual user's Maildirs.

Now create the following configuration files for postfix configuration.

/etc/postfix/mysql_transport.cf

user = [mailuser]
password = [mailpass]
dbname = maildb
table = transport
select_field = transport
where_field = domain
hosts=127.0.0.1

/etc/postfix/mysql_virtual.cf

user = [mailuser]
password = [mailpass]
dbname = maildb
table = virtual
select_field = goto
where_field = address
hosts=127.0.0.1

/etc/postfix/mysql_virtual_maps.cf

user = [mailuser]
password = [mailpass]
dbname = maildb
table = users
select_field = maildir
where_field = address
hosts=127.0.0.1

/etc/postfix/mysql_virtual_uid.cf

user = [mailuser]
password = [mailpass]
dbname = maildb
table = users
select_field = uid
where_field = address
hosts=127.0.0.1

/etc/postfix/mysql_virtual_gid.cf

user = [mailuser]
password = [mailpass]
dbname = maildb
table = users
select_field = gid
where_field = address
hosts=127.0.0.1

Then, update /etc/postfix/main.cf file as follows;

# Global Postfix configuration file for 210.97.250.57
#
# Written by Chuck Au
# Use this configuration at your own risk.
# Last updated: April 4th 2006
# Features enabled: Virtual Users, SASL, Spam Controls, Maildrop

#
# Local Path Name
#
queue_directory = /var/spool/postfix
command_directory = /usr/sbin
config_directory = /etc/postfix
daemon_directory = /usr/lib/postfix

#
# Queue and Process Ownership
#
mail_owner = postfix

#
# Internet Host and Domain Names
#
myhostname = mail.$mydomain
mydomain = handate.com

#
# Message Size
#
message_size_limit = 10240000

#
# Sending Mail
#
myorigin = $mydomain

#
# Receiving Mail
#
inet_interfaces = $myhostname, localhost

#
# Rejecting Mail for Unknown Local Users
#
unknown_local_recipient_reject_code = 550

#
# Trust and Relay Control
#
#mynetworks = 210.97.250.0/26, 127.0.0.0/8
mynetworks_style = subnet

#
# Delivery to Mailbox
#
#mail_spool_directory = /var/mail
home_mailbox = Maildir/
mailbox_size_limit = 0

#
# Rate Controls for External Filtering
#
maildrop_destination_concurrency_limit = 1
maildrop_destination_recipient_limit = 1

#
# Debugging Control
#
debug_peer_level = 2

#
# Install-time Configuration Information
#
sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
setgid_group = maildrop
html_directory = /usr/share/doc/packages/postfix/html
manpage_directory = /usr/share/man
readme_directory = /usr/share/doc/packages/postfix/README_FILES
sample_directory = /usr/share/doc/packages/postfix/samples

#
# IPv4 or IPv6
#
inet_protocols = all

#
# Masquerading
#
masquerade_classes = envelope_sender, header_sender, header_recipient
masquerade_domains =
masquerade_exceptions = root

#
# SASL settings
#
broken_sasl_auth_clients = yes
smtp_sasl_auth_enable = no
smtpd_sasl_auth_enable = yes
smtpd_sasl_authenticated_header = yes
smtpd_sasl_local_domain =
smtpd_sasl_security_options = noanonymous

#
# TLS settings (temporarily turned TLS off)
#
smtp_use_tls = no
smtpd_use_tls = no
#smtpd_tls_auth_only = yes
#smtpd_tls_key_file = /etc/postfix/mailkey.pem
#smtpd_tls_cert_file = /etc/postfix/mail_signed_cert.pem
#smtpd_tls_CAfile = /etc/postfix/cacert.pem
#smtpd_tls_loglevel = 3
#smtpd_tls_received_header = yes

#
# XVERP Command
#
#smtpd_authorized_verp_clients = $mynetworks

#
# Others
#
biff = no
defer_transports =
disable_dns_lookups = no
smtpd_client_restrictions =
strict_rfc821_envelopes = no

#
# Email Notification Settings
#
notify_classes = 2bounce, delay, policy, protocol, resource, software

#
# Maps
#
canonical_maps = hash:/etc/postfix/canonical
sender_canonical_maps = hash:/etc/postfix/sender_canonical
relocated_maps = hash:/etc/postfix/relocated
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases

#
# Virtual Settings
#
mydestination = $myhostname, $transport_maps
transport_maps =        mysql:/etc/postfix/mysql_transport.cf
virtual_alias_maps =    mysql:/etc/postfix/mysql_virtual.cf
virtual_mailbox_maps =  mysql:/etc/postfix/mysql_virtual_maps.cf
virtual_uid_maps =      mysql:/etc/postfix/mysql_virtual_uid.cf
virtual_gid_maps =      mysql:/etc/postfix/mysql_virtual_gid.cf
virtual_mailbox_base =  /home/vmail
virtual_mailbox_limit = 102400000
virtual_minimum_uid =   100

#
# Maildrop using local(8)
#
mailbox_command = /usr/bin/maildrop -d ${USER}

#
# Spam Controls
#
#header_checks = regexp:/etc/postfix/header_checks
#mime_header_checks = regexp:/etc/postfix/mime_header_checks
disable_vrfy_command = yes
smtpd_delay_reject = yes
smtpd_helo_required = yes
smtpd_helo_restrictions =
  permit_mynetworks,
  check_helo_access hash:/etc/postfix/helo_access,
  reject_non_fqdn_hostname,
  reject_invalid_hostname
smtpd_sender_restrictions =
  reject_non_fqdn_sender,
  reject_unknown_sender_domain,
  check_sender_access hash:/etc/postfix/access
smtpd_recipient_restrictions =
  reject_unauth_pipelining,
  reject_non_fqdn_recipient,
  reject_unknown_recipient_domain,
  permit_mynetworks,
  permit_sasl_authenticated,
  reject_rbl_client relays.ordb.org,
  reject_rbl_client list.dsbl.org,
  reject_rbl_client sbl-xbl.spamhaus.org,
  reject_unauth_destination


Additionally, we need the following file in /etc/postfix/ directory.

/etc/postfix/helo_access
# This file has to be compiled with postmap
#   postmap /etc/postfix/helo_access
amd754          OK
210.97.250.57   REJECT You are not me
localhost       REJECT You are not localhost
127.0.0.1       REJECT You are not 127.0.0.1

Outlook Express uses your PC's NetBIOS computer name as argument of EHLO command. So, it is not in a FQDN form. As I cofigured Postfix to reject anyone EHLO/HELO with non_fqdn_hostname, You need a line like "amd754 OK" in /etc/postfix/helo_access for any exceptions. (i.e. my home PC has a name of "amd754", and I want to access my email server with O.E. at home.)

/etc/postfix/header_checks and /etc/postfix/mime_header_checks is redundant 'cause I use SpamAssassin. So I decided to remove 'em.

Check /etc/postfix/master.cf if the following lines are already there.
smtp      inet  n       -       n       -       -       smtpd
virtual   unix  -       n       n       -       -       virtual
:
maildrop  unix  -       n       n       -       -       pipe
  flags=DRhu user=vmail argv=/usr/bin/maildrop -d ${recipient}

2. How to configure Courier IMAP

Open /etc/authlib/authdaemonrc, and change the line that starts with "authmodulelist" to read:

authmodulelist="authpam authmysql"

The 1st module is for local authentication, and the 2nd module is for virtual users. However, for some reason SuSE Linux courier-authlib rpm doesn't include libauthmysql.so. which is required to authenticate through MySQL. So, I had to compile a source rpm by myself after downloading it from the following link;
http://ftp.jaist.ac.jp/pub/Linux/openSUSE/distribution/SL-10.0-OSS/inst-source/suse/src/courier-authlib-0.57-2.src.rpm
Once you have it on your computer, run the following command;

# rpmbuild --rebuild courier-authlib-0.57-2.src.rpm

I have to admit this isn't a graceful way of rebuilding the rpm source 'cause it would end up giving you an error message before it produces new binary rpm files. However, this will create the appropriate files in /var/tmp/courier-authlib-0.57-build/usr/lib64. So, I can use 'em anyway. (I don't know how to edit the source rpm to fix this problem. Any comments to address this problem would be appreciated.) Copy 3 required files to the right place as follows;

# cp -a /var/tmp/courier-authlib-0.57-build/usr/lib64/libauthm* /usr/lib64/

Then you are good to go. Please note that I am using 64bit version of SUSE Linux on AMD64 3000+ Server. If you are using 32bit Linux, you should change directory names accordingly in the above command.

This is optional, but if you make empty /etc/courier/shared/index file, there'd be no repeated log messages about it not being found.

Create a file named /etc/authlib/authmysqlrc as follows;

# Contents of authmysqlrc
#
# Written by Chuck Au
#
MYSQL_SERVER localhost
MYSQL_USERNAME [mailuser]
MYSQL_PASSWORD [mailpass]
MYSQL_SOCKET /var/lib/mysql/mysql.sock
MYSQL_DATABASE maildb
MYSQL_USER_TABLE users
MYSQL_CRYPT_PWFIELD crypt
MYSQL_CLEAR_PWFIELD clear
MYSQL_UID_FIELD uid
MYSQL_GID_FIELD gid
MYSQL_LOGIN_FIELD id
MYSQL_HOME_FIELD home
MYSQL_NAME_FIELD name
MYSQL_MAILDIR_FIELD maildir
MYSQL_WHERE_CLAUSE imapok=1 AND bool1=1 AND bool2=1

3. How to configure Cyrus SASL

Unfotunately, the cyrus sasl rpm packages comes with SuSE Linux doesn't seem to know how to handle mysql as they complain about sql plugin like;

Mar 27 01:50:51 www postfix/smtpd[5535]: SQL engine 'mysql' not supported
Mar 27 01:50:51 www postfix/smtpd[5535]: auxpropfunc error no mechanism available
Mar 27 01:50:51 www postfix/smtpd[5535]: _sasl_plugin_load failed on sasl_auxprop_plug_init for plugin: sql

Again, we need to compile the following source rpm. This time what we need is
http://ftp.jaist.ac.jp/pub/Linux/openSUSE/distribution/SL-10.0-OSS/inst-source/suse/src/cyrus-sasl-2.1.21-3.src.rpm. Here's what you wanna do;

# rpm -ivh cyrus-sasl-2.1.21-3.src.rpm

open /usr/src/packages/SPECS/cyrus-sasl.spec with your favorite editor, and look for the line reads "--with-mysql \" and edit it as "--with-mysql=/usr/include/mysql/ \".

# cd /usr/src/packages/
# rpmbuild -bb SPECS/cyrus-sasl.spec
# cd /usr/src/packages/RPMS/x86_64/

# rpm -Uvh --force cyrus-sasl
# rpm -Uvh --force cyrus-sasl-plain
# rpm -Uvh --force cyrus-sasl-sqlauxprop

If you followed the instructions step by step, you are now good to go. Take a look at the following /usr/lib64/sasl2/smptd.conf. You should also replace the previous configuration with this.

pwcheck_method: auxprop
auxprop_plugin: sql
mech_list: plain login
sql_engine: mysql
sql_hostnames: 127.0.0.1
sql_user: [mailuser]
sql_passwd: [mailpass]
sql_database: maildb
sql_select: SELECT clear FROM users WHERE address = '%u@%r'

For local users' authentication at the time sending emails, you need to add local user information as well as virtual user's in user table of maildb database. Don't forget the fact that you may also need to change your email client's option for SASL authentication.

Though virtual alias settings and TLS settings has been missing in this postfix/mysql configuration, now my email server works like a charm. ;)

SSH

Since I'm not considering any ip address restriction at the moment, ssh service need to be configured to prevent access from root.

Open /etc/ssh/sshd_conf and set PermitRootLogin explicitly to no.

NTP

Clock on a working server should always be correct. With Yast, ntp server can be set up within a matter of seconds.

If you read my previous postings, you would know by now I need to set up content filtering with my mail server configuration which is mainly based on postfix, courier-imap, courier-authlib, cyrus-sasl rpms.

After reading enough documentations, I decided to go with Courier Maildrop instead of procmail for local email delivery and filtering. I built courier-maildrop rpms from source files first, and then installed the compiled binarys and man files from them since I didn't want to mess with SuSE Linux's rpm structure.

As maildrop evolves, the way to compile and/or configure it has also been changed dramatically. You wouldn't want to know how much time I spent for googling to figure this out. So don't waste your time on maildrop 1.x version howto docs. The following instructions are based on what I did;

Download maildrop-2.0.2.tar.bz2 which is availale at http://www.courier-mta.org/maildrop/

Copy it to /usr/src/packages/SOURCES/

Open a favoite editor and create or update maildrop.spec as follows;

# $Id: maildrop.spec.in,v 1.27 2006/02/19 16:39:39 mrsam Exp $
#
# Copyright 1998 - 2005 Double Precision, Inc.  See COPYING for
# distribution information.

%define courier_release %(release="`rpm -q --queryformat='.%{VERSION}' redhat-release 2>/dev/null`" ; if test $? != 0 ; then release="`rpm -q --queryformat='.%{VERSION}' fedora-release 2>/dev/null`" ; if test $? != 0 ; then release="" ; fi ; fi ; echo "$release")

Summary: maildrop mail filter/mail delivery agent
Name: maildrop
Version: 2.0.2
Release: 1%{courier_release}
License: GPL
Group: Applications/Mail
Source: maildrop-2.0.2.tar.bz2
Url: http://www.courier-mta.org/maildrop/
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
BuildRequires: /usr/include/fam.h gdbm-devel pcre-devel

%package devel
Summary: development tools for handling E-mail messages
Group: Applications/Mail

%package man
Summary: manual pages for maildrop
Group: Applications/Mail

%description

Maildrop is a combination mail filter/mail delivery agent.
Maildrop reads the message to be delivered to your mailbox,
optionally reads instructions from a file how filter incoming
mail, then based on these instructions may deliver mail to an
alternate mailbox, or forward it, instead of dropping the
message into your mailbox.

Maildrop uses a structured, real, meta-programming language in
order to define filtering instructions.  Its basic features are
fast and efficient.  At sites which carry a light load, the
more advanced, CPU-demanding, features can be used to build
very sophisticated mail filters.  Maildrop deployments have
been reported at sites that support as many as 30,000
mailboxes.

Maildrop mailing list:
http://lists.sourceforge.net/lists/listinfo/courier-maildrop

This version is compiled with support for GDBM database files,
maildir enhancements (folders+quotas), and userdb.

%description devel
The maildrop-devel package contains the libraries and header files
that can be useful in developing software that works with or processes
E-mail messages.

Install the maildrop-devel package if you want to develop applications
which use or process E-mail messages.

%description man
This package contains manual pages for maildrop and associated
utilities.
%prep

%setup -q
%configure --with-devel --enable-userdb --enable-maildirquota --with-trashquota --enable-syslog=1 --enable-trusted-users='root vmail' --enable-maildrop-uid=5000 --enable-maildrop-gid=5000 --enable-authlib

%build

%{__make} %{_smp_mflags}
%install

rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT
%{__make} install DESTDIR=$RPM_BUILD_ROOT MAILDROPUID='' MAILDROPGID=''

mkdir htmldoc
cp $RPM_BUILD_ROOT%{_datadir}/maildrop/html/* htmldoc
rm -rf $RPM_BUILD_ROOT%{_datadir}/maildrop/html

%files
%defattr(-, bin, bin)
%{_datadir}/maildrop

%doc htmldoc/*

%attr(555, root, vmail) %{_bindir}/maildrop
%attr(555, root, vmail) %{_bindir}/lockmail

%{_bindir}/mailbot
%{_bindir}/maildirmake
%{_bindir}/deliverquota
%{_bindir}/reformail
%{_bindir}/makemime
%{_bindir}/reformime

%doc maildir/README.maildirquota.html maildir/README.maildirquota.txt
%doc COPYING README README.postfix INSTALL NEWS UPGRADE ChangeLog maildroptips.txt

%exclude %{_bindir}/maildirmake
%exclude %{_bindir}/deliverquota

%files devel
%defattr(-, bin, bin)
%{_mandir}/man3/*
%{_includedir}/*
%{_libdir}/lib*

%files man
%defattr(-, bin, bin)
%{_mandir}/man[1578]/*

%exclude %{_mandir}/man1/maildirmake*
%exclude %{_mandir}/man8/deliverquota*

%clean
rm -rf $RPM_BUILD_ROOT

Only a few lines has been edited or appended from the one supplied with the tar ball. They are in bold.

Copy this updated maildrop.spec to /usr/src/packages/SPECS/

Before you proceed any further, check if you have installed courier-authlib-devel rpm. If you have it already on your system. Enter the following commands;

# cd /usr/src/packages/
# rpmbuild -bb SPECS/maildrop.spec

Like 2-3 mins later, you can see newly baked rpms in /usr/src/packages/RPMS/. Sweet.
Move to /usr/src/packages/RPMS/x86_64/, and enter:

# rpm -Uvh maildrop-2.0.2-1.x86_64.rpm
# rpm -Uvh maildrop-man-2.0.2-1.x86_64.rpm

* Updated on April 4th 2006 * Unless you changed DEFAULT_DEF variable in config.h to "./Maildir", maildrop deliver local users' email to /var/mail/$USER, which is mbox style. This is not runtime cofigurable and has to be done at compilation time. See INSTALL.txt that came with source tarball for details. A quick fix to this rpm installation is overwriting the maildrop binary.

# cd /usr/src/packages/BUILD/maildrop-2.0.2/maildrop/

Update config.h as I mentioned above. and then

# make

this will create a new maildrop. followed by;

# cp maildrop /usr/bin/
# chown root:vmail /usr/bin/maildrop
# chmod u+s /usr/bin/maildrop

`maildrop -v` should state "Courier Authentication Library extension enabled." in the output.

Now you need to configure it to use with SpamAssassin. Open your favorite editor and create a file named /etc/maildroprc as follows:

# maildroprc - a global set of maildrop 2.0.2 rules
#
# Written by Chuck Au
# Use this configuration at your own risk.

# Based on what I've read, enviroment variables seem to set differently
# depending on the version of maildrop, or system configurations. On my
# server, $SIZE $HOME $DEFAULT $LOGNAME variables have been set to
# {some number}, /home/vmail, domain.tld/user/, user@domain.tld. So keep
# in mind that this may differ on your system.

# Uncomment the following line if you want to write a log file for debugging.
# logfile "$HOME/maildrop.log"

# Pipe the mail through spamassassin
# (replace 'spamassassin' with 'spamc' if you use the spamc/spamd combination)
#
# The condition line ensures that only messages smaller than 200 KB
# (200 * 1024 = 204800 bytes) are processed by SpamAssassin. Most spam
# isn't bigger than a few K and working with big messages can bring
# SpamAssassin to its knees.

if ($SIZE < 204800)
{
  xfilter "/usr/bin/spamassassin"
}

# After Filtering Behaviors
#
# Almost certainly spams (Mails with a score of 15 or more) will be deleted.
# Probably spams (Mails with a score in between 5 and 14) will be quarantined.
# The rest will be delivered.

if ( /^X-Spam-Level: ***************/:h )
{
  to /dev/null
  exit
}

if ( (/^X-Spam-Flag: YES/:h) || (/^X-Spam-Status: Yes/:h) )
{
  to "$DEFAULT/.Spam/"
}

# As mentioned in maildrop man page, maildrop will deliver any emails not
# filtered in any of the above instructions to the default mailbox.


The above is my current setting. More maildrop configuration examples you can refer are listed at http://www.gentoo-wiki.com/Maildrop_configuration.

Since maildrop uses MySQL backend to get uid/gid/id/crypt/clear/home/name/maildir, make sure users table of your maildb database contains an entry for each local user too.

Postfix document regarding maildrop at http://www.postfix.org/MAILDROP_README.html explains on how to configure postfix to deliver mail using local delivery agent as an intermediate meaning that maildrop can filter local users' email without much hassles. (I already applied the changes to my main.cf with a mailbox_command command) So changing any virtual: entries in transport table of your maildb database to maildrop: is necessary, but local domain which has Linux shell accounts on it isn't.

Next time, we will move on to assassin spam emails with no mercy. I'd rather wanna kill those suckers sending 'em though.

There's not much setting for SpamAssassin at least to me.

I installed spamassassin rpms with YaST.

Then, visited
http://www.yrex.com/spam/spamconfig.php to create my `local.cf` configuration automatically. It is then located in /etc/mail/spamassassin/local.cf directory.

# SpamAssassin config file for version 3.x
# Generated by http://www.yrex.com/spam/spamconfig.php (version 1.50)

# Hostname

report_hostname  your-domain-name.com

# How many hits before a message is considered spam.
required_score  5.0

# Encapsulate spam in an attachment (0=no, 1=yes, 2=safe)
report_safe  1

# Enable the Bayes system
use_bayes  1

# Enable Bayes auto-learning
bayes_auto_learn 1

# Enable or disable network checks
skip_rbl_checks  0
use_razor2  1
use_dcc   1
use_pyzor  1

# Mail using languages used in these country codes will not be marked
# as being possibly spam in a foreign language.
# - english korean
ok_languages  en ko

# Mail using locales used in these country codes will not be marked
# as being possibly spam in a foreign language.
ok_locales  en ko

Lastly, as mentioned in spamassassin document, I uncommented the last four rules in /usr/share/spamassassin/user_prefs.template file.

Well, I can tweak it a bit further for additional features. but, I probably settle down with my current setting at least for now.

This is it folks, If you need an email server on SuSE Linux 10.0 OSS edition with;

Postfix
Courier-IMAP
Courier-Authlib
Courier-Maildrop
Cyrus SASL
MySQL
SpamAssassin

This how-to would save you a big time. After all SuSE Linux isn't probably the best choice for this configuration. Yet, it is still my favorite. Kudo's to SuSE development team!