====== 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)"}.