====== Necto Installation Instructions ======
{{:en:ressources:dossiers:dsc_7286.jpg?500|}}
===== - 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
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
Finally, try sending an email through Postfix. The recipient will receive it with the following headers:
Return-Path:
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
I've had issues with PgSQLPass that were too long, so don't go beyond 32 characters.
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)"}.