Table of Contents

Necto Installation Instructions

- System preparation

# aptitude install ssh vim smartmontools screen sysstat hdparm dstat tmux htop

- smartd

edit smartd default parameters

# grep -v "^#" /etc/default/smartmontools |grep -v "^$"
enable_smart="/dev/sda /dev/sdb"
start_smartd=yes
smartd_opts="--interval=1800"

edit smartd.conf

# grep -v "^#" /etc/smartd.conf |grep -v "^$"
/dev/sda -a -o on -S on -s (S/../.././02|L/../../6/03) -m root
/dev/sdb -a -o on -S on -s (S/../.././02|L/../../6/03) -m root

- Disable write cache on both hard drives

# hdparm -W 0 /dev/sd{a,b}

/dev/sda:
 setting drive write-caching to 0 (off)
 write-caching =  0 (off)

/dev/sdb:
 setting drive write-caching to 0 (off)
 write-caching =  0 (off)

- Necto account

Create the necto user and the /var/necto directory owned by necto.

# useradd -d /var/necto -m -r -s /bin/false necto

- OpenLDAP

Install Slapd and the LDAP utils

# aptitude install slapd ldap-utils

- Activate syslog

Slapd logs in syslog facility 4.

# vim /etc/rsyslog.conf

local4.*                -/var/log/slapd.log

- Give a password to admin config

During the SlapD installation, the debian installer asks for a root password. This password is a Salted SHA and used for the admin user of the local ldap database. We can copy the password value to use it with the cn=config database.

root@samchiel:/etc/ldap/slapd.d/cn=config# grep RootPW olcDatabase\=\{1\}hdb.ldif 
olcRootPW:: e1NTSEF9NFdZWlZ5MWpzTVMyTlA0a0pKa3M4bEV6NWJxeDdyNmQ=

Now we add this value into olcDatabase\=\{0\}config.ldif

olcRootPW:: e1NTSEF9NFdZWlZ5MWpzTVMyTlA0a0pKa3M4bEV6NWJxeDdyNmQ=

Then restart slapd:

# service slapd restart
[ ok ] Stopping OpenLDAP: slapd.
[ ok ] Starting OpenLDAP: slapd.

- Configuration using cn=config

Unlike previous version of OpenLDAP, 2.4 can use the cn=config database to manage configuration parameters. cn=config is a standard LDAP tree that can be accessed with any LDAP browser (I recommend Apache Directory Studio). Configure a connection to the local SlapD instance using :

Bind DN: cn=admin,cn=config
Bind PW: the root password you specified during the slapd installation
Root DN: cn=config

- Change the log level

Once connected, you can change any configuration parameter. For example, to change the Log Level, go to the CN=Config branch and edit the olcLogLevel value to “stats sync ACL config filter”; This is going to execute a ldapmodify command similar to the one below:

dn: cn=config
changetype: modify
replace: olcLogLevel
olcLogLevel: stats sync ACL config filter
-

Now the huge advantage of cn=config is that it doesn't require a reload of slapd for the changes to take effect, unlike the configuration files.

- Configure the linuxwall.info database

Via cn=config, we can change the internal parameters of the dc=linuxwall,dc=info database. For example, to increase the cache size from 2MB (the default on debian) to 20MB, edit the olcDbConfig inside olcDatabase={1}hdb as follow:

{0}set_cachesize 0 20971520 0

This will generate the following LDAP query

#!RESULT OK
#!CONNECTION ldap://192.168.1.153:389
#!DATE 2011-09-18T13:37:54.823
dn: olcDatabase={1}hdb,cn=config
changetype: modify
replace: olcDbConfig
olcDbConfig: {1}set_lk_max_objects 1500
olcDbConfig: {2}set_lk_max_locks 1500
olcDbConfig: {3}set_lk_max_lockers 1500
olcDbConfig: {0}set_cachesize 0 20971520 0
-

We can also define more indexes on the “cn” and “uid” attributes (the default creates indexes for ObjectClass only).

#!RESULT OK
#!CONNECTION ldap://192.168.1.153:389
#!DATE 2011-09-18T13:44:10.004
dn: olcDatabase={1}hdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: cn eq,sub,pres,approx
-

#!RESULT OK
#!CONNECTION ldap://192.168.1.153:389
#!DATE 2011-09-18T13:45:14.604
dn: olcDatabase={1}hdb,cn=config
changetype: modify
add: olcDbIndex
olcDbIndex: uid eq
-

- Creating users

Use the python script below to generate a SSHA password:

#!/usr/bin/env python
import os, sys, hashlib
from base64 import urlsafe_b64encode as encode
from base64 import urlsafe_b64decode as decode
 
def makeSecret(password):
    salt = os.urandom(4)
    h = hashlib.sha1(password)
    h.update(salt)
    return "{SSHA}" + encode(h.digest() + salt)
 
def checkPassword(challenge_password, password):
    challenge_bytes = decode(challenge_password[6:])
    digest = challenge_bytes[:20]
    salt = challenge_bytes[20:]
    hr = hashlib.sha1(password)
    hr.update(salt)
    return digest == hr.digest()
 
cleartext_password = raw_input("password > ")
challenge_password = makeSecret(cleartext_password)
print challenge_password

Edit the following LDIF:

dn: cn=Bob Kelso,ou=people,dc=linuxwall,dc=info
uid: bob
uidNumber: 10002
gidNumber: 998
sn: Kelso
cn: Bob Kelso
homeDirectory: /dev/null
objectClass: posixAccount
objectClass: top
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
mail: bob@linuxwall.info
userPassword: {SSHA}MJmued-ye7RLJlAjW_g6F5Qj_MYuRR74

import the LDIF into LDAP:

# ldapadd -h 127.0.0.1 -p 389 -D "cn=admin,dc=linuxwall,dc=info" -W -f /root/bob.ldif 
Enter LDAP Password: 
adding new entry "cn=Bob Kelso,ou=people,dc=linuxwall,dc=info"

- Dovecot

Install the package for imap and lmtpd. This will automatically enable dovecot's imap support, and listen for connections on tcp/143.

# apt-get install dovecot-imapd dovecot-lmtpd

- Home and Mail locations

Virtual users need a home directory. We will set that into /var/necto/homedirs. The Maildir will go under ~/Maildir.

# vim /etc/dovecot/conf.d/10-mail.conf

mail_home = /var/necto/homedirs/%n
mail_location = maildir:~/mail

Create a virtualusers group as follow:

# groupadd -r virtualusers
# grep virtualusers /etc/group
virtualusers:x:998:

Users in LDAP must be members of the gid 998.

Now create the directory. It should be owned by necto:virtualusers.

# mkdir /var/necto/homedirs
# chown necto:virtualusers /var/necto/homedirs
# chmod g+rwx /var/necto/homedirs

- IMAP Authentication

Dovecot should be set to accept STARTTLS connections by default. Make sure to disable plain text auth on non encrypted connections.

# vim /etc/dovecot/conf.d/10-auth.conf

disable_plaintext_auth = yes
auth_mechanisms = plain login digest-md5

In /etc/dovecot/conf.d/10-master.conf

service auth {
  unix_listener /var/spool/postfix/private/auth {
    group = postfix
    mode = 0660
    user = postfix
  }
  user = root
}

In /etc/dovecot/conf.d/10-auth.conf, uncomment the line

!include auth-ldap.conf.ext

The configuration of the LDAP auth driver is installed by the dovecot-ldap package into /etc/dovecot/conf.d/auth-ldap.conf.ext. The default is fine.

And then in /etc/dovecot/dovecot-ldap.conf.ext

hosts = localhost:389
auth_bind = yes
ldap_version = 3
base = dc=linuxwall,dc=info
scope = subtree
user_attrs = uidNumber=uid, gidNumber=gid
user_filter = (&(objectClass=inetOrgPerson)(uid=%u))
pass_attrs = uid=user,userPassword=password
pass_filter = (&(objectClass=inetOrgPerson)(uid=%u))

- LMTP delivery from Postfix

In 10-master.conf, enable the LMTP service as follow:

service lmtp {
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    user = postfix
    group = postfix
    mode = 0666
  }
}

The above creates a unix socket inside of Postfix's chroot. Now add this to /etc/postfix/main.cf:

mailbox_transport = lmtp:unix:private/dovecot-lmtp

And finally, tell dovecot to use the username part of an email address when authenticating users. This is done in /etc/dovecot/conf.d/10-auth.conf:

auth_username_format = %n

- Postfix

- Auth

In main.cf

mynetworks = 127.0.0.0/8 [::1]/128

smtpd_sasl_auth_enable = yes 
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_local_domain = $mydomain
smtpd_sasl_security_options = noanonymous
smtpd_sasl_authenticated_header = yes

smtpd_recipient_restrictions = permit_sasl_authenticated, permit_mynetworks, reject_unauth_destination

Postfix will use the socket located in /var/spool/postfix/private/auth to connect to dovecot, and dovecot will verify the authentication against ldap.

- TLS

To enable STARTTLS support in smtp and smtpd, in main.cf:

# TLS server options
smtpd_tls_security_level = may
smtpd_tls_auth_only = yes
smtpd_tls_key_file = /etc/postfix/certs/samchiel.linuxwall.info.key
smtpd_tls_cert_file = /etc/postfix/certs/samchiel.linuxwall.info.crt
smtpd_tls_CAfile = /etc/postfix/certs/ca-linuxwall.crt
smtpd_tls_loglevel = 2
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_tls_session_cache
tls_random_source = dev:/dev/urandom
smtpd_tls_ask_ccert = yes
smtpd_tls_req_ccert = no
smtpd_tls_mandatory_protocols = !SSLv2, SSLv3, TLSv1
smtpd_tls_mandatory_ciphers = high
tls_high_cipherlist = ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:kEDH+AESGCM:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK
tls_preempt_cipherlist = yes

# TLS client options
smtp_use_tls = yes
smtp_tls_note_starttls_offer = yes
smtp_tls_protocols = !SSLv2, SSLv3, TLSv1
smtp_tls_loglevel = 1

- DKIM

apt-get install opendkim-tools opendkim

Activate the TCP socket between postfix and opendkim in /etc/default/opendkim:

SOCKET="inet:5001@localhost" # listen on loopback on port 12345

Configure /etc/opendkim.conf as follow:

Syslog			yes
UMask			002
Domain			linuxwall.info
KeyFile			/etc/dkim/samchiel.private
Selector		samchiel
Canonicalization	simple
Mode			sv
SubDomains		no
AlwaysAddARHeader	yes
OversignHeaders		From

- DKIM key setup

Create /etc/dkim

# mkdir /etc/dkim
# cd /etc/dkim/

Generate the signing key:

root:/etc/dkim# opendkim-genkey -s samchiel
root:/etc/dkim# ls
samchiel.private  samchiel.txt

root:/etc/dkim# cat samchiel.private 
-----BEGIN RSA PRIVATE KEY-----
MII..............
................lm5vYaO/M6VrQOiC0TE=
-----END RSA PRIVATE KEY-----

root:/etc/dkim# cat samchiel.txt 
samchiel._domainkey IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDWYz+pWFNyT0v0+HbRXmpHKR9f4A0kGtucwrbf+5we2YM8rUKoocg4itI18xsE4aB69SZo/oqkY7pqxiE3sNjv/mGaqb3+iiS4REj6sWoeRWZ0MGKdRjln2VKvAhtZOn03GLk1KSIyBMnzFiPOwyftscFdPWgTiRQVsj+OauqQBwIDAQAB" ; ----- DKIM key samchiel for linuxwall.info

Don't forget to change the permissions on /etc/dkim

# chown opendkim /etc/dkim/ -R

Copy the DNS record into you DNS, and test it using dig.

$ dig TXT samchiel._domainkey.linuxwall.info @ns0.linuxwall.info +short

"v=DKIM1\; k=rsa\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDWYz+pWFNyT0v0+HbRXmpHKR9f4A0kGtucwrbf+5we2YM8rUKoocg4itI18xsE4aB69SZo/oqkY7pqxiE3sNjv/mGaqb3+iiS4REj6sWoeRWZ0MGKdRjln2VKvAhtZOn03GLk1KSIyBMnzFiPOwyftscFdPWgTiRQVsj+OauqQBwIDAQAB\;"

Once your DNS records have propagated, use opendkim-testkey to verify the setup:

# opendkim-testkey -d linuxwall.info -s samchiel -k /etc/dkim/samchiel.private -vvv
opendkim-testkey: key loaded from /etc/dkim/samchiel.private
opendkim-testkey: checking key 'samchiel._domainkey.linuxwall.info'
opendkim-testkey: key not secure
opendkim-testkey: key OK

The returned message “key not secure” signifies that the key has been verified correctly, but the DNS transport did not use DNSSEC.

- Integrate with Postfix

Enable a listening socket in /etc/default/opendkim:

SOCKET="inet:5001@localhost" # listen on loopback on port 12345

And restart the daemon. It will now be listening on localhost:5001.

# netstat -taupen|grep LISTEN|grep 5001

tcp        0      0 127.0.0.1:5001          0.0.0.0:*               LISTEN      108        67516       26652/opendkim

Then tell postfix to use this socket in /etc/postfix/main.cf

# sign using opendkim
smtpd_milters = inet:localhost:5001
non_smtpd_milters = inet:localhost:5001

<note> As noted in the documentation of opendkim:

    (c) If you have a content filter in master.cf that feeds it back into a
        different smtpd process, you should alter the second smtpd process in
	master.cf to contain '-o receive_override_options=no_milters' to
	prevent messages being signed or verified twice.  For tips on avoiding
	DKIM signature breakage, see:
	http://www.postfix.org/MILTER_README.html#workarounds

</note>

Finally, try sending an email through Postfix. The recipient will receive it with the following headers:

Return-Path: <julien@linuxwall.info>
Delivered-To: xxx@xxxx.com
[.....]
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=linuxwall.info;
        s=samchiel; t=1342323330;
        bh=4mHBVj76U6YgzAm5ZVkHTVb7MpRdguQPtIH1WLoOPoA=;
        h=subject:Date:From:From;
        b=LRList01AdB2UuiHLw7xa/NQHaF28UdH/ufzu4EvPI4rmuUjx1/J2cENxlegy67Vi
        M9Aox0Q8OshTTDQForrGOzi7OFmvy3vsQh92JFVvVvq/VJ0kCD5aRn2qVCRnRRx/pa
        2RRCrEsaNMlYaiIl1Vsa7evw1gl9Wuz3K2arXg5w=
subject: test dkim signature
Message-Id: <20120715033517.6C78F17C0060@samchiel.linuxwall.info>
Date: Sat, 14 Jul 2012 23:35:12 -0400 (EDT)
From: julien@linuxwall.info

test caribou 12345.

- Postscreen

In /etc/postfix/main.cf

# Postcreen configuration
postscreen_dnsbl_sites =
    zen.spamhaus.org*3
    dnsbl.njabl.org*2
    bl.spameatingmonkey.net*2
    dnsbl.ahbl.org
    bl.spamcop.net
    dnsbl.sorbs.net
postscreen_dnsbl_threshold = 3
postscreen_dnsbl_action = enforce
postscreen_greet_banner = Welcome. Please wait to be seated
postscreen_greet_action = enforce
postscreen_pipelining_enable = yes
postscreen_pipelining_action = enforce
postscreen_non_smtp_command_enable = yes
postscreen_non_smtp_command_action = enforce
postscreen_bare_newline_enable = yes
postscreen_bare_newline_action = enforce

And update /etc/postfix/master.cf to direct the smtp service to postscreen:

# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (yes)   (never) (100)
# ==========================================================================
#smtp      inet  n       -       -       -       -       smtpd
smtp      inet  n       -       -       -       1       postscreen
smtpd     pass  -       -       -       -       -       smtpd
dnsblog   unix  -       -       -       -       0       dnsblog
tlsproxy  unix  -       -       -       -       0       tlsproxy

Restart postfix, and test a connection on port 25:

$ nc 192.168.1.220 25
220-Welcome. Please wait to be seated
220 samchiel.linuxwall.info ESMTP Postfix (Debian/GNU)
^C

And active postscreen TLS support in main.cf

postscreen_tls_security_level = may

- Submission

When sending email, do not use port tcp/25. Use tcp/587 so that DSPAM will not inspect outgoing emails. Do to so, enable the submission service in /etc/postfix/master.cf:

submission inet n       -       -       -       -       smtpd
  -o syslog_name=postfix/submission
  -o smtpd_sasl_auth_enable=yes
  -o smtpd_client_restrictions=permit_sasl_authenticated,reject
  -o milter_macro_daemon_name=ORIGINATING

- Recipient control via LDAP

Postfix must be able to query the LDAP directory to verify that incoming email are valid recipient in the directory. Create this file in /etc/postfix/ldap_recipient_map.cf:

server_host = localhost
server_port = 389
search_base = ou=people,dc=linuxwall,dc=info
query_filter = (mail=%s)
result_attribute = mail

And add this directive to main.cf:

local_recipient_maps = ldap:/etc/postfix/ldap_recipient_map.cf, $alias_maps

Reload postfix. You can test this check using the postmap command:

# postmap -q julien@linuxwall.info ldap://etc/postfix/ldap_recipient_map.cf 
julien@linuxwall.info

If the command returns nothing, then the check has failed.

- DSPAM

Install Postgresql first.

# apt-get install postgresql

Then, install dspam and libdspam7-drv-pgsql:

# apt-get install dspam libdspam7-drv-pgsql

dpkg will attempt to create the dspam database. If this fails (as it did for me), you can create it manually. Connect to postgres, change the password of the “dspam” role (or create it, if it's missing), and load the SQL for the database creation.

# su postgres
postgres@samchiel:/etc/dspam/dspam.d$ psql
psql (9.1.4)
Type "help" for help.

postgres=# alter role dspam password 'oqwidh1o2ehfg93rtogh09yh5j06534vskdbf';
ALTER ROLE

postgres=# \c dspam
You are now connected to database "dspam" as user "postgres".

dspam=# \i /usr/share/dbconfig-common/data/libdspam7-drv-pgsql/install/pgsql

dspam=# \d

                   List of relations
 Schema |          Name          |   Type   |  Owner   
--------+------------------------+----------+----------
 public | dspam_preferences      | table    | postgres
 public | dspam_signature_data   | table    | postgres
 public | dspam_stats            | table    | postgres
 public | dspam_token_data       | table    | postgres
 public | dspam_virtual_uids     | table    | postgres
 public | dspam_virtual_uids_seq | sequence | postgres
(6 rows)

dspam=# alter table dspam_preferences owner to dspam;
ALTER TABLE
dspam=# alter table dspam_signature_data owner to dspam;
ALTER TABLE
dspam=# alter table dspam_stats owner to dspam;
ALTER TABLE
dspam=# alter table dspam_token_data owner to dspam;
ALTER TABLE
dspam=# alter table dspam_virtual_uids owner to dspam;
ALTER TABLE
dspam=# alter sequence dspam_virtual_uids_seq owner to dspam;
ALTER SEQUENCE

Configure /etc/dspam/dspam.d/pgsql.conf as follow:

PgSQLServer	127.0.0.1
PgSQLPort	5432
PgSQLUser	dspam
PgSQLPass	oqwidh1o2ehfg93rtogh
PgSQLDb		dspam
PgSQLConnectionCache	3

<note>I've had issues with PgSQLPass that were too long, so don't go beyond 32 characters.</note> And enable the daemon in /etc/default/dspam:

# Variables for dspam.
#
# Do not start dspam.
START=yes

- dspam.conf

See http://wiki.linuxwall.info/doku.php/en:ressources:dossiers:dspam

Home /var/spool/dspam
StorageDriver /usr/lib/x86_64-linux-gnu/dspam/libpgsql_drv.so
TrustedDeliveryAgent "/usr/bin/procmail"
DeliveryHost		127.0.0.1
DeliveryPort		5003
DeliveryIdent		localhost
DeliveryProto		SMTP
EnablePlusedDetail	on
PlusedCharacter	+
PlusedUserLowercase	on
OnFail error
Trust root
Trust dspam
Trust www-data
Trust mail
Trust daemon
TrainingMode tum
TestConditionalTraining on
Feature whitelist
Algorithm graham burton
Tokenizer osb
PValue bcr
WebStats on
ImprobabilityDrive on
Preference "trainingMode=TUM"		# { TOE | TUM | TEFT | NOTRAIN } -> default:teft
Preference "spamAction=deliver"		# { quarantine | tag | deliver } -> default:quarantine
Preference "spamSubject=[SPAM]"		# { string } -> default:[SPAM]
Preference "statisticalSedation=5"	# { 0 - 10 } -> default:0
Preference "enableBNR=on"		# { on | off } -> default:off
Preference "enableWhitelist=on"		# { on | off } -> default:on
Preference "signatureLocation=headers"	# { message | headers } -> default:message
Preference "tagSpam=off"		# { on | off }
Preference "tagNonspam=off"		# { on | off }
Preference "showFactors=on"		# { on | off } -> default:off
Preference "optIn=off"			# { on | off }
Preference "optOut=off"			# { on | off }
Preference "whitelistThreshold=10"	# { Integer } -> default:10
Preference "makeCorpus=off"		# { on | off } -> default:off
Preference "storeFragments=off"		# { on | off } -> default:off
Preference "localStore="		# { on | off } -> default:username
Preference "processorBias=on"		# { on | off } -> default:on
Preference "fallbackDomain=off"		# { on | off } -> default:off
Preference "trainPristine=off"		# { on | off } -> default:off
Preference "optOutClamAV=off"		# { on | off } -> default:off
Preference "ignoreRBLLookups=off"	# { on | off } -> default:off
Preference "RBLInoculate=off"		# { on | off } -> default:off
Preference "notifications=off"		# { on | off } -> default:off
AllowOverride enableBNR
AllowOverride enableWhitelist
AllowOverride fallbackDomain
AllowOverride ignoreGroups
AllowOverride ignoreRBLLookups
AllowOverride localStore
AllowOverride makeCorpus
AllowOverride optIn
AllowOverride optOut
AllowOverride optOutClamAV
AllowOverride processorBias
AllowOverride RBLInoculate
AllowOverride showFactors
AllowOverride signatureLocation
AllowOverride spamAction
AllowOverride spamSubject
AllowOverride statisticalSedation
AllowOverride storeFragments
AllowOverride tagNonspam
AllowOverride tagSpam
AllowOverride trainPristine
AllowOverride trainingMode
AllowOverride whitelistThreshold
AllowOverride dailyQuarantineSummary
AllowOverride notifications
IgnoreHeader Accept-Language
IgnoreHeader Approved
IgnoreHeader Archive
IgnoreHeader Authentication-Results
IgnoreHeader Cache-Post-Path
IgnoreHeader Cancel-Key
IgnoreHeader Cancel-Lock
IgnoreHeader Complaints-To
IgnoreHeader Content-Description
IgnoreHeader Content-Disposition
IgnoreHeader Content-ID
IgnoreHeader Content-Language
IgnoreHeader Content-Return
IgnoreHeader Content-Transfer-Encoding
IgnoreHeader Content-Type
IgnoreHeader DKIM-Signature
IgnoreHeader Date
IgnoreHeader Disposition-Notification-To
IgnoreHeader DomainKey-Signature
IgnoreHeader Importance
IgnoreHeader In-Reply-To
IgnoreHeader Injection-Info
IgnoreHeader Lines
IgnoreHeader List-Archive
IgnoreHeader List-Help
IgnoreHeader List-Id
IgnoreHeader List-Post
IgnoreHeader List-Subscribe
IgnoreHeader List-Unsubscribe
IgnoreHeader Message-ID
IgnoreHeader Message-Id
IgnoreHeader NNTP-Posting-Date
IgnoreHeader NNTP-Posting-Host
IgnoreHeader Newsgroups
IgnoreHeader OpenPGP
IgnoreHeader Organization
IgnoreHeader Originator
IgnoreHeader PGP-ID
IgnoreHeader Path
IgnoreHeader Received
IgnoreHeader Received-SPF
IgnoreHeader References
IgnoreHeader Reply-To
IgnoreHeader Resent-Date
IgnoreHeader Resent-From
IgnoreHeader Resent-Message-ID
IgnoreHeader Thread-Index
IgnoreHeader Thread-Topic
IgnoreHeader User-Agent
IgnoreHeader X--MailScanner-SpamCheck
IgnoreHeader X-AV-Scanned
IgnoreHeader X-AVAS-Spam-Level
IgnoreHeader X-AVAS-Spam-Score
IgnoreHeader X-AVAS-Spam-Status
IgnoreHeader X-AVAS-Spam-Symbols
IgnoreHeader X-AVAS-Virus-Status
IgnoreHeader X-AVK-Virus-Check
IgnoreHeader X-Abuse
IgnoreHeader X-Abuse-Contact
IgnoreHeader X-Abuse-Info
IgnoreHeader X-Abuse-Management
IgnoreHeader X-Abuse-To
IgnoreHeader X-Abuse-and-DMCA-Info
IgnoreHeader X-Accept-Language
IgnoreHeader X-Admission-MailScanner-SpamCheck
IgnoreHeader X-Admission-MailScanner-SpamScore
IgnoreHeader X-Amavis-Alert
IgnoreHeader X-Amavis-Hold
IgnoreHeader X-Amavis-Modified
IgnoreHeader X-Amavis-OS-Fingerprint
IgnoreHeader X-Amavis-PenPals
IgnoreHeader X-Amavis-PolicyBank
IgnoreHeader X-AntiVirus
IgnoreHeader X-Antispam
IgnoreHeader X-Antivirus
IgnoreHeader X-Antivirus-Scanner
IgnoreHeader X-Antivirus-Status
IgnoreHeader X-Archive
IgnoreHeader X-Assp-Spam-Prob
IgnoreHeader X-Attention
IgnoreHeader X-BTI-AntiSpam
IgnoreHeader X-Barracuda
IgnoreHeader X-Barracuda-Bayes
IgnoreHeader X-Barracuda-Spam-Flag
IgnoreHeader X-Barracuda-Spam-Report
IgnoreHeader X-Barracuda-Spam-Score
IgnoreHeader X-Barracuda-Spam-Status
IgnoreHeader X-Barracuda-Virus-Scanned
IgnoreHeader X-BeenThere
IgnoreHeader X-Bogosity
IgnoreHeader X-Brightmail-Tracker
IgnoreHeader X-CRM114-CacheID
IgnoreHeader X-CRM114-Status
IgnoreHeader X-CRM114-Version
IgnoreHeader X-CTASD-IP
IgnoreHeader X-CTASD-RefID
IgnoreHeader X-CTASD-Sender
IgnoreHeader X-Cache
IgnoreHeader X-ClamAntiVirus-Scanner
IgnoreHeader X-Comment-To
IgnoreHeader X-Comments
IgnoreHeader X-Complaints
IgnoreHeader X-Complaints-Info
IgnoreHeader X-Complaints-To
IgnoreHeader X-DKIM
IgnoreHeader X-DMCA-Complaints-To
IgnoreHeader X-DMCA-Notifications
IgnoreHeader X-Despammed-Tracer
IgnoreHeader X-ELTE-SpamCheck
IgnoreHeader X-ELTE-SpamCheck-Details
IgnoreHeader X-ELTE-SpamScore
IgnoreHeader X-ELTE-SpamVersion
IgnoreHeader X-ELTE-VirusStatus
IgnoreHeader X-Enigmail-Supports
IgnoreHeader X-Enigmail-Version
IgnoreHeader X-Evolution-Source
IgnoreHeader X-Extra-Info
IgnoreHeader X-FSFE-MailScanner
IgnoreHeader X-FSFE-MailScanner-From
IgnoreHeader X-Face
IgnoreHeader X-Fellowship-MailScanner
IgnoreHeader X-Fellowship-MailScanner-From
IgnoreHeader X-Forwarded
IgnoreHeader X-GMX-Antispam
IgnoreHeader X-GMX-Antivirus
IgnoreHeader X-GPG-Fingerprint
IgnoreHeader X-GPG-Key-ID
IgnoreHeader X-GPS-DegDec
IgnoreHeader X-GPS-MGRS
IgnoreHeader X-GWSPAM
IgnoreHeader X-Gateway
IgnoreHeader X-Greylist
IgnoreHeader X-HTMLM
IgnoreHeader X-HTMLM-Info
IgnoreHeader X-HTMLM-Score
IgnoreHeader X-HTTP-Posting-Host
IgnoreHeader X-HTTP-UserAgent
IgnoreHeader X-HTTP-Via
IgnoreHeader X-Headers-End
IgnoreHeader X-ID
IgnoreHeader X-IMAIL-SPAM-STATISTICS
IgnoreHeader X-IMAIL-SPAM-URL-DBL
IgnoreHeader X-IMAIL-SPAM-VALFROM
IgnoreHeader X-IMAIL-SPAM-VALHELO
IgnoreHeader X-IMAIL-SPAM-VALREVDNS
IgnoreHeader X-Info
IgnoreHeader X-IronPort-Anti-Spam-Filtered
IgnoreHeader X-IronPort-Anti-Spam-Result
IgnoreHeader X-KSV-Antispam
IgnoreHeader X-Kaspersky-Antivirus
IgnoreHeader X-MDAV-Processed
IgnoreHeader X-MDRemoteIP
IgnoreHeader X-MDaemon-Deliver-To
IgnoreHeader X-MIE-MailScanner-SpamCheck
IgnoreHeader X-MIMEOLE
IgnoreHeader X-MIMETrack
IgnoreHeader X-MMS-Spam-Filter-ID
IgnoreHeader X-MS-Exchange-Forest-RulesExecuted
IgnoreHeader X-MS-Exchange-Organization-Antispam-Report
IgnoreHeader X-MS-Exchange-Organization-AuthAs
IgnoreHeader X-MS-Exchange-Organization-AuthDomain
IgnoreHeader X-MS-Exchange-Organization-AuthMechanism
IgnoreHeader X-MS-Exchange-Organization-AuthSource
IgnoreHeader X-MS-Exchange-Organization-Journal-Report
IgnoreHeader X-MS-Exchange-Organization-Original-Scl
IgnoreHeader X-MS-Exchange-Organization-Original-Sender
IgnoreHeader X-MS-Exchange-Organization-OriginalArrivalTime
IgnoreHeader X-MS-Exchange-Organization-OriginalSize
IgnoreHeader X-MS-Exchange-Organization-PCL
IgnoreHeader X-MS-Exchange-Organization-Quarantine
IgnoreHeader X-MS-Exchange-Organization-SCL
IgnoreHeader X-MS-Exchange-Organization-SenderIdResult
IgnoreHeader X-MS-Has-Attach
IgnoreHeader X-MS-TNEF-Correlator
IgnoreHeader X-MSMail-Priority
IgnoreHeader X-MailScanner
IgnoreHeader X-MailScanner-Information
IgnoreHeader X-MailScanner-SpamCheck
IgnoreHeader X-Mailer
IgnoreHeader X-Mailman-Version
IgnoreHeader X-Mlf-Spam-Status
IgnoreHeader X-NAI-Spam-Checker-Version
IgnoreHeader X-NAI-Spam-Flag
IgnoreHeader X-NAI-Spam-Level
IgnoreHeader X-NAI-Spam-Report
IgnoreHeader X-NAI-Spam-Route
IgnoreHeader X-NAI-Spam-Rules
IgnoreHeader X-NAI-Spam-Score
IgnoreHeader X-NAI-Spam-Threshold
IgnoreHeader X-NEWT-spamscore
IgnoreHeader X-NNTP-Posting-Date
IgnoreHeader X-NNTP-Posting-Host
IgnoreHeader X-NetcoreISpam1-ECMScanner
IgnoreHeader X-NetcoreISpam1-ECMScanner-From
IgnoreHeader X-NetcoreISpam1-ECMScanner-Information
IgnoreHeader X-NetcoreISpam1-ECMScanner-SpamCheck
IgnoreHeader X-NetcoreISpam1-ECMScanner-SpamScore
IgnoreHeader X-Newsreader
IgnoreHeader X-Newsserver
IgnoreHeader X-No-Archive
IgnoreHeader X-No-Spam
IgnoreHeader X-OSBF-Lua-Score
IgnoreHeader X-OWM-SpamCheck
IgnoreHeader X-OWM-VirusCheck
IgnoreHeader X-Olypen-Virus
IgnoreHeader X-Orig-Path
IgnoreHeader X-OriginalArrivalTime
IgnoreHeader X-Originating-IP
IgnoreHeader X-PAA-AntiVirus
IgnoreHeader X-PAA-AntiVirus-Message
IgnoreHeader X-PGP-Fingerprint
IgnoreHeader X-PGP-Hash
IgnoreHeader X-PGP-ID
IgnoreHeader X-PGP-Key
IgnoreHeader X-PGP-Key-Fingerprint
IgnoreHeader X-PGP-KeyID
IgnoreHeader X-PGP-Sig
IgnoreHeader X-PIRONET-NDH-MailScanner-SpamCheck
IgnoreHeader X-PIRONET-NDH-MailScanner-SpamScore
IgnoreHeader X-PMX
IgnoreHeader X-PMX-Version
IgnoreHeader X-PN-SPAMFiltered
IgnoreHeader X-Posting-Agent
IgnoreHeader X-Posting-ID
IgnoreHeader X-Posting-IP
IgnoreHeader X-Priority
IgnoreHeader X-Proofpoint-Spam-Details
IgnoreHeader X-Qmail-Scanner-1.25st
IgnoreHeader X-Quarantine-ID
IgnoreHeader X-RAV-AntiVirus
IgnoreHeader X-RITmySpam
IgnoreHeader X-RITmySpam-IP
IgnoreHeader X-RITmySpam-Spam
IgnoreHeader X-Rc-Spam
IgnoreHeader X-Rc-Virus
IgnoreHeader X-Received-Date
IgnoreHeader X-RedHat-Spam-Score
IgnoreHeader X-RedHat-Spam-Warning
IgnoreHeader X-RegEx
IgnoreHeader X-RegEx-Score
IgnoreHeader X-Rocket-Spam
IgnoreHeader X-SA-GROUP
IgnoreHeader X-SA-RECEIPTSTATUS
IgnoreHeader X-STA-NotSpam
IgnoreHeader X-STA-Spam
IgnoreHeader X-Scam-grey
IgnoreHeader X-Scanned-By
IgnoreHeader X-Sender
IgnoreHeader X-SenderID
IgnoreHeader X-Sohu-Antivirus
IgnoreHeader X-Spam
IgnoreHeader X-Spam-ASN
IgnoreHeader X-Spam-Check
IgnoreHeader X-Spam-Checked-By
IgnoreHeader X-Spam-Checker
IgnoreHeader X-Spam-Checker-Version
IgnoreHeader X-Spam-Clean
IgnoreHeader X-Spam-DCC
IgnoreHeader X-Spam-Details
IgnoreHeader X-Spam-Filter
IgnoreHeader X-Spam-Filtered
IgnoreHeader X-Spam-Flag
IgnoreHeader X-Spam-Level
IgnoreHeader X-Spam-OrigSender
IgnoreHeader X-Spam-Pct
IgnoreHeader X-Spam-Prev-Subject
IgnoreHeader X-Spam-Processed
IgnoreHeader X-Spam-Pyzor
IgnoreHeader X-Spam-Rating
IgnoreHeader X-Spam-Report
IgnoreHeader X-Spam-Scanned
IgnoreHeader X-Spam-Score
IgnoreHeader X-Spam-Status
IgnoreHeader X-Spam-Tagged
IgnoreHeader X-Spam-Tests
IgnoreHeader X-Spam-Tests-Failed
IgnoreHeader X-Spam-Virus
IgnoreHeader X-Spam-Warning
IgnoreHeader X-Spam-detection-level
IgnoreHeader X-SpamAssassin-Clean
IgnoreHeader X-SpamAssassin-Warning
IgnoreHeader X-SpamBouncer
IgnoreHeader X-SpamCatcher-Score
IgnoreHeader X-SpamCop-Checked
IgnoreHeader X-SpamCop-Disposition
IgnoreHeader X-SpamCop-Whitelisted
IgnoreHeader X-SpamDetected
IgnoreHeader X-SpamInfo
IgnoreHeader X-SpamPal
IgnoreHeader X-SpamPal-Timeout
IgnoreHeader X-SpamReason
IgnoreHeader X-SpamScore
IgnoreHeader X-SpamTest-Categories
IgnoreHeader X-SpamTest-Info
IgnoreHeader X-SpamTest-Method
IgnoreHeader X-SpamTest-Status
IgnoreHeader X-SpamTest-Version
IgnoreHeader X-Spamadvice
IgnoreHeader X-Spamarrest-noauth
IgnoreHeader X-Spamarrest-speedcode
IgnoreHeader X-Spambayes-Classification
IgnoreHeader X-Spamcount
IgnoreHeader X-Spamsensitivity
IgnoreHeader X-TERRACE-SPAMMARK
IgnoreHeader X-TERRACE-SPAMRATE
IgnoreHeader X-TM-AS-Category-Info
IgnoreHeader X-TM-AS-MatchedID
IgnoreHeader X-TM-AS-Product-Ver
IgnoreHeader X-TM-AS-Result
IgnoreHeader X-TMWD-Spam-Summary
IgnoreHeader X-TNEFEvaluated
IgnoreHeader X-Text-Classification
IgnoreHeader X-Text-Classification-Data
IgnoreHeader X-Trace
IgnoreHeader X-UCD-Spam-Score
IgnoreHeader X-User-Agent
IgnoreHeader X-User-ID
IgnoreHeader X-User-System
IgnoreHeader X-Virus-Check
IgnoreHeader X-Virus-Checked
IgnoreHeader X-Virus-Checker-Version
IgnoreHeader X-Virus-Scan
IgnoreHeader X-Virus-Scanned
IgnoreHeader X-Virus-Scanner
IgnoreHeader X-Virus-Scanner-Result
IgnoreHeader X-Virus-Status
IgnoreHeader X-VirusChecked
IgnoreHeader X-Virusscan
IgnoreHeader X-WSS-ID
IgnoreHeader X-WinProxy-AntiVirus
IgnoreHeader X-WinProxy-AntiVirus-Message
IgnoreHeader X-Yandex-Forward
IgnoreHeader X-Yandex-Front
IgnoreHeader X-Yandex-Spam
IgnoreHeader X-Yandex-TimeMark
IgnoreHeader X-cid
IgnoreHeader X-iHateSpam-Checked
IgnoreHeader X-iHateSpam-Quarantined
IgnoreHeader X-policyd-weight
IgnoreHeader X-purgate
IgnoreHeader X-purgate-Ad
IgnoreHeader X-purgate-ID
IgnoreHeader X-sgxh1
IgnoreHeader X-to-viruscore
IgnoreHeader Xref
IgnoreHeader acceptlanguage
IgnoreHeader thread-index
IgnoreHeader x-uscspam
Notifications	off
PurgeSignature	off	# Specified in purge.sql
PurgeNeutral	90
PurgeUnused	off	# Specified in purge.sql
PurgeHapaxes	off	# Specified in purge.sql
PurgeHits1S	off	# Specified in purge.sql
PurgeHits1I	off	# Specified in purge.sql
LocalMX 127.0.0.1
SystemLog	on
UserLog		on
Opt out
ParseToHeaders on
ChangeModeOnParse on
ChangeUserOnParse full
ServerHost		127.0.0.1
ServerPort		5002
ServerQueueSize	32
ServerPID		/var/run/dspam/dspam.pid
ServerMode auto
ServerParameters	"--deliver=innocent,spam -d %u"
ServerIdent		"localhost.localdomain"
ProcessorURLContext on
ProcessorBias on
StripRcptDomain off
Include /etc/dspam/dspam.d/

- Dspam routes to Postfix

Dspam will receive email to inspect on port tcp/5002, and return them to postfix on port tcp/5003. Therefore, postfix needs to have a listening port on tcp/5003.

Add this to the end of /etc/postfix/master.cf

#Dspam return route
127.0.0.1:5003 inet n  -       n       -        -      smtpd
      -o content_filter=
      -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks,no_milters
      -o smtpd_helo_restrictions=
      -o smtpd_client_restrictions=
      -o smtpd_sender_restrictions=
      -o smtpd_recipient_restrictions=permit_mynetworks,reject
      -o mynetworks=127.0.0.0/8
      -o smtpd_authorized_xforward_hosts=127.0.0.0/8

And update the smtp line of postfix to submit incoming emails to dspam, still in master.cf.

smtpd     pass  -       -       -       -       -       smtpd
        -o content_filter=lmtp:127.0.0.1:5002

- Dspam Maintenance

Add this to /etc/crontab

30 4    * * *   dspam   /usr/bin/dspam_logrotate -a 60 -d /var/spool/dspam/data/
30 4    * * *   dspam   /usr/bin/dspam_maintenance

- Additional configuration

- Enable support for plussed addresses

Addresses of the form user+something@domain.com, where “something” is a random string that is not part of the username. To enable support for plussed addresses, go to /etc/dovecot/conf.d/15-lda.conf and set recipient_delimiter as follow:

recipient_delimiter = +

Same in /etc/postfix/main.cf:

recipient_delimiter = +

And in /etc/dspam/dspam.conf:

PlusedCharacter	+

- Sieve

# apt-get install dovecot-managesieved dovecot-sieve

Edit the managesieve configuration in /etc/dovecot/conf.d/20-managesieve.conf:

service managesieve-login {
  inet_listener sieve {
    port = 4190
  }
  service_count = 1
  process_min_avail = 1
  vsz_limit = 64M
}
service managesieve {
}
protocol sieve {
  mail_max_userip_connections = 3
}

And configure the sieve service itself in /etc/dovecot/conf.d/90-sieve.conf.

plugin {
  sieve = ~/.dovecot.sieve
  sieve_dir = ~/sieve
   
  recipient_delimiter = +
  sieve_max_script_size = 10M
  sieve_max_actions = 1024
  sieve_max_redirects = 64
}

Reload dovecot, and tcp/4190 will be listening for sieve connectionss.

# netstat -taupen|grep LISTEN|grep 4190
tcp        0      0 0.0.0.0:4190            0.0.0.0:*               LISTEN      0          11253       3228/dovecot    
tcp6       0      0 :::4190                 :::*                    LISTEN      0          11254       3228/dovecot

Test the connection using sieve-connect as follow: To test the authentication, generate credentials using this perl script:

#!/usr/bin/perl
# Stephan Bosch, stephan@rename-it.nl
use MIME::Base64;
use strict;
my $username = shift;
my $password = shift;
my $userpass = "\x00".$username."\x00".$password."";
my $encode=encode_base64($userpass);
$encode =~ s/^\s+//;
$encode =~ s/\s+$//;
print "AUTHENTICATE \"PLAIN\" \"$encode\"\r\n";

And use the returned AUTHENTICATE string into a netcat connection to the managesieve port:

# nc localhost 4190

"IMPLEMENTATION" "Dovecot Pigeonhole"
"SIEVE" "fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date ihave"
"NOTIFY" "mailto"
"SASL" "PLAIN LOGIN DIGEST-MD5"
"STARTTLS"
"VERSION" "1.0"
OK "Dovecot ready."

AUTHENTICATE "PLAIN" "AGp1bGllbgB0aGlzaXNub3RteXJlYWxwYXNzd29yZA=="
OK "Logged in."

LISTSCRIPTS
OK "Listscripts completed."

Enable the plugin directory in /etc/dovecot/conf.d/10-mail.conf as follow:

# Directory where to look up mail plugins.
mail_plugin_dir = /usr/lib/dovecot/modules

And finally, enable the sieve plugin for dovecot-lda in /etc/dovecot/conf.d/15-lda.conf:

protocol lda {
  # Space separated list of plugins to load (default is global mail_plugins).
  mail_plugins = sieve
}

And for dovecot-lmtp in /etc/dovecot/conf.d/20-lmtp.conf:

protocol lmtp {
  mail_plugins = sieve
}

Test using sieve-connect:

# sieve-connect -s localhost -p 4190 --notlsverify -u julien --authmech PLAIN 
Sieve/IMAP Password: 
ReadLine support enabled.
> ls
> put /home/julien/dovecotsieve 
> ls
"dovecotsieve"
> activate dovecotsieve 
> ls
"dovecotsieve" ACTIVE
> 

- Roundcube

apt-get install roundcube-plugins roundcube-pgsql roundcube-plugins-extra 

The above will install roundcube and dependencies, configure the postgres database and prepare Apache.

In /etc/roundcube/apache.conf, uncomment the two Aliases lines as follow:

# Those aliases do not work properly with several hosts on your apache server
# Uncomment them to use it or adapt them to your configuration
Alias /roundcube/program/js/tiny_mce/ /usr/share/tinymce/www/
Alias /roundcube /var/lib/roundcube

And restart Apache2. This will make available at http://SERVERIP/roundcube/.

- Ejabberd

apt-get install ejabberd

In ejabberd.cfg, replace the Hostname:

%% Hostname
{hosts, ["linuxwall.info"]}.

Enable SSL:

  %%
  %% To enable the old SSL connection method (deprecated) in port 5223:
  %%
  {5223, ejabberd_c2s, [
                        {access, c2s},
                        {shaper, c2s_shaper},
                        {max_stanza_size, 65536},
                      zlib,
                        tls, {certfile, "/etc/ejabberd/ejabberd.pem"}
                       ]},

Comment out the default auth method to enable the LDAP authentication:

%%
%% {auth_method, internal}.

...

%%
%% Authentication using LDAP
%%
{auth_method, ldap}.
%%
%% List of LDAP servers:
{ldap_servers, ["localhost"]}.
%%
%% Encryption of connection to LDAP servers (LDAPS):
%%{ldap_encrypt, none}.
%%{ldap_encrypt, tls}.
%%
%% Port connect to LDAP server:
{ldap_port, 389}.
%%{ldap_port, 636}.
%%
%% LDAP manager:
%%{ldap_rootdn, "dc=example,dc=com"}.
%%
%% Password to LDAP manager:
%%{ldap_password, "******"}.
%%
%% Search base of LDAP directory:
{ldap_base, "ou=people,dc=linuxwall,dc=info"}.
%%
%% LDAP attribute that holds user ID:
{ldap_uids, [{"mail", "%u@linuxwall.info"}]}.
%%
%% LDAP filter:
{ldap_filter, "(objectClass=inetOrgPerson)"}.