# Postfix(admin)/Dovecot/Mysql/Squirrelmail guide

## audiodef

Feedback on this guide is welcome and appreciated, and will be incorporated if it fits. 

I wrote this guide because my old mail server setup stopped working and I switched to using external services such as Zoho. Zoho & co. work very well, but as someone who has more time than money, I could only create so many free domain/user accounts. So this past Sunday, I resolved to sit down and get my darn mail server back up and running in order to have all the email support I needed for my various community/non-profit projects, not to mention my own personal and business email. I also determined to write down everything I did because I have found no single useable mailserver guide for Gentoo. This is probably not "the single useable guide," either, but my goal is to document this way of doing it as completely as possible, with no ambiguity or skipped steps. 

This guide assumes you have an existing server configured with Apache, Mysql and PHP. If you don't have these, this guide will not work for you. 

The following components will be used in this mailserver:

Postfix Admin (for managing mail domains and users)

Postfix MTA (mail transfer agent)

Dovecot LDA (local delivery agent)

MySQL

Squirrelmail web interface

Clam antivirus integrated with Amavis

Spamassassin integrated with Amavis

Throughout this guide, remember to replace example.org, server.example.org and user@example.org with your actual server details. 

I don't go into great detail explaining individual lines - otherwise this guide would be several times as long - but info about any particular configuration line is easily found.

Use flags

Make sure you have the following use flags enabled in make.conf, in addition to whatever flags you already have:

```

USE="apache2 bindist bzip2 caps clamdtop crypt curl dovecot dovecot-sasl

     filecaps fontconfig gd geoip imap ipv6 jpeg maildir mysql mysqldump

     mysqlhotcopy mysqli pdo png sasl sieve sockets spamassassin spell ssl

     threads truetype urandom vhosts xslt -mbox"

```

If you had to add any of these use flags, run

```

emerge -vuDN world

```

before proceeding.

Postfix Admin

Postfix Admin is in Portage. I love Portage - I think it's a great package manager - but I have no love for installing web apps through a package manager of any kind. If you want to go this route, that's up to you, but you need to look elsewhere for help with that. I do recommend manually installing Postfix Admin and other web apps. It's not difficult, and you get the latest production version from the developer instead of whatever old version is hanging around in Portage, as often happens with web apps.

I have my webserver set up with virtual hosts, with /var/www/localhost unassigned. This means that while my web sites have friendly URLs, my server's IP address is directly accessible in a browser - albeit secured from the public - and therefore available to me for running web apps. This guide assumes you have /var/www/localhost/htdocs set up to run web apps, but you can put your web apps wherever you would normally put them in your own web server config. 

Download Postfix Admin from https://sourceforge.net/projects/postfixadmin/

If you access your server through ssh, scp the tarball to your server. 

mv /scp/upload/location/postfixadmin-(version).tar.gz /var/www/localhost/htdocs

cd /var/www/localhost/htdocs

tar xvzf postfixadmin-(version).tar.gz

(Optional, but I find this makes for an easier URL) mv postfixadmin-(version) postfixadmin

(Optional, no reason to have it hanging around, though) rm postfixadmin-(version).tar.gz

chown -R apache:apache postfixadmin/

That's the install. ls -lah should give you this:

```

drwxrwxr-x 17 apache apache 4.0K Sep 11 19:40 postfixadmin

```

Make sure you minimally secure the postfixadmin dir with an .htaccess file over SSL. 

Now for the Postfix Admin setup. 

Go to http://example.org/postfixadmin (or wherever you've configured Postfix Admin to be.) You should see the Postfix Admin welcome page. 

You need to go back to your terminal and create the MySQL database for Postfix Admin:

```

mysql -u root -p

create database postfix;

use postfix;

```

We need two users for this database - one for Postfix Admin to manage domains and users, and one for Postfix and Dovecot to validate logins. The latter does not need to be able to write to the database or otherwise change anything. 

Create Postfix Admin user:

```

CREATE USER 'postfix' IDENTIFIED BY 'somepassword';

```

Grant appropriate privileges to this user:

```

GRANT SELECT, INSERT, DELETE, UPDATE, CREATE, ALTER, INDEX, DROP, CREATE TEMPORARY TABLES, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, EXECUTE, CREATE VIEW, EVENT, TRIGGER ON postfix.* TO 'postfix'@'localhost';

```

Create the user for Postfix and Dovecot:

```

CREATE USER 'mailuser' IDENTIFIED BY 'mailuserpassword';

```

Grant it appropriate permissions:

```

GRANT SELECT ON postfix.* TO 'mailuser'@'localhost';

```

With that done, the Postfix Admin configuration file needs to be edited manually. Change the following items in /var/www/localhost/htdocs/postfixadmin/config.inc.php:

Change

```

$CONF['configured'] = false; 

```

to: 

```

$CONF['configured'] = true;

```

Change

```

$CONF['database_user'] = 'postfix'; 

```

to: whatever Postfix Admin database user you created if it's not "postfix."

Change

```

$CONF['database_password'] = 'postfixadmin'; 

```

to: the password you created for database user "postfix."

Change

```

$CONF['database_name'] = 'postfix'; 

```

to: the name of the database you created if it's not "postfix."

Change

```

$CONF['admin_email'] = ''; 

```

to: a working email address you want to use for administrative contact purposes.

Change

```

$CONF['encrypt'] = 'md5crypt'; 

```

to:

```

$CONF['encrypt'] = 'dovecot:PLAIN-MD5';

```

Change

```

$CONF['dovecotpw'] = "/usr/sbin/doveadm pw"; 

```

to:

```

$CONF['dovecotpw'] = "/usr/bin/doveadm pw";

```

Save and quit. Return to the Postfix Admin welcome page in your browser and go to http://example.org/postfixadmin/setup.php. If everything above was configured correctly, the page should take a minute or so to load while it creates database tables. If it is not able to proceed, it will tell you why and you should fix those items listed. When it's done creating database tables, at the bottom of the page should be a form to change the setup password. Enter a password and click on "Generate password hash." Open config.inc.php again and paste the hash into:

```

$CONF['setup_password'] = 'changeme';

```

Now create your Postfix Admin superadmin account. 

If all went well, you should now be looking at a link to login to Postfix Admin. 

Do not delete any files from the postfixadmin dir. Some web apps want you to delete initial setup or config files/dirs. Postfix Admin requires no such thing and is not designed to have anything deleted from its file dir. 

Use Postfix Admin to set up your first mail domain and at least one mailbox for that domain. Leave "send welcome mail" unchecked when creating a mailbox - the mail server isn't set up yet. Create a catch-all alias, if you want. I generally don't. If spammers try to hit a bunch of random - and non-existent - mail users at my domain, I don't want them to get through. 

Installing Postfix and Dovecot

```

emerge postfix

```

If you didn't skip the section above about use flags, this will pull in Dovecot automatically. 

If you're like me and have started over several times to set up a mail server using this or that guide, you might get this:

```

* IMPORTANT: config file '/etc/sasl2/smtpd.conf' needs updating.

```

Go ahead and run etc-update on that, overwriting the existing smtpd.conf. 

Edit /etc/mail/aliases and add the following:

```

root:              root@example.org

operator:        operator@example.org

```

I also change everything above that to "root" on the right, which ensures that everything goes to "root" as defined above, which in turn is mapped to a real email address. Note that this also means whatever the system mails to root will show up in the inbox of the root-mapped email address. That could be handy or annoying, depending on how much of a server admin you are. 

Generate alias database:

```

newaliases

```

Symlink the aliases to the Postfix dir to make them easier to find:

```

ln -s /etc/mail/aliases /etc/postfix/aliases

ln -s /etc/mail/aliases.db /etc/postfix/aliases.db

```

To integrate Dovecot with Postfix, add the following to the end of /etc/postfix/master.cf:

```

dovecot   unix  -       n       n       -       -       pipe

  flags=DRhu user=mail:mail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}

```

Open /etc/postfix/main.cf and set myhostname to your server's FQDN. It should look like servername.example.org. Uncomment the line for myorigin = $myhostname. Uncomment the line for mydestination = $myhostname, localhost.$mydomain, localhost. 

Add to the bottom of /etc/postfix/main.cf:

```

virtual_transport = dovecot

dovecot_destination_recipient_limit = 1

```

To integrate Dovecot SASL authentication, add the following to /etc/postfix/main.cf:

```

smtpd_sasl_auth_enable = yes

smtpd_sasl_type = dovecot

smtpd_sasl_path = private/auth

```

Create the following files, which Postfix will use to look up user details in the postfix database. (Database maps.)

/etc/postfix/sql_virtual_alias_maps.cf:

```

user = mailuser

password = mailuserpassword

hosts = localhost

dbname = postfix

query = SELECT goto FROM alias WHERE address='%s' AND active = '1'

```

/etc/postfix/sql_virtual_domain_maps.cf:

```

user = mailuser

password = mailuserpassword

hosts = localhost

dbname = postfix

query = SELECT domain FROM domain WHERE domain='%s' AND backupmx = '0' AND active = '1'

```

/etc/postfix/sql_virtual_mailbox_maps.cf:

```

user = mailuser

password = mailuserpassword

hosts = localhost

dbname = postfix

query = SELECT CONCAT(maildir, 'Maildir/') AS maildir FROM mailbox WHERE username='%s' AND active = '1'

```

These files need to be known by Postfix. Open /etc/postfix/main.cf and add:

```

virtual_alias_maps = mysql:/etc/postfix/sql_virtual_alias_maps.cf

virtual_mailbox_domains = mysql:/etc/postfix/sql_virtual_domain_maps.cf

virtual_mailbox_maps = mysql:/etc/postfix/sql_virtual_mailbox_maps.cf

```

To enforce sender restrictions and to handle rejection, add to /etc/postfix/main.cf:

```

smtpd_sender_restrictions = reject_non_fqdn_sender

smtpd_reject_unlisted_sender = yes

smtpd_recipient_restrictions =

        permit_mynetworks

        reject_non_fqdn_recipient

        permit_sasl_authenticated

        reject_unauth_destination

        reject_rbl_client zen.spamhaus.org

        reject_rbl_client bl.spamcop.net

```

Secure SMTP

To securely access SMTP to send mail, the following steps should be taken.

Either acquire certificates from http://www.cacert.org/ or http://www.startssl.com/, or generate your own self-signed certificates. I personally prefer the later, since I don't need to prove any authenticity to anyone but myself and keep spammers out, but either works just as well. 

Generate a self-signed cert:

```

cd /etc/postfix (You can put your certs anywhere, but I find it simplifies things to keep Postfix-related items in the Postfix dir.)

openssl genrsa -des3 -out server.example.org.key 2048

openssl req -new -key server.example.org.key -out server.example.org.csr

openssl x509 -req -days 365 -in server.example.org.csr -signkey server.example.org.key -out server.example.org.crt

openssl rsa -in server.example.org.key -out server.example.org.key.nopass 

mv server.example.org.key.nopass server.example.org.key

openssl req -new -x509 -extensions v3_ca -keyout cakey.pem -out cacert.pem -days 3650

```

Add the following to /etc/postfix/main.cf: 

```

smtpd_tls_key_file = /etc/postfix/server.example.org.key

smtpd_tls_cert_file = /etc/postfix/server.example.org.crt

smtpd_tls_CAfile = /etc/postfix/cacert.pem

smtpd_tls_loglevel = 0

smtpd_tls_received_header = yes

smtpd_tls_session_cache_timeout = 10800s

smtp_tls_mandatory_ciphers = high

smtp_tls_security_level = may

smtpd_tls_security_level = may

smtpd_tls_auth_only = yes

```

And add to /etc/postfix/master.cf:

```

smtps     inet  n       -       n       -       -       smtpd -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes

submission inet n       -       n       -       -       smtpd -o smtpd_enforce_tls=yes -o smtpd_sasl_auth_enable=yes

```

Note that in the chroot column, everything should be "n."

Dovecot configuration

Edit /etc/dovecot/dovecot.conf:

Change 

```

#protocols = imap pop3 lmtp 

```

to: Uncomment.

Change

```

#listen = *, :: 

```

to: Uncomment.

Edit /etc/dovecot/conf.d/10-auth.conf:

Change

```

#disable_plaintext_auth = yes 

```

to: Uncomment.

Change

```

auth_mechanisms = plain 

```

to: 

```

auth_mechanisms = plain login cram-md5

```

Change

```

!include auth-system.conf.ext 

```

to: Comment out.

Edit /etc/dovecot/conf.d/10-mail.conf:

Change

```

mail_location = maildir:~/.maildir 

```

to:

```

mail_location = maildir:/var/mail/%d/%n/Maildir/:INDEX=/var/mail/%d/%n/indexes

```

Change

```

#mail_uid = 

```

to:

```

mail_uid = 8

```

Change

```

#mail_gid = 

```

to:

```

mail_gid = 12

```

Change

```

#first_valid_uid = 500 

```

to:

```

first_valid_uid = 8

```

Change

```

#last_valid_uid = 0 

```

to:

```

last_valid_uid = 8

```

Change

```

#first_valid_gid = 1 

```

to:

```

first_valid_gid = 12

```

Change

```

#last_valid_gid = 0 

```

to:

```

last_valid_gid = 12

```

Change

```

#mail_plugins = 

```

to:

```

mail_plugins = quota

```

The above mail user and group ids belong to the mail user. If your mail user and group has different ids, you should use those. Double check the uid and gid with:

```

id mail

```

Open /etc/dovecot/conf.d/10-master.conf and find the section "service auth". Uncomment lines in the code below, and add any lines in the code below if they are missing from the default config:

```

service auth {

  unix_listener auth-userdb {

    mode = 0600

    user = mail

    group = mail

  }

  unix_listener /var/spool/postfix/private/auth {

    mode = 0660

    user = postfix

    group = postfix

  }

}

...

service auth-worker {

  user = mail

}

...

service lmtp {

  unix_listener /var/spool/postfix/private/dovecot-lmtp {

    mode = 0660

    user = postfix

    group = postfix

  }

...

}

```

Edit /etc/dovecot/conf.d/15-lda.conf:

Change

```

#postmaster_address = 

```

to:

```

postmaster_address = your-administrative-email@example.org

```

Edit /etc/dovecot/conf.d/20-imap.conf:

Change

```

#mail_plugins = $mail_plugins 

```

to:

```

mail_plugins = $mail_plugins imap_quota

```

Edit /etc/dovecot/dovecot-sql.conf.ext:

Change

```

#driver = 

```

to:

```

driver = mysql

```

Change

```

#connect = 

```

to:

```

connect = host=/var/run/mysqld/mysqld.sock user=mailuser password=mailuserpassword dbname=postfix

```

Change

```

#default_pass_scheme = MD5 

```

to:

```

default_pass_scheme = CRAM-MD5

```

Change

```

#password_query = \

#  SELECT username, domain, password \

#  FROM users WHERE username = '%n' AND domain = '%d'

```

to:

```

password_query = SELECT CONCAT('/var/mail/', maildir) AS userdb_home, \

  username AS user, password, CONCAT('*:bytes=', quota) AS userdb_quota_rule \

  FROM mailbox WHERE username = '%u' AND active = 1

```

Change

```

#user_query = \

#  SELECT home, uid, gid \

#  FROM users WHERE username = '%n' AND domain = '%d'

```

to:

```

user_query = SELECT CONCAT('/var/mail/', maildir) AS home, \

  CONCAT('*:bytes=', quota) AS quota_rule \

  FROM mailbox WHERE username = '%u' AND active = 1

```

Edit /etc/dovecot/conf.d/auth-sql.conf.ext:

Change

```

#userdb {

#  driver = prefetch

#}

```

to:

```

userdb {

  driver = prefetch

}

```

Starting services

```

/etc/init.d/postfix start

rc-update add postfix default

/etc/init.d/dovecot start

rc-update add dovecot default

/etc/init.d/saslauthd start

rc-update add saslauthd default

```

Testing

Now we can test the mail server locally, in a terminal on the server or through ssh. 

```

telnet example.org 25

```

You should see this:

```

Trying 1.2.3.4...

Connected to example.org.

Escape character is '^]'.

220 server.example.org ESMTP Postfix

```

Enter the auth login command:

```

auth login

```

You should see this:

```

334 VXNlcm5hbWU6

```

This is base64 for "Username." You'll need to reply in base64. In another terminal, do

```

perl -MMIME::Base64 -e 'print encode_base64("username\@example.org");'

```

It is necessary to escape @ with \. Enter the output of that into your telnet session - you can copy/paste - and you should see:

```

334 UGFzc3dvcmQ6

```

This is base64 for "Password." Repeat the above perl command, putting the password you created for this mailbox in Postfix Admin inside the quotes, and enter it into your telnet session. If everything was done right, you should see:

```

235 2.7.0 Authentication successful

```

Now test sending mail, using the same telnet session.

Enter

```

mail from:user@example.org

```

You should see:

```

250 2.1.0 Ok

```

Enter:

```

rcpt to:user@example.org

```

You should see:

```

250 2.1.5 Ok

```

Enter:

```

data

```

You should see:

```

354 End data with <CR><LF>.<CR><LF>

```

Type a message - any message:

```

Today is a good day to succeed.

```

Now type a dot on a line by itself:

```

.

```

You should see:

```

250 2.0.0 Ok: queued as D39E6538005D

```

Quit:

```

quit

```

You'll see:

```

221 2.0.0 Bye

Connection closed by foreign host.

```

The whole thing should look like this:

```

Trying 1.2.3.4...

Connected to example.org.

Escape character is '^]'.

220 server.example.org ESMTP Postfix

auth login

334 VXNlcm5hbWU6

dXNlcm5hbWVAZXhhbXBsZS5vcmc=

334 UGFzc3dvcmQ6

eW91cnBhc3N3b3Jk

235 2.7.0 Authentication successful

mail from:user@example.org

250 2.1.0 Ok

rcpt to:user@example.org

250 2.1.5 Ok

data

354 End data with <CR><LF>.<CR><LF>

Today is a good day to succeed.

.

250 2.0.0 Ok: queued as D39E6538005D

quit

221 2.0.0 Bye

Connection closed by foreign host.

```

Go to /var/mail/example.org/user/.maildir/. This is your mail user's home dir. The test message you just sent should be in the "new" dir. You can read it with nano/vi/less/whatever. 

If all that is working, it's time to set up Squirrelmail.

Squirrelmail

Squirrelmail is not flashy, but it is maintained and it works well. It doesn't need its own database, which is one less thing for you to worry about. 

Download Squirrelmail from http://squirrelmail.org/download.php. Download the bz2 file and scp it to your server. Then:

mv /scp/upload/location/squirrelmail-webmail-1.4.22.tar.bz2 /var/www/localhost/htdocs/

tar xvjpf squirrelmail-webmail-1.4.22.tar.bz2

mv squirrelmail-webmail-1.4.22 squirrelmail

chown -R apache:apache squirrelmail

rm squirrelmail-webmail-1.4.22.tar.bz2

cd squirrelmail

./configure

You need to set the data and attachment dirs in 4. General Options. They should look like:

```

1.  Data Directory               : /var/www/localhost/htdocs/squirrelmail/data/

2.  Attachment Directory         : /var/www/localhost/htdocs/squirrelmail/attach/

```

You should also set your domain in 2. Server Settings. Everything else is according to your preferences. Go through the options and see what you want to change. When you're done, hit S to save. You should now be able to visit http://example.org/squirrelmail and log in with the user@example.org you created in Postfix Admin. This is another web app should be minimally secure with .htaccess over SSL. Send a test message to an account on another server - such as a gmail account - and reply back when you get it. 

Setting up antivirus

Integrating anti-spam and antivirus

```

emerge amavisd-new

```

Edit /etc/amavisd.conf:

Change

```

$mydomain = 'example.com';

```

to:

```

$mydomain = 'localhost';

```

Change

```

virus_admin_maps => ["virusalert\@$mydomain"],

```

to:

```

virus_admin_maps => ["root\@$mydomain"],

```

Change

```

spam_admin_maps  => ["virusalert\@$mydomain"],

```

to:

```

spam_admin_maps  => ["root\@$mydomain"],

```

Change

```

$virus_admin               = "virusalert\@$mydomain";  

$mailfrom_notify_admin     = "virusalert\@$mydomain";  

$mailfrom_notify_recip     = "virusalert\@$mydomain";  

$mailfrom_notify_spamadmin = "spam.police\@$mydomain"; 

```

to: Change all these to root\@$mydomain. 

The above domain and address settings work in conjunction with the /etc/mail/aliases file you set up earlier in this guide. Reports will go to root@localhost, which in /etc/mail/aliases is already mapped to a real email address. 

Change

```

# $myhostname = 'host.example.com';

```

to: Uncomment and fill in your FQDN.

Change

```

$log_level = 0;

```

to:

```

$log_level = 5;

```

This is for testing purposes. You can leave it at 5 or turn it down when everything is confirmed to be working.

Change

```

# ['ClamAV-clamd',

#   \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamav/clamd.sock"],

#   qr/\bOK$/m, qr/\bFOUND$/m,

#   qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ],

```

to: Uncomment these lines.

Edit /etc/postfix/master.cf and add to the bottom of the file:

```

localhost:10025 inet n  -       n       -       2       smtpd

  -o smtp_dns_support_level=enabled

  -o content_filter=

  -o myhostname=server.example.org

  -o local_recipient_maps=

  -o relay_recipient_maps=

  -o smtpd_restriction_classes=

  -o smtpd_client_restrictions=

  -o smtpd_helo_restrictions=

  -o smtpd_sender_restrictions=

  -o smtpd_recipient_restrictions=permit_mynetworks,reject

  -o mynetworks=127.0.0.0/8

  -o strict_rfc821_envelopes=yes

  -o smtpd_error_sleep_time=0

  -o smtpd_soft_error_limit=1001

  -o smtpd_hard_error_limit=1000

  -o smtpd_client_connection_count_limit=0

  -o smtpd_client_connection_rate_limit=0

  -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks

  -o smtpd_authorized_xforward_hosts=127.0.0.0/8

amavis    unix  -       -       n       -       2       lmtp

  -o disable_dns_lookups=yes

  -o lmtp_send_xforward_command=yes

  -o lmtp_data_done_timeout=1200

```

Replace the lines for smtp and smtps with:

```

smtp       inet  n       -       n       -       2       smtpd

  -o content_filter=amavis:[127.0.0.1]:10024

  -o receive_override_options=no_address_mappings

smtps     inet  n       -       n       -       2       smtpd

  -o smtpd_tls_wrappermode=yes

  -o smtpd_sasl_auth_enable=yes

  -o content_filter=amavis:[127.0.0.1]:10024

  -o receive_override_options=no_address_mappings

```

Now run:

```

sa-update

gpasswd -a clamav amavis

/etc/init.d/clamd restart.

```

(Clamav needs to be a part of amavisd's group, and then restarted.)

Start amavisd:

```

/etc/init.d/amavisd start

rc-update add amavisd default

postfix reload

```

Test by using a remote client to send mail from an external mail address, with "X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*" in the body of the message. Check the headers by viewing the source of the reply. In the source, you should see:

```

X-Virus-Scanned: amavisd-new at localhost

```

In /var/log/messages, you should find (you can tail -f /var/log/messages before you send the email):

```

Jan 14 17:07:58 (servername) amavis[3714]: (03714-02) Blocked INFECTED (Eicar-Test-Signature) {DiscardedOpenRelay,Quarantined}, [ip address]:21429 [ip address] <external@emailaddress.com> -> <testuser@example.org>, quarantine: virus-Vj-v2__IqQnQ, Queue-ID: 945005380061, Message-ID: <f2e8f414-0896-2fae-4e88-8e772da686a7@example.org>, mail_id: Vj-v2__IqQnQ, Hits: -, size: 1652, 124 ms

Jan 14 17:07:58 (servername) postfix/lmtp[20424]: 945005380061: to=<testuser@example.org>, relay=127.0.0.1[127.0.0.1]:10024, delay=0.84, delays=0.71/0.01/0/0.12, dsn=2.7.0, status=sent (250 2.7.0 Ok, discarded, id=03714-02 - INFECTED: Eicar-Test-Signature)

```

You should get a message from root@localhost with

```

VIRUS (Eicar-Test-Signature) in mail FROM [ip address]:21429 <external@user.com>

```

as the subject.

Spamassassin integration

Spamassassin should already be installed from your use flags pulling it in. 

Edit /etc/mail/spamassassin/local.cf:

Change:

```

# rewrite_header Subject *****SPAM*****

```

to: Uncomment.

Change:

```

# report_safe 1

```

to: Uncomment.

Change:

```

# required_score 5.0

```

to: Uncomment.

Change:

```

# bayes_auto_learn 1

```

to: Uncomment.

Edit /etc/amavisd.conf:

Change:

```

# @bypass_spam_checks_maps  = (1);

```

to: Make sure this line is commented out.

Change:

```

@local_domains_maps = ( [".$mydomain"]);

```

to, if you have multiple mail domains:

```

@local_domains_maps = ( [".$mydomain", "anotherdomain.com","yetanother.org"]);

```

Stub: Would like to have a better way to have this check the virtual domains already set up for Postfix. 

Edit /etc/postfix/main.cf:

Add:

```

content_filter = amavis:[127.0.0.1]:10024

```

Edit /etc/postfix/master.cf:

Add:

```

localhost:10025 inet n  -   n   -   2   smtpd

  -o smtp_dns_support_level=enabled

  -o content_filter=

  -o myhostname=serverdef.audiodef.com

  -o local_recipient_maps=

  -o relay_recipient_maps=

  -o smtpd_restriction_classes=

  -o smtpd_client_restrictions=

  -o smtpd_helo_restrictions=

  -o smtpd_sender_restrictions=

  -o smtpd_recipient_restrictions=permit_mynetworks,reject

  -o mynetworks=127.0.0.0/8

  -o strict_rfc821_envelopes=yes

  -o smtpd_error_sleep_time=0

  -o smtpd_soft_error_limit=1001

  -o smtpd_hard_error_limit=1000

  -o smtpd_client_connection_count_limit=0

  -o smtpd_client_connection_rate_limit=0

  -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks

  -o smtpd_authorized_xforward_hosts=127.0.0.0/8

amavis    unix  -       -       n       -       2       lmtp

  -o disable_dns_lookups=yes

  -o lmtp_send_xforward_command=yes

  -o lmtp_data_done_timeout=1200

```

Restart Amavis:

```

/etc/initd.amavisd restart

```

Reload Postfix:

```

postfix reload

```

Test Spamassassin by sending an email to one of your users from an external source, such as Gmail or Yahoo mail. In the body should be, on it's own line:

```

XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X

```

This should trigger your setup to deliver the message with a spam label, if everything has been done correctly.

Appendix

Your config files should look like these. You should not simply copy/paste them unless you're already familiar with this guide and need to restore something or are rebuilding your server. 

/etc/postfix/main.cf:

```

compatibility_level = 2

soft_bounce = yes

queue_directory = /var/spool/postfix

command_directory = /usr/sbin

daemon_directory = /usr/libexec/postfix

data_directory = /var/lib/postfix

mail_owner = postfix

myhostname = fullyqualified.domain.com

myorigin = $myhostname

mydestination = $myhostname, localhost.$mydomain, localhost

unknown_local_recipient_reject_code = 550

debug_peer_level = 2

debugger_command =

    PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin

    ddd $daemon_directory/$process_name $process_id & sleep 5

sendmail_path = /usr/sbin/sendmail

newaliases_path = /usr/bin/newaliases

mailq_path = /usr/bin/mailq

setgid_group = postdrop

html_directory = no

manpage_directory = /usr/share/man

sample_directory = /etc/postfix

readme_directory = no

inet_protocols = ipv4

meta_directory = /etc/postfix

shlib_directory = /usr/lib64/postfix/${mail_version}

home_mailbox = .maildir/

#Guide config options

virtual_transport = dovecot

dovecot_destination_recipient_limit = 1

smtpd_sasl_auth_enable = yes

smtpd_sasl_type = dovecot

smtpd_sasl_path = private/auth

virtual_alias_maps = mysql:/etc/postfix/sql_virtual_alias_maps.cf

virtual_mailbox_domains = mysql:/etc/postfix/sql_virtual_domain_maps.cf

virtual_mailbox_maps = mysql:/etc/postfix/sql_virtual_mailbox_maps.cf

smtpd_sender_restrictions = reject_non_fqdn_sender

smtpd_reject_unlisted_sender = yes

smtpd_recipient_restrictions = 

   permit_mynetworks

   reject_non_fqdn_recipient

   permit_sasl_authenticated

   reject_unauth_destination

   reject_rbl_client zen.spamhaus.org

   reject_rbl_client bl.spamcop.net

smtpd_tls_key_file = /etc/postfix/fullyqualified.domain.com.key

smtpd_tls_cert_file = /etc/postfix/fullyqualified.domain.com.crt

smtpd_tls_CAfile = /etc/postfix/cacert.pem

smtpd_tls_loglevel = 3

smtpd_tls_received_header = yes

smtpd_tls_session_cache_timeout = 10800s

smtp_tls_mandatory_ciphers = high

smtp_tls_security_level = may

smtpd_tls_security_level = may

smtpd_tls_auth_only = yes 

```

/etc/postfix/master.cf:

```

#

# Postfix master process configuration file.  For details on the format

# of the file, see the master(5) manual page (command: "man 5 master" or

# on-line: http://www.postfix.org/master.5.html).

#

# Do not forget to execute "postfix reload" after editing this file.

#

# ==========================================================================

# service type  private unpriv  chroot  wakeup  maxproc command + args

#               (yes)   (yes)   (no)    (never) (100)

# ==========================================================================

smtp       inet  n       -       n       -       2       smtpd

  -o content_filter=amavis:[127.0.0.1]:10024

  -o receive_override_options=no_address_mappings

smtps     inet  n       -       n       -       2       smtpd

  -o smtpd_tls_wrappermode=yes

  -o smtpd_sasl_auth_enable=yes

  -o content_filter=amavis:[127.0.0.1]:10024

  -o receive_override_options=no_address_mappings

submission inet n       -       n       -       -       smtpd -o smtpd_enforce_tls=yes -o smtpd_sasl_auth_enable=yes

pickup    unix  n       -       n       60      1       pickup

cleanup   unix  n       -       n       -       0       cleanup

qmgr      unix  n       -       n       300     1       qmgr

tlsmgr    unix  -       -       n       1000?   1       tlsmgr

rewrite   unix  -       -       n       -       -       trivial-rewrite

bounce    unix  -       -       n       -       0       bounce

defer     unix  -       -       n       -       0       bounce

trace     unix  -       -       n       -       0       bounce

verify    unix  -       -       n       -       1       verify

flush     unix  n       -       n       1000?   0       flush

proxymap  unix  -       -       n       -       -       proxymap

proxywrite unix -       -       n       -       1       proxymap

smtp      unix  -       -       n       -       -       smtp

relay     unix  -       -       n       -       -       smtp

showq     unix  n       -       n       -       -       showq

error     unix  -       -       n       -       -       error

retry     unix  -       -       n       -       -       error

discard   unix  -       -       n       -       -       discard

local     unix  -       n       n       -       -       local

virtual   unix  -       n       n       -       -       virtual

lmtp      unix  -       -       n       -       -       lmtp

anvil     unix  -       -       n       -       1       anvil

scache    unix  -       -       n       -       1       scache

dovecot   unix  -       n       n       -       -       pipe

  flags=DRhu user=mail:mail argv=/usr/libexec/dovecot/deliver -f ${sender} -d ${recipient}

localhost:10025 inet n  -       n       -       2       smtpd

  -o smtp_dns_support_level=enabled

  -o content_filter=

  -o myhostname=serverdef.audiodef.com

  -o local_recipient_maps=

  -o relay_recipient_maps=

  -o smtpd_restriction_classes=

  -o smtpd_client_restrictions=

  -o smtpd_helo_restrictions=

  -o smtpd_sender_restrictions=

  -o smtpd_recipient_restrictions=permit_mynetworks,reject

  -o mynetworks=127.0.0.0/8

  -o strict_rfc821_envelopes=yes

  -o smtpd_error_sleep_time=0

  -o smtpd_soft_error_limit=1001

  -o smtpd_hard_error_limit=1000

  -o smtpd_client_connection_count_limit=0

  -o smtpd_client_connection_rate_limit=0

  -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks

  -o smtpd_authorized_xforward_hosts=127.0.0.0/8

amavis    unix  -       -       n       -       2       lmtp

  -o disable_dns_lookups=yes

  -o lmtp_send_xforward_command=yes

  -o lmtp_data_done_timeout=1200

```

/etc/dovecot/dovecot.conf:

```

protocols = imap pop3 lmtp

listen = *, ::

dict {

  #quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext

  #expire = sqlite:/etc/dovecot/dovecot-dict-sql.conf.ext

}

!include conf.d/*.conf

!include_try local.conf

#log_path = /var/log/dovecot.log

```

/etc/amavisd.conf

```

use strict;

$max_servers = 2;            # num of pre-forked children (2..30 is common), -m

$daemon_user  = 'amavis';     # (no default;  customary: vscan or amavis), -u

$daemon_group = 'amavis';     # (no default;  customary: vscan or amavis), -g

$mydomain = 'fullyqualified.domain.com';   # a convenient default for other settings

$TEMPBASE = "$MYHOME/tmp";   # working directory, needs to exist, -T

$ENV{TMPDIR} = $TEMPBASE;    # environment variable TMPDIR, used by SA, etc.

$QUARANTINEDIR = "$MYHOME/quarantine";  # -Q

$log_level = 0;              # verbosity 0..5, -d

$log_recip_templ = undef;    # disable by-recipient level-0 log entries

$do_syslog = 1;              # log via syslogd (preferred)

$syslog_facility = 'mail';   # Syslog facility as a string

           # e.g.: mail, daemon, user, local0, ... local7

$enable_db = 1;              # enable use of BerkeleyDB/libdb (SNMP and nanny)

$nanny_details_level = 2;    # nanny verbosity: 1: traditional, 2: detailed

$enable_dkim_verification = 0;  # enable DKIM signatures verification

$enable_dkim_signing = 0;    # load DKIM signing code, keys defined by dkim_key

@local_domains_maps = ( [".$mydomain", "anotherdomain.com"]);  # list of all local domains

@mynetworks = qw( 127.0.0.0/8 [::1] [FE80::]/10 [FEC0::]/10

                  10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 );

$unix_socketname = "$MYHOME/amavisd.sock";  # amavisd-release or amavis-milter

               # option(s) -p overrides $inet_socket_port and $unix_socketname

$inet_socket_port = 10024;   # listen on this local TCP port(s)

$policy_bank{'MYNETS'} = {   # mail originating from @mynetworks

  originating => 1,  # is true in MYNETS by default, but let's make it explicit

  os_fingerprint_method => undef,  # don't query p0f for internal clients

};

$interface_policy{'10026'} = 'ORIGINATING';

$policy_bank{'ORIGINATING'} = {  # mail supposedly originating from our users

  originating => 1,  # declare that mail was submitted by our smtp client

  allow_disclaimers => 1,  # enables disclaimer insertion if available

  # notify administrator of locally originating malware

  virus_admin_maps => ["root\@$mydomain"],

  spam_admin_maps  => ["root\@$mydomain"],

  warnbadhsender   => 1,

  # forward to a smtpd service providing DKIM signing service

  forward_method => 'smtp:[127.0.0.1]:10027',

  # force MTA conversion to 7-bit (e.g. before DKIM signing)

  smtpd_discard_ehlo_keywords => ['8BITMIME'],

  bypass_banned_checks_maps => [1],  # allow sending any file names and types

  terminate_dsn_on_notify_success => 0,  # don't remove NOTIFY=SUCCESS option

};

$interface_policy{'SOCK'} = 'AM.PDP-SOCK'; # only applies with $unix_socketname

$policy_bank{'AM.PDP-SOCK'} = {

  protocol => 'AM.PDP',

  auth_required_release => 0,  # do not require secret_id for amavisd-release

};

$sa_tag_level_deflt  = -999;  # add spam info headers if at, or above that level

$sa_tag2_level_deflt = 5.0;  # add 'spam detected' headers at that level

$sa_kill_level_deflt = 6.9;  # triggers spam evasive actions (e.g. blocks mail)

$sa_dsn_cutoff_level = 10;   # spam level beyond which a DSN is not sent

$sa_crediblefrom_dsn_cutoff_level = 18; # likewise, but for a likely valid From

$penpals_bonus_score = 8;    # (no effect without a @storage_sql_dsn database)

$penpals_threshold_high = $sa_kill_level_deflt;  # don't waste time on hi spam

$bounce_killer_score = 100;  # spam score points to add for joe-jobbed bounces

$sa_mail_body_size_limit = 400*1024; # don't waste time on SA if mail is larger

$sa_local_tests_only = 0;    # only tests which do not require internet access?

$virus_admin               = "root\@$mydomain";  # notifications recip.

$mailfrom_notify_admin     = "root\@$mydomain";  # notifications sender

$mailfrom_notify_recip     = "root\@$mydomain";  # notifications sender

$mailfrom_notify_spamadmin = "root\@$mydomain"; # notifications sender

$mailfrom_to_quarantine = ''; # null return path; uses original sender if undef

@addr_extension_virus_maps      = ('virus');

@addr_extension_banned_maps     = ('banned');

@addr_extension_spam_maps       = ('spam');

@addr_extension_bad_header_maps = ('badh');

$path = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin:/usr/bin:/bin';

$MAXLEVELS = 14;

$MAXFILES = 3000;

$MIN_EXPANSION_QUOTA =      100*1024;  # bytes  (default undef, not enforced)

$MAX_EXPANSION_QUOTA = 500*1024*1024;  # bytes  (default undef, not enforced)

$sa_spam_subject_tag = '***Spam*** ';

$defang_virus  = 1;  # MIME-wrap passed infected mail

$defang_banned = 1;  # MIME-wrap passed mail containing banned name

$defang_by_ccat{CC_BADH.",3"} = 1;  # NUL or CR character in header

$defang_by_ccat{CC_BADH.",5"} = 1;  # header line longer than 998 characters

$defang_by_ccat{CC_BADH.",6"} = 1;  # header field syntax error

$myhostname = 'fullyqualified.domain.com';  # must be a fully-qualified domain name!

$final_virus_destiny      = D_DISCARD;

$final_banned_destiny     = D_DISCARD;

$final_spam_destiny       = D_PASS;  #!!!  D_DISCARD / D_REJECT

@keep_decoded_original_maps = (new_RE(

  qr'^MAIL$',                # let virus scanner see full original message

  qr'^MAIL-UNDECIPHERABLE$', # same as ^MAIL$ if mail is undecipherable

  qr'^(ASCII(?! cpio)|text|uuencoded|xxencoded|binhex)'i,

# qr'^Zip archive data',     # don't trust Archive::Zip

));

$banned_filename_re = new_RE(

### BLOCKED ANYWHERE

  qr'^\.(exe-ms|dll)$',                   # banned file(1) types, rudimentary

### BLOCK THE FOLLOWING, EXCEPT WITHIN UNIX ARCHIVES:

  [ qr'^\.(rpm|cpio|tar)$'       => 0 ],  # allow any in Unix-type archives

  qr'.\.(pif|scr)$'i,                     # banned extensions - rudimentary

### BLOCK THE FOLLOWING, EXCEPT WITHIN ARCHIVES:

  qr'^application/x-msdownload$'i,        # block these MIME types

  qr'^application/x-msdos-program$'i,

  qr'^application/hta$'i,

  qr'^(?!cid:).*\.[^./]*[A-Za-z][^./]*\.\s*(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)[.\s]*$'i,

  qr'.\.(exe|vbs|pif|scr|cpl)$'i,             # banned extension - basic

);

# ENVELOPE SENDER SOFT-WHITELISTING / SOFT-BLACKLISTING

@score_sender_maps = ({ # a by-recipient hash lookup table,

                        # results from all matching recipient tables are summed

  ## site-wide opinions about senders (the '.' matches any recipient)

  '.' => [  # the _first_ matching sender determines the score boost

   new_RE(  # regexp-type lookup table, just happens to be all soft-blacklist

    [qr'^(bulkmail|offers|cheapbenefits|earnmoney|foryou)@'i         => 5.0],

    [qr'^(greatcasino|investments|lose_weight_today|market\.alert)@'i=> 5.0],

    [qr'^(money2you|MyGreenCard|new\.tld\.registry|opt-out|opt-in)@'i=> 5.0],

    [qr'^(optin|saveonlsmoking2002k|specialoffer|specialoffers)@'i   => 5.0],

    [qr'^(stockalert|stopsnoring|wantsome|workathome|yesitsfree)@'i  => 5.0],

    [qr'^(your_friend|greatoffers)@'i                                => 5.0],

    [qr'^(inkjetplanet|marketopt|MakeMoney)\d*@'i                    => 5.0],

   ),

#  read_hash("/var/amavis/sender_scores_sitewide"),

   { # a hash-type lookup table (associative array)

     'nobody@cert.org'                        => -3.0,

     'cert-advisory@us-cert.gov'              => -3.0,

     'owner-alert@iss.net'                    => -3.0,

     'slashdot@slashdot.org'                  => -3.0,

     'securityfocus.com'                      => -3.0,

     'ntbugtraq@listserv.ntbugtraq.com'       => -3.0,

     'security-alerts@linuxsecurity.com'      => -3.0,

     'mailman-announce-admin@python.org'      => -3.0,

     'amavis-user-admin@lists.sourceforge.net'=> -3.0,

     'amavis-user-bounces@lists.sourceforge.net' => -3.0,

     'spamassassin.apache.org'                => -3.0,

     'notification-return@lists.sophos.com'   => -3.0,

     'owner-postfix-users@postfix.org'        => -3.0,

     'owner-postfix-announce@postfix.org'     => -3.0,

     'owner-sendmail-announce@lists.sendmail.org'   => -3.0,

     'sendmail-announce-request@lists.sendmail.org' => -3.0,

     'donotreply@sendmail.org'                => -3.0,

     'ca+envelope@sendmail.org'               => -3.0,

     'noreply@freshmeat.net'                  => -3.0,

     'owner-technews@postel.acm.org'          => -3.0,

     'ietf-123-owner@loki.ietf.org'           => -3.0,

     'cvs-commits-list-admin@gnome.org'       => -3.0,

     'rt-users-admin@lists.fsck.com'          => -3.0,

     'clp-request@comp.nus.edu.sg'            => -3.0,

     'surveys-errors@lists.nua.ie'            => -3.0,

     'emailnews@genomeweb.com'                => -5.0,

     'yahoo-dev-null@yahoo-inc.com'           => -3.0,

     'returns.groups.yahoo.com'               => -3.0,

     'clusternews@linuxnetworx.com'           => -3.0,

     lc('lvs-users-admin@LinuxVirtualServer.org')    => -3.0,

     lc('owner-textbreakingnews@CNNIMAIL12.CNN.COM') => -5.0,

     # soft-blacklisting (positive score)

     'sender@example.net'                     =>  3.0,

     '.example.net'                           =>  1.0,

   },

  ],  # end of site-wide tables

});

@decoders = (

  ['mail', \&do_mime_decode],

  ['F',    \&do_uncompress, ['unfreeze', 'freeze -d', 'melt', 'fcat'] ],

  ['Z',    \&do_uncompress, ['uncompress', 'gzip -d', 'zcat'] ],

  ['gz',   \&do_uncompress, 'gzip -d'],

  ['gz',   \&do_gunzip],

  ['bz2',  \&do_uncompress, 'bzip2 -d'],

  ['xz',   \&do_uncompress,

           ['xzdec', 'xz -dc', 'unxz -c', 'xzcat'] ],

  ['lzma', \&do_uncompress,

           ['lzmadec', 'xz -dc --format=lzma',

            'lzma -dc', 'unlzma -c', 'lzcat', 'lzmadec'] ],

  ['lrz',  \&do_uncompress,

           ['lrzip -q -k -d -o -', 'lrzcat -q -k'] ],

  ['lzo',  \&do_uncompress, 'lzop -d'],

  ['rpm',  \&do_uncompress, ['rpm2cpio.pl', 'rpm2cpio'] ],

  [['cpio','tar'], \&do_pax_cpio, ['pax', 'gcpio', 'cpio'] ],

           # ['/usr/local/heirloom/usr/5bin/pax', 'pax', 'gcpio', 'cpio']

  ['deb',  \&do_ar, 'ar'],

  ['rar',  \&do_unrar, ['unrar', 'rar'] ],

  ['arj',  \&do_unarj, ['unarj', 'arj'] ],

  ['arc',  \&do_arc,   ['nomarch', 'arc'] ],

  ['zoo',  \&do_zoo,   ['zoo', 'unzoo'] ],

  ['doc',  \&do_ole,   'ripole'],

  ['cab',  \&do_cabextract, 'cabextract'],

  ['tnef', \&do_tnef_ext, 'tnef'],

  ['tnef', \&do_tnef],

  [['zip','kmz'], \&do_7zip,  ['7za', '7z'] ],

  [['zip','kmz'], \&do_unzip],

  ['7z',   \&do_7zip,  ['7zr', '7za', '7z'] ],

  [[qw(7z zip gz bz2 Z tar)],

           \&do_7zip,  ['7za', '7z'] ],

  [[qw(xz lzma jar cpio arj rar swf lha iso cab deb rpm)],

           \&do_7zip,  '7z' ],

  ['exe',  \&do_executable, ['unrar','rar'], 'lha', ['unarj','arj'] ],

);

@av_scanners = (

 ['ClamAV-clamd',

   \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamav/clamd.sock"],

   qr/\bOK$/m, qr/\bFOUND$/m,

   qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ],

);

@av_scanners_backup = (

  ### http://www.clamav.net/   - backs up clamd or Mail::ClamAV

  ['ClamAV-clamscan', 'clamscan',

    "--stdout --no-summary -r --tempdir=$TEMPBASE {}",

    [0], qr/:.*\sFOUND$/m, qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ],

# ### http://www.clamav.net/ - using remote clamd scanner as a backup

# ['ClamAV-clamdscan', 'clamdscan',

#   "--stdout --no-summary --config-file=/etc/clamd-client.conf {}",

#   [0], qr/:.*\sFOUND$/m, qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ],

# ['ClamAV-clamd-stream',

#   \&ask_daemon, ["*", 'clamd:/var/run/clamav/clamd.sock'],

#   qr/\bOK$/m, qr/\bFOUND$/m,

#   qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ],

);

1;  # insure a defined return value

```

/etc/mail/spamassassin/local.cf:

```

rewrite_header Subject *****SPAM*****

report_safe 1

required_score 5.0

bayes_auto_learn 1

ifplugin Mail::SpamAssassin::Plugin::Shortcircuit

endif # Mail::SpamAssassin::Plugin::Shortcircuit

```

Connecting from Thunderbird

Fetching mail:

Server Name: example.org

User Name: user@example.org

Port: 143

Connection security: STARTTLS

Authentication method: Normal password

Sending mail:

Server Name: example.org

Port 587

Connection security: STARTTLS

Authentication method: Normal password

User Name: user@example.org

You need to click on Advanced config, which will basically close the new account setup window. Go into account settings and manually set the above options. This will get you set up with reading your inbox and connecting to your SMTP server to send mail.

Enjoy!

Thanks to:

grknight

Ant P.

freke

TODO: fail2ban integration to block repeated unauth login attempts to mail server.

----------

## freke

 *audiodef wrote:*   

> This guide is im bau until I remove this sentence. I need to proof-read, fill-in gaps, etc. Shouldn't take too long. 
> 
> To enforce sender restrictions and to handle rejection, add to /etc/postfix/main.cf:
> 
> ```
> ...

 

I'm not sure you're supposed to have the '=' - here's a snippet from my config:

```
smtpd_recipient_restrictions =

        check_sender_access hash:/etc/postfix/maps/sender_access

        permit_mynetworks

        permit_sasl_authenticated

        reject_rbl_client in.dnsbl.vlh.dk

        reject_rbl_client vn.dnsbl.vlh.dk

        reject_unknown_recipient_domain

        reject_non_fqdn_recipient

        check_recipient_access hash:/etc/postfix/maps/recipient

        check_policy_service unix:/var/run/sqlgrey.sock

        check_policy_service inet:mail.vlh.dk:12525

        check_policy_service unix:private/policyd-spf
```

----------

## audiodef

Thank you, freke! That worked. Guide updated.

----------

## Ant P.

I'm just going to drop in with a few things I've had in my postfix config for a while:

```
smtpd_delay_reject = no

smtpd_helo_required = yes

smtpd_helo_restrictions =

    permit_mynetworks,

    reject_non_fqdn_helo_hostname,

    reject_invalid_helo_hostname,

    reject_unknown_helo_hostname,

    permit

smtpd_recipient_restrictions =

    reject_unauth_pipelining,

    reject_non_fqdn_recipient,

    reject_unknown_recipient_domain,

    permit_mynetworks,

    reject_rbl_client zen.spamhaus.org,

    reject_rbl_client bl.spamcop.net,

    reject_unauth_destination,

    check_policy_service inet:127.0.0.1:2501,    # mail-filter/sqlgrey

    permit

smtpd_sender_restrictions =

    permit_mynetworks,

    reject_non_fqdn_sender,

    reject_unknown_sender_domain,

    permit

smtpd_tls_auth_only = yes

smtpd_tls_mandatory_ciphers = high

smtpd_tls_mandatory_exclude_ciphers = aNULL, eNULL

smtpd_tls_mandatory_protocols = TLSv1.2

smtpd_tls_received_header = yes

smtpd_tls_security_level = may     # level=encrypt breaks too much

strict_rfc821_envelopes = yes

tls_disable_workarounds = 0xFFFFFFFF

tls_random_source = dev:/dev/urandom

disable_vrfy_command = yes

header_checks = pcre:/etc/postfix/header_checks
```

```
/^X-Mailer:\s.*Microsoft/

    REJECT You look like a spambot, don't come back until you get a real mail program.
```

The reject lines are fairly safe, the last part isn't but it caught a wave of spam when nothing else worked. Depends on your audience I guess.

----------

## audiodef

Ant, that is much appreciated. I do want to add setting up greylisting at some point.

----------

## audiodef

Updated: Added clamav/amavis integration.

----------

## audiodef

Updated: Spamassassin integration.

----------

## audiodef

TBD: While watching tail -f /var/log/messages, mail appears to be received via remote client, but not delivered, with no error message, when sending from user@example.org to user@example.org.

This is also true when sending mail from any user of any domain to any user of any domain if both domains are on the same server set up as per this guide.

EDIT:

Found

```

warning: connect to transport private/smtp-amavis: Connection refused

```

in /var/log/messages after sending test mail.

SOLVED: Had

```

content_filter = smtp-amavis:[127.0.0.1]:10024

```

at the end of main.cf, conflicting with master.cf.

----------

## direwolf

Squirrelmail is masked now and being removed???

How do we get it back into emerge?

----------

## ct85711

Looking at the mask message and the bug report mentioned, the main reason why it is masked for removal is because there isn't anyone willing to maintain the package anymore.  Though judging by the last couple comments in the bug report, there may be someone that is finally stepping up to maintain the package.

----------

## direwolf

 *ct85711 wrote:*   

> Looking at the mask message and the bug report mentioned, the main reason why it is masked for removal is because there isn't anyone willing to maintain the package anymore.  Though judging by the last couple comments in the bug report, there may be someone that is finally stepping up to maintain the package.

 

I've done so myself, but without response. 

I guess I'll have to build an overlay instead.

----------

