Version 14 (modified by Jamie McClelland, 14 years ago) (diff)


Setup Debian Server for May First/People Link

Purchase an ssl certificate

  • Generate a private key and certificate signing request.
openssl genrsa -out 4096
openssl req -new -key -out
  • Change the domain@… email alias to point to your address.
  • Go to Godaddy (which is a thawte reseller) for This will take a day or so to be generated.
  • Concat the CRT and KEY file into a file called: (replace server with the name of the server being setup)
  • Then add dh paramaters with:
openssl gendh >>

This file will be used by courier. Copy into /etc/courier/imapd.pem and /etc/courier/pop3d.pem

  • Now, put each one in a separate file called: and (these will be used by apache)

Use volatile for SA and clamav

  • Edit /etc/apt/sources.list. Add the following:
    # clamav (volatile) and spam assassin (volatile-sloppy)
    deb etch/volatile main
    deb etch/volatile-sloppy main

Install debian packages

$ sudo apt-get install apache2 libapache2-mod-suphp cvs amavisd-new clamav clamav-daemon spamassassin maildrop courier-imap-ssl courier-pop-ssl scponly logcheck logcheck-database cron-apt awstats razor libnet-dns-perl dcc-client phpmyadmin php5-mysql php5-imap php5-gd mysql-server-5.0 mysql-client-5.0 squirrelmail php-mail php-db fail2ban aspell aspell-en aspell-es php5-mcrypt php-auth iproute  bzip2 imagemagick php-pear php-log imp4 turba2 ingol php-file

Configure HE routes

In order to route traffic directly from computer to computer (across different subnetworks) we need to add the different routes

  • Create a file called add-he-routes with the following contents. Replace CANONICAL-IP with the IP that you want the server to use as it's src ip. It should be the same as the IP you use when setting up the host DNS record.
# add routes for alternate blocks in rack src CANONICAL-IP
#ip route add dev eth0 src CANONICAL-IP
ip route add dev eth0 src CANONICAL-IP
#ip route add dev eth0 src CANONICAL-IP
ip route add dev eth0 src CANONICAL-IP
ip route add dev eth0 src CANONICAL-IP
  • Comment out the line representing the network this server is on
  • Save the file in /etc/network/if-up.d and chmod it to 755
  • And add a corresponding file:
# remove routes for alternate blocks in rack
ip route del
ip route del
ip route del
#ip route del
ip route del
  • Save the file in /etc/network/if-down.d and chmod it to 755

Configure suPHP

  • Use dpkg-statoverride to change the ownership of our common php web programs (horde, phpmyadmin, and squirrelmail). This script will do it all for you:
    #!/bin/bash -e
    # phpmyadmin
    # use /var/lib/phpmyadmin as home dir because it already exists
    if ! (getent passwd phpmyadmin) ; then
    adduser --system --disabled-login --quiet --home /var/lib/phpmyadmin --shell /bin/false -gid 65534 phpmyadmin
    #userdel phpmyadmin
    phpmyadmin_files =`dpkg -L phpmyadmin | grep '\.php'`
    for file in $phpmyadmin_files; do
    dpkg-statoverride --add --update --force --quiet phpmyadmin nogroup 444 $file
    # #dpkg-statoverride --remove $file
    # horde: share one user between horde and imp and any other horde apps
    # use /var/log/horde as home directory because it already exists
    if ! (getent passwd horde) ; then
    adduser --system --disabled-login --quiet --home /var/log/horde --shell /bin/false -gid 65534 horde
    #userdel horde
    # chown the directory recursively to get existing logs
    # it is written to by the web process
    chown -R horde /var/log/horde
    chown horde /etc/horde/horde3/conf.php
    #chmod 600 /etc/horde/horde3/conf.php
    # add it to the mix
    dpkg-statoverride --add --update --force --quiet  horde nogroup 644 /var/log/horde
    #dpkg-statoverride --remove /var/log/horde
    # ack - this is not mainainable!
    perl -pi -e 's/www-data www-data/horde nogroup/g' /etc/logrotate.d/horde3
    horde_files =`dpkg -L horde3 | grep '\.php'`
    imp_files =`dpkg -L imp4 | grep '\.php'`
    turba_files =`dpkg -L turba2 | grep '\.php'`
    ingo_files =`dpkg -L ingo1 | grep '\.php'`
    all_horde_files ="$horde_files $imp_files $turba_files $ingo_files"
    for file in $all_horde_files; do
    dpkg-statoverride --add --update --force --quiet horde nogroup 444 $file
    #dpkg-statoverride --remove $file
    if ! (getent passwd|grep squirrelmail) ; then
    adduser --system --disabled-login --quiet --home /var/lib/squirrelmail/data --shell /bin/false -gid 65534 squirrelmail
    #userdel squirrelmail
    sm_files =`dpkg -L squirrelmail | grep '\.php'`
    chown -R squirrelmail:nogroup /var/lib/squirrelmail/data
    dpkg-statoverride --add --update --force --quiet squirrelmail nogroup 700 /var/lib/squirrelmail/data
    #dpkg-statoverride --remove /var/lib/squirrelmail/data
    for file in $sm_files; do
    dpkg-statoverride --update --add --force squirrelmail nogroup 444 $file
    #dpkg-statoverride --remove $file
  • Edit /etc/suphp/suphp.conf
    ;Path to logfile
    logfile =/var/log/suphp/suphp.log
    loglevel = info
    ;User Apache is running as
    webserver_user = www-data
    ;Path all scripts have to be in
    docroot =/
    ;Path to chroot() to before executing script
    ;chroot =/mychroot
    ; Security options
    ;allow_file_group_writeable = false
    allow_file_group_writeable = true
    ;allow_file_others_writeable = false
    allow_file_others_writeable = true
    ;allow_directory_group_writeable = false
    allow_directory_group_writeable = true
    ;allow_directory_others_writeable = false
    allow_directory_others_writeable = true
    ;Check wheter script is within DOCUMENT_ROOT
    ;check_vhost_docroot = true
    check_vhost_docroot = false
    ;Send minor error messages to browser
    errors_to_browser = false
    ;PATH environment variable
    env_path =/bin:/usr/bin
    ;Umask to set, specify in octal notation
    ;umask =0077
    umask =0022
    ; Minimum UID
    min_uid =100
    ; Minimum GID
    min_gid =100
    ;Handler for php-scripts
    x-httpd-php = php:/usr/bin/php-cgi
    ;Handler for CGI-scripts
    x-suphp-cgi = execute:!self

Configure fail2ban

Create /etc/fail2ban/jail.local. Modify the following lines, by adding them to the jail.local file that you just created:

bantime  = 200

action = iptables[name =%(__name__)s, port =%(port)s]
mail-whois[name =%(__name__)s, dest =%(destemail)s]

Install Red

  • Edit /etc/apt/sources.list - make sure non-free is there, e.g.: deb stable main contrib non-free. If you are adding anything to this line, run sudo apt-get update afterwards.
    $ sudo apt-get install ucspi-tcp-src
    $ sudo build-ucspi-tcp
  • Create a user in the red database with (change sylvia to name of server):
GRANT SELECT on seso.* to 'red-sylvia'@'' identified by 'secret';
GRANT UPDATE on seso.red_item to 'red-sylvia'@'';
GRANT INSERT on seso.red_error_log to 'red-sylvia'@'';
  • Download the source from cvs
  • Copy and paste the following commands
$ cd /usr/local/share
$ sudo cvs co red
$ sudo ln -s /usr/local/share/red/server/sbin/red_server_cli /usr/local/sbin/
$ sudo ln -s /usr/local/share/red/server/sbin/pinky /usr/local/sbin/
$ sudo chmod 755 /usr/local/share/red/server/sbin/red_server_cli
$ sudo chmod 755 /usr/local/share/red/server/sbin/pinky
$ sudo mkdir /usr/local/etc
$ sudo mkdir /usr/local/etc/red
$ cd /usr/local/share/red/server/etc/red
$ sudo cp /usr/local/share/red/server/etc/red/* /usr/local/etc/red/
$ cd /usr/local/etc/red
$ for file in `ls *.sample`; do sudo cp $file /usr/local/etc/red/${file%.sample}; done;
  • Edit the file called pinky. Change ip address to machine's real ip address. also edit red_server.conf, to add the database user and password.
  • Launch pinky with:
    $ sudo /usr/local/sbin/pinky &

Postfix setup

  • Create aliases in /etc/aliases
www: www-data
  • Don't forget to run newaliases!
  • Create empty access, virtual_alias_maps and virtual_alias_domains files in /etc/postfix
sudo touch virtual_alias_maps virtual_alias_domains access

Create an empty access database (later we can add entries in access to restrict or allow senders):

sudo postmap access
  • Create /var/lib/postfix (used by tls), owned by root
mkdir /var/lib/postfix
  • Add the following to the bottom of the /etc/postfix/ file (change SERVER to the server name)
# May First custom config
# file based virtual hosting configuration
# List of virtual domain names
virtual_alias_domains = hash:/etc/postfix/virtual_alias_domains

# list of email address -> unix account mappings
virtual_alias_maps = hash:/etc/postfix/virtual_alias_maps

# use maildir
home_mailbox = Maildir/

# Added for maildrop
mailbox_command = /usr/bin/maildrop
maildrop_destination_recipient_limit = 1

# Added by jamie 6/10/04 to try to stem the tide of spam
smtpd_sender_restrictions =

# Added for amavisd-new

# to enable authentication for sending email
# and postgrey (policy port 6000 line)
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
broken_sasl_auth_clients = yes
smtpd_recipient_restrictions =
  check_policy_service inet:

# TLS Stuff here:
tls_random_source = dev:/dev/urandom
tls_daemon_random_source = dev:/dev/urandom

# sever side tls - offer tls encryption when an smtp client
# (either user email program or sending smtp server) can use it
smtpd_tls_security_level = may
smtpd_tls_CApath = /etc/ssl/certs
smtpd_tls_loglevel = 1
smtpd_tls_session_cache_database = sdbm:/var/lib/postfix/smtpd_scache
# force people who want to authenticate to use tls - you can't authenticate
# otherwise. This is important because passwords are sent in the clear
smtpd_tls_auth_only = yes
smtpd_tls_key_file = /etc/postfix/ssl/
smtpd_tls_cert_file = /etc/postfix/ssl/
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s

# client side - when we send to a server that offers tls, we should
# accept
smtp_tls_security_level = may
smtp_tls_CApath = /etc/ssl/certs
smtp_tls_session_cache_database = sdbm:/var/lib/postfix/smtp_scache
smtp_tls_loglevel = 1
# recommends leaving these
# lines commented out so we don't present a client certificate.
# It is rare to be required to have a client certificate and presenting
# one sometimes causes problems
#smtp_tls_key_file = /etc/postfix/ssl/
#smtp_tls_cert_file = /etc/postfix/ssl/

  • Copy the /etc/postfix/ file from chavez to get the amavis settings (and for chroot to be turned off)
  • Postfix as secure mail relay setup
  • Install the sasl packages
    sudo apt-get install sasl2-bin libsasl2-modules ca-certificates
  • Configure sasl. Edit /etc/default/saslauthd
    Uncomment START = yes
    Change MECHANISMS to read:
    MECHANISMS ="shadow"
  • Add postfix to the sasl group
    sudo addgroup postfix sasl
  • Make the /etc/postfix/ssl directory and copy the pem files there
    sudo mkdir /etc/postfix/ssl
    sudo cp /whereever/server.pem /etc/postfix/ssl/
  • Edit
    # to enable authentication for sending email
    smtpd_sasl_auth_enable = yes
    smtpd_sasl_security_options = noanonymous
    smtpd_sasl_local_domain = $myhostname
    broken_sasl_auth_clients = yes
    smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination
    # TLS Stuff here:
    smtpd_use_tls = yes
    # force people who want to authenticate to use tls - you can't authenticate
    # otherwise. This is important because passwords are sent in the clear
    smtpd_tls_auth_only = yes
    smtpd_tls_key_file = /etc/postfix/ssl/your-server-key-here.pem
    smtpd_tls_cert_file = /etc/postfix/ssl/your-server-key-here.pem
    smtpd_tls_received_header = yes
    smtpd_tls_session_cache_timeout = 3600s
    tls_random_source = dev:/dev/urandom
  • Edit - uncomment the smtps and submission lines. In both lines change the chroot variable from "-" to "n"
  • Create /etc/postfix/sasl/smtpd.conf
sudo mkdir /etc/postfix/sasl
sudo vim /etc/postfix/sasl/smtpd.conf
# add these lines:
pwcheck_method: saslauthd
mech_list: plain login

Setup Postgrey

Postgrey defers all mail for 5 minutes the first time it receives a message with a never before seen sender and recipient. This results in a lot of spam not being delivered.

  • Install Postgrey
    sudo apt-get install postgrey
  • Edit /etc/default/postgrey adding the following line:
    POSTGREY_TEXT ="Greylisted, see"
  • Restart postgrey
    /etc/init.d/postgrey restart
  • Edit /etc/postfix/, add the following to the end of the smtpd_recipient_restrictions stanza:
    check_policy_service inet:

Setup Courier

  • Create a shared/index file that is empty (to avoid getting error messages in the log)
    mkdir /etc/courier/shared
    touch /etc/courier/index
  • Setup ssl - copy the server pem file (which you got from dotster) to the /etc/courier directories:
    cp /etc/courier/imapd.pem
    cp /etc/courier/pop3d.pem

If you are using Godaddy Certificates, copy the godaddy bundle to /etc/courier/ (you can download it here:

Then add this line to both imapd-ssl and pop3d-ssl:


Setup amavis

  • Edit /etc/amavis/conf.d/50-user

Add the following lines

@bypass_virus_checks_maps = (
\%bypass_virus_checks, \@bypass_virus_checks_acl, \$bypass_virus_checks_re);
$final_banned_destiny     = D_PASS;   # D_REJECT when front-end MTA
$final_spam_destiny       = D_PASS;
$final_bad_header_destiny = D_PASS;
# *Don't* notify me about viruses. Please.
$virus_admin = '';
  • Add clamav to the amavis group with:
    sudo addgroup clamav amavis
  • Add AllowSupplementaryGroups to /etc/clamav/clamd.conf
  • Add a cron job to clean out viruses and spam collected by amavis in /etc/cron.d called clean-up-virus with the contents:
    # Find and delete all emails older than 14 days
    2 4 * * *       amavis  find /var/lib/amavis/virusmails -mtime +14  -exec rm '{}' \;

Configure Spamassassin

  • Install helper packages
    sudo apt-get install razor dcc-client
  • Add a new rule for spamassassin (debian etch or above only!)
  • Create /usr/local/share/spamassassin/plugins
    sudo mkdir /usr/local/share/spamassassin; sudo mkdir /usr/local/share/spamassassin/plugins
  • Download the ImageInfo plugin to that directory
    cd /usr/local/share/spamassassin/plugins
    sudo wget
  • Add rule to /etc/spamassassin
    cd /etc/spamassassin
    sudo wget
  • Edit /etc/spamassassin/init.pre. Add the following line:
    loadplugin Mail::SpamAssassin::Plugin::ImageInfo /usr/local/share/spamassassin/plugins/


  • Enable dcc - uncomment line in /etc/spamassassin/v310.pre the refers to dcc
  • Turn on subject munging (uncomment line in /etc/spamassassin/
  • Add temporary work around to get spamassassin to properly tag messages sent to us via tls by adding this line to /etc/spamassassin/ (change hostname, see
    header LOCAL_AUTH_RCVD    Received =~ /\(using TLS.*\) by chavez\.mayfirst\.org /
    score LOCAL_AUTH_RCVD -20
  • Turn off report safe (in /etc/spamassassin/ set: report_safe 0)
  • Edit /etc/default/spamassassin - enable spamassassin
  • Setup sa-update
    sudo apt-get install gnupg libnet-dns-perl libnet-ssleay-perl libnet-ident-perl
    # test with:
    sudo sa-update -D
    # make sure the above command exited cleanly
    # Create a file in /etc/cron.daily called "mfpl-sa-update" with:
    sa-update && /etc/init.d/spamassassin restart
    # always exit with 0 - sa-update will exit with 1 if no update is available
    # and we don't want cron to report that to us
    exit 0


Edit /etc/maildroprc and add the following lines:

DEFAULT ="$HOME/Maildir"
# spamassassin
xfilter "/usr/bin/spamc -u $LOGNAME"
`test -d $HOME/Maildir/`
if( $RETURNCODE == 1 ) 
  `/usr/bin/maildirmake $HOME/Maildir/`

Webmail setup

  • Symlink the squirrelmail apache conf file:
$ ln -s /etc/squirrelmail/apache.conf /etc/apache2/conf.d/squirrelmail.conf
  • Edit the /etc/apache2/conf.d/horde.conf file. Add:
    Redirect /webmail
  • Copy the various /etc/horde/*/conf.conf files from chavez
  • Edit /etc/horde/imp4/servers.php (see chavez for details)
  • Run sudo /etc/squirrelmail/
  • Change 1: organizational preferences (org name, provider link, provider name)
  • Change 2: server settings: A IMAP Settings (port: 993, secure imap: true,

server software: courier

  • Plugins: install: delete_move_next,squirrelspell, filters,abook_take,listcommands,mail_fetch,gpg (you will need to download

this one from into the /usr/share/squirrelmail/plugins

  • Gunzip/usr/share/doc/horde3/examples/scripts/sql/create.mysql.sql.gz into your home directory
  • Edit - change the password to a good password
  • Import into mysql: Directly import /usr/share/doc/turba2/examples/scripts/sql/turba_objects.mysql.sql with:
mysql -u root -p horde <  /usr/share/doc/turba2/examples/scripts/sql/turba_objects.mysql.sql

Install Drupal

  • Download from into: /usr/local/share/
  • Name the drupal directory after the version (i.e. drupal-4.7.3)
  • Create a soft link to the version (i.e. sudo ln -s drupal-4.7.3 drupal-4.7)
  • Tar up and copy all the files from wiwa /usr/local/share/drupal-modules-4.7 and place into the /usr/local/share/drupal-modules-4.7 on the target server.

Configure Apache

  • In /etc/apache2/site-available/default change NameVirtualHost * to: NameVirtualHost *:80
  • Change:
    <VirtualHost *> to: <VirtualHost *:80>
    DocumentRoot /srv/apache/web (create this directory and index.html file)

Configure logrotate

Create a file called apache2-red in the /etc/logrotate.d directory with:

/home/members/*/sites/*/logs/*.log {
rotate 12
create 644 root root
if [ -f /var/run/ ]; then
/etc/init.d/apache2 restart > /dev/null

Configure logcheck

Copy from Wiwa to the server:


Configure cron-apt

Edit /etc/cron-apt

Change line MAILON to MAILON ="upgrade"

Configure Awstats

  • Copy /etc/awstats/awstats.conf.local from chavez to the target server's /etc/awstats directory
  • Copy /usr/local/sbin/mf-awstats-create, /usr/local/sbin/mf-awstats-build-staticpages, and /usr/local/etc/awstats-create from

chavez to the target server.

  • Copy /usr/share/doc/awstats/examples/ to /usr/local/sbin/
  • Copy /usr/share/doc/awstats/examples/apache.conf to /etc/apache2/conf.d/awstats

Configure Mutt

Create /etc/Muttrc.d and put a file named maildir.rc with

set mbox_type = Maildir
set mbox =~/Maildir
set spoolfile =~/Maildir
set folder =~/Maildir

Change ssh

Make sure the following settings are set:

PermitRootLogin no
AllowGroups sshusers
# Required for Contribute. Grr.
PasswordAuthentication yes

Congifure phpmyadmin

Copy the apache conf file from /etc/phpmyadmin to /etc/apach2/conf.d

cp /etc/phpmyadmin/apache.conf /etc/apache2/conf.d/phpmyadmin

Add the phpmyadmin alias:

echo "Alias /phpmyadmin /usr/share/phpmyadmin" >> /etc/apache2/conf.d/phpmyadmin

Setup Backup

  • Copy the /usr/local/sbin/mf-backup and /etc/mf-backup.xml files from another server
  • Edit /etc/mf-backup.xml as needed
  • Be sure to grant the mysql backup user the proper permissions with:
    GRANT SELECT,SHOW VIEW,LOCK TABLES ON *.* TO 'backup'@'localhost' identified by 'secret'