Do da math...

Here is my spam filter stats over the last year or so. If you do the math on the total received vs the total allowed it's pretty impressive. Out of nearly 3.9 million emails received it allowed just over 2.5% of all email through. That's over 97% of all inbound email is spam. And that's with it not cranked down as tight as it could be. I'm sure I could get over 98% out of it if needed. Yes, I'm know I'm a geek...

Factory reset a Cisco 7640 or 7960...

I've been using the Cisco 7940 and 7960 phones for a while now. That's why I was so surprised the other day to find a handy way to do a factory reset on them. I don't know how I could have missed it all this time...

Simply hold down the # key while you power-cycle the phone. (If you already have the SIP firmware loaded, simply press * and 6 and Settings at the same time, and the phone will reboot. Then press and hold the # key while it boots.)

After a second or two, the phone display will say:

Reset key sequence detected

The headset, mute, and speakerphone lights will cycle. Now, simply press the following keys:

1 2 3 4 5 6 7 8 9 * 0 #

Now, the phone will ask you whether or not you want to save your network configuration. I usually press 2 for no.

Save network cfg? 1=yes 2=no

The display will then say:

Factory reset initiated

and the phone will continue to boot. There you have it -- a quick and easy way to do a factory reset.

WARNING, Work Stuff: Panasonic KV-S2045c/Kofax Out of Paper error...

Issue: I have a Windows XP SP1 machine. It has a Kofax Adrenaline 650i scsi card and a Panasonic KV-S2045c scanner attached. After upgrading to SP2 all scanning stops. Home grown scan software has weird random crash. Panasonic RTIV scan software has a divide by zero crash. Kofax vcdemo and vbdemo report Out of paper error. Reinstalling, removing, upgrading, or downgrading and all combonations of those do not fix it. Uninstalling SP2 does fix this issue.

Fix: Downloaded ASPI drivers from adaptec at http://www.adaptec.com/en-US/speed/software_pc/aspi/aspi_471a2_exe.htm . Ran aspiinst.exe and then aspichk.exe and verified that updated drivers were installed. Rebooted and attempted to scan. Same error. Removed scanner from device manager and attempted a scan. This time it worked as normal. Made a few scans just to be sure. Scanned for new hardware, reinstalled scanner drivers when asked.

All is well...

Mysql replication heartbeat script

#!/usr/bin/perl -w

## On a slave server, check to see that the slave hasn't stopped.

use strict;
use DBIx::DWIW;

my $conn = DBIx::DWIW->Connect(
DB => "mysql",
User => "root",
Pass => "7mailliw",
Host => "localhost",
) or exit;

my $info = $conn->Hash("SHOW SLAVE STATUS");

if (exists $info->{Slave_SQL_Running} and $info->{Slave_SQL_Running} eq 'No')
{
warn "slave SQL thread has stopped\n";

my $to = 'rootnotification@aghealth123.com';
my $from = 'root@avenger.aghealth123.com';
my $subject = '*******Avenger Replication Failed*******';
open(MAIL, "|/usr/sbin/sendmail -t");
print MAIL "To: $to\n";
print MAIL "From: $from\n";
print MAIL "Subject: $subject\n\n";
print MAIL "Mysql heartbeat script has detected that mysql replication
has failed between agdb1 and avenger.

Thanks...
root\n";
close(MAIL);

}
elsif (exists $info->{Slave_IO_Running} and $info->{Slave_IO_Running} eq 'No')
{
warn "slave IO thread has stopped\n";

my $to = 'rootnotification@aghealth123.com';
my $from = 'root@avenger.aghealth123.com';
my $subject = '*******Avenger Replication Failed*******';
open(MAIL, "|/usr/sbin/sendmail -t");
print MAIL "To: $to\n";
print MAIL "From: $from\n";
print MAIL "Subject: $subject\n\n";
print MAIL "Mysql heartbeat script has detected that mysql replication
has failed between agdb1 and avenger.

Thanks...
root\n";
close(MAIL);
}
elsif (exists $info->{Slave_Running} and $info->{Slave_Running} eq 'No')
{
warn "slave has stopped\n";

my $to = 'rootnotification@aghealth123.com';
my $from = 'root@avenger.aghealth123.com';
my $subject = '*******Avenger Replication Failed*******';
open(MAIL, "|/usr/sbin/sendmail -t");
print MAIL "To: $to\n";
print MAIL "From: $from\n";
print MAIL "Subject: $subject\n\n";
print MAIL "Mysql heartbeat script has detected that mysql replication
has failed between agdb1 and avenger.

Thanks...
root\n";
close(MAIL);
}

dirlist

#This program grabs the directory listing from the
#clients fromclient directory. Determines if it is a
#file, if so it logs in in the csv file. Then it emails
#the file to the users listed in the mailatt.php file.
#
#Requested by Scott

cd /home/list #For crontab reasons. It's lost with out it.

logfile="fromclient`date +%Y%m%d%H%M`.csv" #Initially sets the log file name

echo "This report contains fromclient directory." >> $logfile
dir_list_array=( $(ls /home/ftpusers) ) #Loads ls results into an array
dl_count=${#dir_list_array[@]} #Determines the array length and sets a var
dl_index=0 #Inital set of the index var

while [ "$dl_index" -lt "$dl_count" ] #Loops for each dir name in the array
do
client=${dir_list_array[$dl_index]} #makes code easier to look at

if [[ $client == ftp* ]] #Determines if the dir starts with FTP. If so processes
then
frompath="/home/ftpusers/$client/fromclient" #Once again, to make code easier to read
fromclient_array=( $(ls $frompath) ) #Loads ls results into an array
fc_count=${#fromclient_array[@]} #Determines the array length and sets a var
fc_index=0 #Inital set of the index var

while [ "$fc_index" -lt "$fc_count" ] #Loops for each dir name in the array
do
listfile=${fromclient_array[$fc_index]} #Easier to read
filepath="$frompath/$listfile" #Sets path to actual file
if [[ -f $filepath ]] #Check to see if file or dir
then
# date=`find "$filepath" -prune -printf "%Tm%Td%TY%TT"`
date=`find "$filepath" -prune -printf "%Tc"` #Grabs file date and formats it
echo "$client , $listfile, $date" >> $logfile #Create and append csv file
fi
let "fc_index = $fc_index +1" #Increment counter
done

fi
let "dl_index = $dl_index +1" #Increment counter
done

###########################Non-standard Directories######################

while read ns_dirname
do
ns_array=( $(ls $ns_dirname) ) #Loads ls results into an array
ns_count=${#ns_array[@]} #Determines the array length and sets a var
ns_index=0 #Inital set of the index var

while [ "$ns_index" -lt "$ns_count" ] #Loops for each dir name in the array
do
ns_listfile=${ns_array[$ns_index]} #Easier to read
filepath="$ns_dirname/$ns_listfile" #Sets path to actual file
if [[ -f $filepath ]] #Check to see if file or dir
then
date=`find "$filepath" -prune -printf "%Tc"` #Grabs file date and formats it
echo "$ns_dirname, $ns_listfile, $date" >> $logfile #Create and append csv file
fi
let "ns_index = $ns_index +1" #Increment counter
done
done

dirlist2

#This program grabs the directory listing from the
#clients fromclient and the archive directory. Determines
#if it is a file, if so it logs in in the csv file. Then
#it emails the file to the users listed in the mailatt.php file.
#
#Requested by Armando

cd /home/list2 #For crontab reasons. It's lost with out it.

logfile="fromclient`date +%Y%m%d%H%M`.csv" #Initially sets the log file name
echo "Client, Root Directory, Filename, Date" >> $logfile

dir_list_array=( $(ls /home/ftpusers) ) #Loads ls results into an array
dl_count=${#dir_list_array[@]} #Determines the array length and sets a var
dl_index=0 #Inital set of the index var

while [ "$dl_index" -lt "$dl_count" ] #Loops for each dir name in the array
do
client=${dir_list_array[$dl_index]} #makes code easier to look at

if [[ $client == ftp* ]] #Determines if the dir starts with FTP. If so processes
then
frompath="/home/ftpusers/$client/fromclient" #Once again, to make code easier to read
fromclient_array=( $(ls $frompath) ) #Loads ls results into an array
fc_count=${#fromclient_array[@]} #Determines the array length and sets a var
fc_index=0 #Inital set of the index var

while [ "$fc_index" -lt "$fc_count" ] #Loops for each dir name in the array
do
listfile=${fromclient_array[$fc_index]} #Easier to read
filepath="$frompath/$listfile" #Sets path to actual file
if [[ -f $filepath ]] #Check to see if file or dir
then
date=`find "$filepath" -prune -printf "%Tm%Td%TY%TT"`
# date=`find "$filepath" -prune -printf "%Tc"` #Grabs file date and formats it
echo "$client , fromclient, $listfile, $date" >> $logfile #Create and append csv file
else
if [[ $listfile == archive ]]
then
archpath="$frompath/archive"
archive_array=( $(ls $archpath) ) #Loads ls results into an array
ar_count=${#archive_array[@]} #Determines the array length and sets a var
ar_index=0 #Inital set of the index var

while [ "$ar_index" -lt "$ar_count" ] #Loops for each dir name in the array
do
ar_listfile=${archive_array[$ar_index]} #Easier to read
ar_filepath="$archpath/$ar_listfile" #Sets path to actual file
if [[ -f $ar_filepath ]] #Check to see if file or dir
then
ar_date=`find "$ar_filepath" -prune -printf "%Tm%Td%TY%TT"`
# ar_date=`find "$ar_filepath" -prune -printf "%Tm"/"%Td"/"%TY %Tr"`
# ar_date=`find "$ar_filepath" -prune -printf "%Tc"` #Grabs file date and formats
echo "$client , archive, $ar_listfile, $ar_date" >> $logfile
fi
let "ar_index = $ar_index +1" #Increment Counter
done
fi
fi
let "fc_index = $fc_index +1" #Increment counter
done

fi
let "dl_index = $dl_index +1" #Increment counter
done
cp $logfile /home/ftpusers/fromclient_list.csv
php mailatt.php subject="Daily fromclient and archive data" log=$logfile #Email log file.

archive ftp logs

include("/etc/function.php");

compresslog();

?>


FUNCTIONS


error_reporting(E_ALL);


//*********************************************************************************************************************

// COMPRESSLOG

//*********************************************************************************************************************

function compresslog() {


include("/etc/tar.php");

$logfile_list = "/var/log/vsftpd.log";

$filename = "/var/log/vsftpd/logarchive" . date("YmdHis") . ".tar.gz";

$tar_object = new Archive_Tar($filename, true);

$tar_object->setErrorHandling(PEAR_ERROR_PRINT); // Optional error handling

$tar_object->createModify($logfile_list, "");

if(!unlink($logfile_list)) {

echo "A problem was encountered attempting to delete $logfile_list .";

}

}


?>

Mysql replication setup

Taken from http://dev.mysql.com/doc/refman/5.0/en/replication-howto.html

6.4. How to Set Up Replication

This section briefly describes how to set up complete replication of a MySQL server. It assumes that you want to replicate all databases on the master and have not previously configured replication. You must shut down your master server briefly to complete the steps outlined here.

This procedure is written in terms of setting up a single slave, but you can repeat it to set up multiple slaves.

Although this method is the most straightforward way to set up a slave, it is not the only one. For example, if you have a snapshot of the master's data, and the master already has its server ID set and binary logging enabled, you can set up a slave without shutting down the master or even blocking updates to it. For more details, please see Section 6.10, “Replication FAQ”.

If you want to administer a MySQL replication setup, we suggest that you read this entire chapter through and try all statements mentioned in Section 13.6.1, “SQL Statements for Controlling Master Servers”, and Section 13.6.2, “SQL Statements for Controlling Slave Servers”. You should also familiarize yourself with the replication startup options described in Section 6.8, “Replication Startup Options”.

Note: This procedure and some of the replication SQL statements shown in later sections require the SUPER privilege.

1.

Make sure that the versions of MySQL installed on the master and slave are compatible according to the table shown in Section 6.5, “Replication Compatibility Between MySQL Versions”. Ideally, you should use the most recent version of MySQL on both master and slave.

If you encounter a problem, please do not report it as a bug until you have verified that the problem is present in the latest MySQL release.
2.

Set up an account on the master server that the slave server can use to connect. This account must be given the REPLICATION SLAVE privilege. If the account is used only for replication (which is recommended), you don't need to grant any additional privileges.

Suppose that your domain is mydomain.com and that you want to create an account with a username of repl such that slave servers can use the account to access the master server from any host in your domain using a password of slavepass. To create the account, use this GRANT statement:

mysql> GRANT REPLICATION SLAVE ON *.*
-> TO 'repl'@'%.mydomain.com' IDENTIFIED BY 'slavepass';

If you plan to use the LOAD TABLE FROM MASTER or LOAD DATA FROM MASTER statements from the slave host, you must grant this account additional privileges:
*

Grant the account the SUPER and RELOAD global privileges.
*

Grant the SELECT privilege for all tables that you want to load. Any master tables from which the account cannot SELECT will be ignored by LOAD DATA FROM MASTER.

For additional information about setting up user accounts and privileges, see Section 5.9, “MySQL User Account Management”.
3.

Flush all the tables and block write statements by executing a FLUSH TABLES WITH READ LOCK statement:

mysql> FLUSH TABLES WITH READ LOCK;

For InnoDB tables, note that FLUSH TABLES WITH READ LOCK also blocks COMMIT operations. When you have acquired a global read lock, you can start a filesystem snapshot of your InnoDB tables. Internally (inside the InnoDB storage engine) the snapshot won't be consistent (because the InnoDB caches are not flushed), but this is not a cause for concern, because InnoDB resolves this at startup and delivers a consistent result. This means that InnoDB can perform crash recovery when started on this snapshot, without corruption. However, there is no way to stop the MySQL server while insuring a consistent snapshot of your InnoDB tables.

Leave running the client from which you issue the FLUSH TABLES statement so that the read lock remains in effect. (If you exit the client, the lock is released.) Then take a snapshot of the data on your master server.

The easiest way to create a snapshot is to use an archiving program to make a binary backup of the databases in your master's data directory. For example, use tar on Unix, or PowerArchiver, WinRAR, WinZip, or any similar software on Windows. To use tar to create an archive that includes all databases, change location into the master server's data directory, then execute this command:

shell> tar -cvf /tmp/mysql-snapshot.tar .

If you want the archive to include only a database called this_db, use this command instead:

shell> tar -cvf /tmp/mysql-snapshot.tar ./this_db

Then copy the archive file to the /tmp directory on the slave server host. On that machine, change location into the slave's data directory, and unpack the archive file using this command:

shell> tar -xvf /tmp/mysql-snapshot.tar

You may not want to replicate the mysql database if the slave server has a different set of user accounts from those that exist on the master. In this case, you should exclude it from the archive. You also need not include any log files in the archive, or the master.info or relay-log.info files.

While the read lock placed by FLUSH TABLES WITH READ LOCK is in effect, read the value of the current binary log name and offset on the master:

mysql > SHOW MASTER STATUS;
+---------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------+----------+--------------+------------------+
| mysql-bin.003 | 73 | test | manual,mysql |
+---------------+----------+--------------+------------------+

The File column shows the name of the log and Position shows the offset within the file. In this example, the binary log file is mysql-bin.003 and the offset is 73. Record these values. You need them later when you are setting up the slave. They represent the replication coordinates at which the slave should begin processing new updates from the master.

If the master has been running previously without binary logging enabled, the log name and position values displayed by SHOW MASTER STATUS or mysqldump --master-data will be empty. In that case, the values that you need to use later when specifying the slave's log file and position are the empty string ('') and 4.

After you have taken the snapshot and recorded the log name and offset, you can re-enable write activity on the master:

mysql> UNLOCK TABLES;

If you are using InnoDB tables, ideally you should use the InnoDB Hot Backup tool, which takes a consistent snapshot without acquiring any locks on the master server, and records the log name and offset corresponding to the snapshot to be later used on the slave. Hot Backup is an additional non-free (commercial) tool that is not included in the standard MySQL distribution. See the InnoDB Hot Backup home page at http://www.innodb.com/manual.php for detailed information.

Without the Hot Backup tool, the quickest way to take a binary snapshot of InnoDB tables is to shut down the master server and copy the InnoDB data files, log files, and table format files (.frm files). To record the current log file name and offset, you should issue the following statements before you shut down the server:

mysql> FLUSH TABLES WITH READ LOCK;
mysql> SHOW MASTER STATUS;

Then record the log name and the offset from the output of SHOW MASTER STATUS as was shown earlier. After recording the log name and the offset, shut down the server without unlocking the tables to make sure that the server goes down with the snapshot corresponding to the current log file and offset:

shell> mysqladmin -u root shutdown

An alternative that works for both MyISAM and InnoDB tables is to take an SQL dump of the master instead of a binary copy as described in the preceding discussion. For this, you can use mysqldump --master-data on your master and later load the SQL dump file into your slave. However, this is slower than doing a binary copy.
4.

Make sure that the [mysqld] section of the my.cnf file on the master host includes a log-bin option. The section should also have a server-id=master_id option, where master_id must be a positive integer value from 1 to 232 – 1. For example:

[mysqld]
log-bin=mysql-bin
server-id=1

If those options are not present, add them and restart the server. The server cannot act as a replication master unless binary logging is enabled.

Note: For the greatest possible durability and consistency in a replication setup using InnoDB with transactions, you should use innodb_flush_log_at_trx_commit=1, sync_binlog=1, and, before MySQL 5.0.3, innodb_safe_binlog, in the master my.cnf file. (innodb_safe_binlog is not needed from 5.0.3 on.)
5.

Stop the server that is to be used as a slave and add the following lines to its my.cnf file:

[mysqld]
server-id=slave_id

The slave_id value, like the master_id value, must be a positive integer value from 1 to 232 – 1. In addition, it is necessary that the ID of the slave be different from the ID of the master. For example:

[mysqld]
server-id=2

If you are setting up multiple slaves, each one must have a unique server-id value that differs from that of the master and from each of the other slaves. Think of server-id values as something similar to IP addresses: These IDs uniquely identify each server instance in the community of replication partners.

If you do not specify a server-id value, it is set to 1 if you have not defined master-host; otherwise it is set to 2. Note that in the case of server-id omission, a master refuses connections from all slaves, and a slave refuses to connect to a master. Thus, omitting server-id is good only for backup with a binary log.
6.

If you made a binary backup of the master server's data, copy it to the slave server's data directory before starting the slave. Make sure that the privileges on the files and directories are correct. The system account that you use to run the slave server must be able to read and write the files, just as on the master.

If you made a backup using mysqldump, start the slave first. The dump file is loaded in a later step.
7.

Start the slave server. If it has been replicating previously, start the slave server with the --skip-slave-start option so that it doesn't immediately try to connect to its master. You also may want to start the slave server with the --log-warnings option to get more messages in the error log about problems (for example, network or connection problems). The option is enabled by default, but aborted connections are not logged to the error log unless the option value is greater than 1.
8.

If you made a backup of the master server's data using mysqldump, load the dump file into the slave server:

shell> mysql -u root -p CHANGE MASTER TO
-> MASTER_HOST='master_host_name',
-> MASTER_USER='replication_user_name',
-> MASTER_PASSWORD='replication_password',
-> MASTER_LOG_FILE='recorded_log_file_name',
-> MASTER_LOG_POS=recorded_log_position;

The following table shows the maximum allowable length for the string-valued options:
MASTER_HOST 60
MASTER_USER 16
MASTER_PASSWORD 32
MASTER_LOG_FILE 255
10.

Start the slave threads:

mysql> START SLAVE;

After you have performed this procedure, the slave should connect to the master and catch up on any updates that have occurred since the snapshot was taken.

If you have forgotten to set the server-id option for the master, slaves cannot connect to it.

If you have forgotten to set the server-id option for the slave, you get the following error in the slave's error log:

Warning: You should set server-id to a non-0 value if master_host
is set; we will force server id to 2, but this MySQL server will
not act as a slave.

You also find error messages in the slave's error log if it is not able to replicate for any other reason.

Once a slave is replicating, you can find in its data directory one file named master.info and another named relay-log.info. The slave uses these two files to keep track of how much of the master's binary log it has processed. Do not remove or edit these files unless you know exactly what you are doing and fully understand the implications. Even in that case, it is preferred that you use the CHANGE MASTER TO statement to change replication parameters. The slave will use the values specified in the statement to update the status files automatically.

Note: The content of master.info overrides some of the server options specified on the command line or in my.cnf. See Section 6.8, “Replication Startup Options”, for more details.

Once you have a snapshot of the master, you can use it to set up other slaves by following the slave portion of the procedure just described. You do not need to take another snapshot of the master; you can use the same one for each slave.

Linux Server Setup

Installing And Configuring The Rest Of The System

Configure Additional IP Addresses

If you want to add more IP addresses to your system, simply run

yast2

The YaST Control Center will pop up. Go to Network Devices -> Network Card. The next steps are the same as during the network setup in the installation.

Setting The Hostname

echo server1.example.com > /etc/hostname
/bin/hostname -F /etc/hostname

Install apt For SUSE

apt is the packaging system used on Debian. Since it cares much better for package dependencies than rpm it would be nice if we could use it on our new SUSE system. This would save us a lot of hassle. Fortunately, apt has been ported to a lot of rpm based distributions, and is also available for SUSE 9.3 (you will love it... Smile).

rpm -ivh ftp://ftp.gwdg.de/pub/linux/suse/apt/SuSE/9.3-i386/RPMS.suser-rbos/\
apt-libs-0.5.15cnc7-0.suse093.rb0.i586.rpm
rpm -ivh ftp://ftp.gwdg.de/pub/linux/suse/apt/SuSE/9.3-i386/RPMS.suser-rbos/\
apt-0.5.15cnc7-0.suse093.rb0.i586.rpm

Edit /etc/apt/sources.list. It should contain the following line:

rpm ftp://ftp.gwdg.de/pub/linux/suse/apt/ SuSE/9.3-i386 base update security

Run

apt-get update

Install Some Software And Deactivate SUSE's Firewall

apt-get install findutils ncftp readline libgcc glibc-devel findutils-locate gcc flex lynx compat-readline4 db-devel

/etc/init.d/SuSEfirewall2_setup stop
chkconfig --del SuSEfirewall2_setup
chkconfig --del SuSEfirewall2_init

Quota

apt-get install quota

Edit /etc/fstab to look like this (I added ,usrquota,grpquota to partition /dev/sda2 (mount point /; your device name might be /dev/hda2 or similar)):

/dev/sda2 / reiserfs acl,user_xattr,usrquota,grpquota 1 1
/dev/sda1 swap swap pri=42 0 0
devpts /dev/pts devpts mode=0620,gid=5 0 0
proc /proc proc defaults 0 0
usbfs /proc/bus/usb usbfs noauto 0 0
sysfs /sys sysfs noauto 0 0
/dev/cdrecorder /media/cdrecorder subfs noauto,fs=cdfss,ro,procuid,nosuid,nodev,exec,iocharset=utf8 0 0
/dev/fd0 /media/floppy subfs noauto,fs=floppyfss,procuid,nodev,nosuid,sync 0 0

Then run:

touch /aquota.user /aquota.group
chmod 600 /aquota.*
mount -o remount /
quotacheck -avugm
quotaon -avug

DNS-Server

apt-get install bind bind-chrootenv bind-devel bind-utils

chkconfig --add named
/etc/init.d/named start

Bind will run in a chroot jail under /var/lib/named.

MySQL

apt-get install mysql mysql-client mysql-shared mysql-devel perl-DBD-mysql perl-DBI perl-Data-ShowTable

chkconfig --add mysql
/etc/init.d/mysql start

Now check that networking is enabled. Run

netstat -tap

It should show a line like this:

tcp 0 0 *:mysql *:* LISTEN 6621/mysqld

If it does not, edit /etc/my.cnf, comment out the option skip-networking:

# Don't listen on a TCP/IP port at all. This can be a security enhancement,
# if all processes that need to connect to mysqld run on the same host.
# All interaction with mysqld must be made via Unix sockets or named pipes.
# Note that using this option without enabling named pipes on Windows
# (via the "enable-named-pipe" option) will render mysqld useless!
#
#skip-networking

and restart your MySQL server:

/etc/init.d/mysql restart

Run

mysqladmin -u root password yourrootsqlpassword

to set a password for the user root (otherwise anybody can access your MySQL database!).

Postfix With SMTP-AUTH And TLS

apt-get install cyrus-sasl cyrus-sasl-crammd5 cyrus-sasl-devel cyrus-sasl-digestmd5 cyrus-sasl-gssapi cyrus-sasl-otp cyrus-sasl-plain cyrus-sasl-saslauthd

chkconfig --add saslauthd
/etc/init.d/saslauthd start

mkdir /etc/postfix/ssl
cd /etc/postfix/ssl/
openssl genrsa -des3 -rand /etc/hosts -out smtpd.key 1024
chmod 600 smtpd.key
openssl req -new -key smtpd.key -out smtpd.csr
openssl x509 -req -days 3650 -in smtpd.csr -signkey smtpd.key -out smtpd.crt
openssl rsa -in smtpd.key -out smtpd.key.unencrypted
mv -f smtpd.key.unencrypted smtpd.key
openssl req -new -x509 -extensions v3_ca -keyout cakey.pem -out cacert.pem -days 3650

postconf -e 'mydomain = example.com'
postconf -e 'myhostname = server1.$mydomain'
postconf -e 'smtpd_sasl_local_domain ='
postconf -e 'smtpd_sasl_auth_enable = yes'
postconf -e 'smtpd_sasl_security_options = noanonymous'
postconf -e 'broken_sasl_auth_clients = yes'
postconf -e 'smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,check_relay_domains'
postconf -e 'inet_interfaces = all'
postconf -e 'alias_maps = hash:/etc/aliases'
postconf -e 'smtpd_tls_auth_only = no'
postconf -e 'smtp_use_tls = yes'
postconf -e 'smtpd_use_tls = yes'
postconf -e 'smtp_tls_note_starttls_offer = yes'
postconf -e 'smtpd_tls_key_file = /etc/postfix/ssl/smtpd.key'
postconf -e 'smtpd_tls_cert_file = /etc/postfix/ssl/smtpd.crt'
postconf -e 'smtpd_tls_CAfile = /etc/postfix/ssl/cacert.pem'
postconf -e 'smtpd_tls_loglevel = 1'
postconf -e 'smtpd_tls_received_header = yes'
postconf -e 'smtpd_tls_session_cache_timeout = 3600s'
postconf -e 'tls_random_source = dev:/dev/urandom'

Now restart Postfix:

/etc/init.d/postfix restart

To see if SMTP-AUTH and TLS work properly now run the following command:

telnet localhost 25

After you have established the connection to your postfix mail server type

ehlo localhost

If you see the lines

250-STARTTLS

and

250-AUTH

everything is fine.

Type

quit

to return to the system's shell.

Courier-IMAP/Courier-POP3

I want to use a POP3/IMAP daemon that has Maildir support. That's why I use Courier-IMAP and Courier-POP3.

apt-get install courier-imap fam-server

/etc/init.d/courier-authdaemon start
/etc/init.d/courier-imap start
/etc/init.d/courier-imap-ssl start
/etc/init.d/courier-pop3 start
/etc/init.d/courier-pop3-ssl start
chkconfig --add courier-authdaemon
chkconfig --add courier-imap
chkconfig --add courier-imap-ssl
chkconfig --add courier-pop3
chkconfig --add courier-pop3-ssl

Then configure Postfix to deliver emails to a user's Maildir*:

postconf -e 'home_mailbox = Maildir/'
postconf -e 'mailbox_command ='
/etc/init.d/postfix restart

*Please note: You do not have to do this if you intend to use ISPConfig on your system as ISPConfig does the necessary configuration using procmail recipes. But please go sure to enable Maildir under Management -> Settings -> EMail in the ISPConfig web interface.

Apache/PHP5

apt-get install apache2 apache2-devel apache2-mod_perl apache2-mod_php5 apache2-prefork libapr0 perl-HTML-Parser perl-HTML-Tagset perl-Tie-IxHash perl-URI perl-libwww-perl php5 php5-devel

apt-get install php5-bcmath php5-bz2 php5-calendar php5-ctype php5-curl php5-dba php5-dbase php5-dbx php5-debuginfo php5-dio php5-dom php5-fam php5-filepro php5-ftp php5-gd php5-gettext php5-gmp php5-iconv php5-imap php5-ldap php5-mbstring php5-mcrypt php5-mhash php5-mysql php5-mysqli php5-ncurses php5-odbc php5-openssl php5-pcntl php5-pgsql php5-posix php5-readline php5-shmop php5-snmp php5-soap php5-sockets php5-sqlite php5-sysvsem php5-tokenizer php5-wddx php5-xmlrpc php5-xsl php5-yp php5-zlib php5-exif php5-fastcgi php5-pear php5-sysvmsg php5-sysvshm ImageMagick curl (1 line!)

chkconfig --add apache2

Edit /etc/mime.types. Comment out the following 2 lines:

# application/x-httpd-php phtml pht php
# application/x-perl pl pm

Edit /etc/apache2/httpd.conf and change

DirectoryIndex index.html index.html.var

to

DirectoryIndex index.html index.htm index.shtml index.cgi index.php index.php5 index.php4 index.php3 index.pl index.html.var

Edit /etc/sysconfig/apache2 and add rewrite to the APACHE_MODULES line:

APACHE_MODULES="access actions alias auth [...] setenvif ssl suexec userdir php4 php5 rewrite"

Also add SSL to the APACHE_SERVER_FLAGS line:

APACHE_SERVER_FLAGS="SSL"

Then run

SuSEconfig
/etc/init.d/apache2 start

Proftpd

I want to use Proftpd instead of vsftpd which is SUSE's default FTP server because the control panel software I am going to install on this server (ISPConfig) requires Proftpd on SUSE 9.3 (on other distributions this is different). Since there are no SUSE packages for Proftpd I have to compile it manually:

cd /tmp/
wget --passive-ftp ftp://ftp.proftpd.org/distrib/source/proftpd-1.2.10.tar.gz

tar xvfz proftpd-1.2.10.tar.gz
cd proftpd-1.2.10/
./configure --sysconfdir=/etc
make
make install

cd ../
rm -fr proftpd-1.2.10*

Now create the file /etc/init.d/proftpd:

#! /bin/sh
# Copyright (c) 2000-2001 SuSE GmbH Nuernberg, Germany.
# All rights reserved.
#
# Original author: Marius Tomaschewski
#
# Slightly modified in 2003 for use with SuSE Linux 8.1,
# by http://www.learnlinux.co.uk/
#
# Slightly modified in 2005 for use with SuSE Linux 9.2,
# by Falko Timme
#
# /etc/init.d/proftpd
#
### BEGIN INIT INFO
# Provides: proftpd
# Required-Start: $network $remote_fs $syslog $named
# Required-Stop:
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Description: Starts ProFTPD server
### END INIT INFO

# Determine the base and follow a runlevel link name.
base=${0##*/}
link=${base#*[SK][0-9][0-9]}

# Force execution if not called by a runlevel directory.
test $link = $base && START_PROFTPD=yes # Modified by learnlinux.co.uk
test "$START_PROFTPD" = yes || exit 0 # Modified by learnlinux.co.uk

# Return values acc. to LSB for all commands but
# status (see below):
#
# 0 - success
# 1 - generic or unspecified error
# 2 - invalid or excess argument(s)
# 3 - unimplemented feature (e.g. "reload")
# 4 - insufficient privilege
# 5 - program is not installed
# 6 - program is not configured
# 7 - program is not running

proftpd_cfg="/etc/proftpd.conf"
proftpd_bin="/usr/local/sbin/proftpd"
proftpd_pid="/usr/local/var/proftpd.pid"

[ -r $proftpd_cfg ] || exit 6
[ -x $proftpd_bin ] || exit 5

# Source status functions
. /etc/rc.status

# First reset status of this service
rc_reset

case "$1" in
start)
echo -n "Starting ProFTPD Server: "
test -f /etc/shutmsg && rm -f /etc/shutmsg
/sbin/startproc $proftpd_bin
rc_status -v
;;

stop)
echo -n "Shutting down ProFTPD Server: "
test -x /usr/local/sbin/ftpshut && /usr/local/sbin/ftpshut now && sleep 1
/sbin/killproc -TERM $proftpd_bin
test -f /etc/shutmsg && rm -f /etc/shutmsg
rc_status -v
;;

restart)
## If first returns OK call the second, if first or
## second command fails, set echo return value.
$0 stop
$0 start
rc_status
;;

try-restart)
## Stop the service and if this succeeds (i.e. the
## service was running before), start it again.
## Note: not (yet) part of LSB (as of 0.7.5)
$0 status >/dev/null && $0 restart
rc_status
;;

reload|force-reload)
## Exclusive possibility: Some services must be stopped
## and started to force a new load of the configuration.
echo -n "Reload ProFTPD Server: "
/sbin/killproc -HUP $proftpd_bin
rc_status -v
;;

status)
# Status has a slightly different for the status command:
# 0 - service running
# 1 - service dead, but /var/run/ pid file exists
# 2 - service dead, but /var/lock/ lock file exists
# 3 - service not running
echo -n "Checking for ProFTPD Server: "
checkproc $proftpd_bin
rc_status -v
;;

probe)
## Optional: Probe for the necessity of a reload,
## give out the argument which is required for a reload.
[ $proftpd_cfg -nt $proftpd_pid ] && echo reload
;;

*)
echo "Usage: $0 {start|stop|status|restart|reload|try-restart|probe}"
exit 1
;;
esac

# Set an exit status.
rc_exit

chmod 755 /etc/init.d/proftpd
chkconfig --add proftpd

/etc/init.d/proftpd start

For security reasons you can add the following lines to /etc/proftpd.conf:

DefaultRoot ~
IdentLookups off
ServerIdent on "FTP Server ready."

Be sure to comment out the following lines in order to allow ftp users to CHMOD:

# Bar use of SITE CHMOD by default
#
# DenyAll
#

and restart Proftpd:

/etc/init.d/proftpd restart

Webalizer

To install webalizer, just run

apt-get install webalizer

Synchronize the System Clock

If you want to have the system clock synchronized with an NTP server do the following:

apt-get install netdate

netdate tcp 128.2.136.71

Create /var/spool/cron/tabs/root:

# update time with ntp server
0 3,9,15,21 * * * /usr/sbin/netdate 128.2.136.71

Then run

chmod 600 /var/spool/cron/tabs/root
/etc/init.d/cron restart

Install some Perl Modules needed by SpamAssassin (comes with ISPConfig)

Installation using the Perl Shell

Login to your command line as root and run the following command to start the Perl shell:

perl -MCPAN -e shell

If you run the Perl shell for the first time you will be asked some questions. In most cases the default answers are ok.

Please note: If you run a firewall on your system you might have to turn it off while working on the Perl shell in order for the Perl shell to be able to fetch the needed modules without a big delay. You can switch it on afterwards.

The big advantage of the Perl shell compared to the two other methods described here is that it cares about dependencies when installing new modules. I.e., if it turns out that a prerequisite Perl module is missing when you install another module the Perl shell asks you if it should install the prerequisite module for you. You should answer that question with "Yes".

Run the following commands to install the modules needed by SpamAssassin:

install HTML::Parser
install Net::DNS (when prompted to enable tests, choose no)
install Digest::SHA1
install DB_File
q (to leave the Perl shell)

If a module is already installed on your system you will get a message similar to this one:

HTML::Parser is up to date.

Successful installation of a module looks like this:

/usr/bin/make install -- OK

The End

The configuration of the server is now finished, and if you wish you can now install ISPConfig on it.

A Note On SuExec

If you want to run CGI scripts under suExec, you should specify /srv/www as the home directory for websites created by ISPConfig as SUSE 9.3's suExec is compiled with /srv/www as Doc_Root. Run /usr/sbin/suexec2 -V, and the output should look like this:

To select /srv/www as the home directory for websites during the installation of ISPConfig do the following: When you are asked for the installation mode, select the expert mode.

Later during the installation you are asked if the default directory /home/www should be the directory where ISPConfig will create websites in. Answer n and enter /srv/www as the home directory for websites

SFTP over SSH with no shell access (Suse 10.0)

Problem:
I had a need to have users SFTP into my current FTP server. I needed them to be chrooted in their own home directory. I needed them to not have any shell access.

Resources:
The site that helped me the most was ttp://freshmeat.net/articles/view/1576/ I searched over and over and googled myself to death over this one. I found a lot of info that all went in different directions. This is the one that I found worked the best.
RSSH
http://freshmeat.net/projects/rssh/
OPENSSH
http://freshmeat.net/projects/openssh/

Issues:
1. SFTP was the way to go. Fully encrypted with no username/passwords in clear text as with standard FTP.
2. I didn't want the users to have access to an ssh shell.
3. With this setup the way I have it you have to edit your rssh.conf each time you add a user to add their chroot.

Solution:
1. Install OpenSSH
2. Edit /etc/ssh/sshd_config
# Authentication:
LoginGraceTime 1m # only need 1 minute to allow login time
PermitRootLogin no # do not allow root login
#StrictModes yes # default is yes – this should stay
MaxAuthTries 3 # set max tries to 3 (default is 6)
3. Start ssh by running 'rcsshd start'
4. Run 'chkconfig --add sshd' to ensure ssh starts on boot.
5. Test the sftp connection by logging in as a user of the system. If you do not have a user created on the system other than root, create one now.
$ sftp joeblow@localhost
RSA keyfingerprint is ***********************.
Are you sure you want to continue connecting (yes/no)?
After you have said "yes" to the above, your sftp connection will be established, and you will have the following prompt waiting:
sftp>
6. Install RSSH
7. After installation, you need to add rssh to the list of allowed shells.
$ echo /usr/bin/rssh >> /etc/shells
8. Edit the /etc/rssh.conf file to allow chrooting and sftp:
logfacility = LOG_USER
allowsftp
umask = 022
chrootpath="/home"
9. You may, as I needed to, set the chroot for each user.
user=ftpcba:111:00010:/home/ftpusers/ftpcba
Format is user="username":"umask":"service":"chroot dir"
10. Build a chroot for the home of your chroot.
./lib/i686
./lib/i686/libpthread.so.0
./lib/i686/libc.so.6
./lib/libresolv.so.2
./lib/libz.so.1
./lib/libnsl.so.1
./lib/libutil.so.1
./lib/libcom_err.so.2
./lib/libcrypt.so.1
./lib/ld-linux.so.2
./lib/libdl.so.2
./usr/bin/sftp
./usr/lib/ssh/sftp-server
./usr/lib/libasn1.so.6
./usr/lib/libdb-4.1.so
./usr/lib/libcrypto.so.0.9.7
./usr/lib/libkrb5.so.17
./usr/lib/libroken.so.16
./usr/lib/libgssapi.so.1
11. You can find the dependacies of a file by using the ldd command.
12. Edit your user and set their shell to /usr/bin/rssh.
13. DONE!

New ResetFTP Script

#!/bin/bash
#
echo "Starting directory find..."
find /home/ftpusers -type d -fprint dir.txt
echo "Ending directory find."
echo "Starting file find..."
find /home/ftpusers -type f -fprint file.txt
echo "Ending file find."

echo "Starting directory chmod..."
cat dir.txt | grep -i -e "toclient" -e "fromclient" | while read THISLINE
do
echo "chmod on dir $THISLINE"
chmod 770 "$THISLINE"
chgrp ftpusers "$THISLINE"
done
echo "Ending directory chmod."

echo "Starting file chmod..."
cat file.txt | grep -i -e "toclient" -e "fromclient" | while read THISLINE
do
echo "chmod on file $THISLINE"
chmod 660 "$THISLINE"
chgrp ftpusers "$THISLINE"
done
echo "Ending file chmod."

echo "Starting misc rights changes..."
#This is set on scan to prevent client from veiwing directory listings.
chmod -R u-r /home/ftpusers/angscan
chmod -R u-r /home/ftpusers/devangscan
#This is set on jms to prevent them from writing to the root of their ftp.
chmod 577 /home/ftpusers/ftpjms/
echo "Ending misc rights changes."

Reset FTP

#!/bin/bash
#

#for I in `find /home/ftpusers -type d` ; do chmod 777 "$I" ; done
#for X in `find /home/ftpusers -type f` ; do chmod 666 "$X" ; done

#find /home/ftpusers/ftpcba -type d -path'/toclient' > dir.txt
#find /home/ftpusers/ftpcba -type d \( -name toclient -o -name fromclient \) -prune > dir.txt
#find /home/ftpusers -type d > dir.txt
find /home/ftpusers/ftpcba -type d -fprint dir.txt
#find /home/ftpusers -type f > file.txt
find /home/ftpusers/ftpcba -type f -fprint file.txt
#find /home/ftpusers/ftpcba -type f \( -name toclient -o -name fromclient \) -prune > file.txt

cat dir.txt | grep -i -e "toclient" -e "fromclient" | while read THISLINE
do
echo "chmod on dir $THISLINE"
# chmod 777 "$THISLINE"
done

cat file.txt | grep -i -e "toclient" -e "fromclient" | while read THISLINE
do
echo "chmod on file $THISLINE"
# chmod 666 "$THISLINE"
done

#chgrp -R ftpadmin /home/ftpusers
chmod -R u-r /home/ftpusers/angscan
chmod -R u-r /home/ftpusers/devangscan
chmod 577 /home/ftpusers/ftpjms/
chmod 777 /home/ftpusers/ftpjms/toclient/cba/

Start KDE in a VNC session

By default VNC uses the twm window manger but this can easily be modified to your liking. Open the file $HOME/.vnc/xstartup in a editor. Look for "twm &" and modify that to run the window manger of your liking. My choice was KDE for which I modified the line to startkde &". Windowmaker users may want to use "wmaker &" here. You can also place any other commands here that you might want to run at startup. To stop a server use "vncserver -kill :display".