This setup will be based on

  • Debian 8
  • Apache2, multiple domains, SSL
  • Postfix, virtual accounts, using couriers-authdeamon, SSL
  • Courier, virtual accounts, authentication, SSL

The reason why I write this down is to avoid having to look this up again, and I will forget what I did anyway. I created this after the installation, so it might be incomplete, and not in the right order.

I did not cover the installation of the services itself, this is just about the configuration.

User(s)

First of all you want to add your first user:

# adduser paul
Adding user `paul' ...
Adding new group `paul' (1001) ...
Adding new user `paul' (1001) with group `paul' ...
Creating home directory `/home/paul' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
# [...] then follow instructions

For more details on this, check: https://wiki.ubuntuusers.de/adduser/

SSH Settings

Next you might want to change the following settings for the SSH server to avoid the following scenario:

# lastb | head -50
ba       ssh:notty    94.177.52.77     Fri Dec 21 17:11 - 17:11  (00:00)
zo       ssh:notty    94.177.52.77     Fri Dec 21 17:11 - 17:11  (00:00)
test     ssh:notty    94.177.52.77     Fri Dec 21 17:10 - 17:10  (00:00)
webuser  ssh:notty    94.177.52.77     Fri Dec 21 17:10 - 17:10  (00:00)
# [...]
admin    ssh:notty    124.188.40.103   Sat Dec 15 23:39 - 23:39  (00:00)
admin    ssh:notty    124.188.40.103   Sat Dec 15 23:39 - 23:39  (00:00)
# lastb | wc -l
34123

This means I had 34123 failed login attempts in 7 days. That’s a login attempt every 20 seconds. Time to block them.

# apt-get install fail2ban

Fail2Ban scans log files (e.g. /var/log/apache/error_log) and bans IPs that show the malicious signs. Read more on their page ;).

Result:

# tail -2 /var/log/fail2ban.log
2018-12-21 17:12:28,120 fail2ban.actions[22877]: WARNING [ssh] Ban 94.177.52.77

Also: edit the file /etc/fail2ban/jail.conf, and enable the sections

  • postfix
  • couriersmtp
  • courierauth
  • sasl

These are not enabled by default, and it makes sense to enable them after you have figured out how to setup our mail client to avoid getting banned yourself.

This gives us some silence, but we can do more.

First, follow this tutorial: How to set up ssh so you aren’t asked for a password. (TL;DR: ssh-keygen, then ssh-copy-id to your host).

Check the following settings in /etc/ssh/sshd_config:

PermitRootLogin no        # because letting them even try getting root access, is not good
PasswordAuthentication no # because letting them even try passwords, is also not good

Note, those are only the values I changed, so make sure everything else in default mode makes sense, too. Switching the default port is also good. But I’m too lazy for that. For now.

Login Mail Notification

Assuming, you are going to run a personal server, and want to get notified about any logins, let’s set this up. If you are running a server with multiple users, you likely know more than me and are in the wrong place, or like to get flooded by emails.

Then add this script to /usr/sbin/login-notify.sh:

#!/bin/sh

if [ "$PAM_TYPE" != "close_session" ]; then
    host="`hostname`"
    subj="$PAM_USER@$host logged in from $PAM_RHOST; $PAM_TYPE"
    echo "If this was you, you can delete this mail." | mail -s "$subj" login-notification
fi

And register it in /etc/pam.d/sshd with:

session    optional     pam_exec.so seteuid /usr/sbin/login-notify.sh

So IF someone actually does get in, you will get an email. Make sure to relay emails login-notification@example.com to another host, so you actually do get them before someone wipes or messes up your server ;).

Mail server

I followed the blog post from Dan North & Associates, but ran into a tiny problem (that took me 2h to resolve), when trying to use the SMTP mail service:

(Check your /var/log/mail.log)

I was getting

postfix/smtpd[]: fatal: no SASL authentication mechanisms

Which was resolved by installing libsasl2-modules.

After a postfix restart, and another test, this was followed by

postfix/smtpd[]:  warning: SASL authentication failure: cannot connect to Courier authdaemond: No such file or directory

Which I fixed by giving postfix the required socket under /var/spool/postfix/var/run/courier/authdameon/socket by moving the directory /var/run/courier/authdameon to /var/spool/postfix/var/run/courier/, and then symlinking to the directory. This is needed as courier-authdaemon recreates the socket on restart, and linking from postfix to the authdaemon socket throws an warning: SASL authentication failure: cannot connect to Courier authdaemond: Too many levels of symbolic links error.

mkdir -p /var/spool/postfix/var/run/courier/
mv /var/run/courier/authdaemon/ /var/spool/postfix/var/run/courier/
ln -s /var/spool/postfix/var/run/courier/authdaemon/ /var/run/courier/

I tested again, and it worked. :)

Postfix: SMTP TLS

# TLS parameters
smtpd_tls_cert_file=/etc/letsencrypt/live/p3dt.net/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/p3dt.net/privkey.pem
smtpd_use_tls=yes
smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

smtpd_sasl_local_domain =
smtpd_sasl_auth_enable = yes
smtpd_sasl_security_options = noanonymous
smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination
broken_sasl_auth_clients = yes

Postfix: SMTP SASL

Create the file /etc/postfix/sasl/smtpd.conf:

pwcheck_method: authdaemond
mech_list: plain login
authdaemond_path: /var/run/courier/authdaemon/socket

See symlink swappery I had to do above, to get this to work.

Postfix: Virtual Mail

virtual_mailbox_domains = p3dt.net
virtual_alias_maps = hash:/etc/postfix/virtual
virtual_mailbox_maps = hash:/etc/postfix/vmailbox
virtual_mailbox_base = /home/vhosts
virtual_minimum_uid = 100
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000

Hint: the files virtual and vmailbox have to be converted with postmap to take effect:

cd /etc/postfix
postmap virtual
postmap vmailbox
postfix reload

Courier: SSL

Create the file /etc/couried/imapd.pem:

cd /etc/letsencrypt/live/p3dt.net
cat privkey.pem cert.pem chain.pem  > /etc/courier/imapd.pem

In /etc/courier/imapd-ssl:

TLS_CERTFILE=/etc/courier/imapd.pem
TLS_TRUSTCERTS=/etc/letsencrypt/live/p3dt.net/chain.pem

I can’t remember what else I changed. :)

Courier: adding users

I noticed that I had to adapt the way of adding the user to access the virtual mailboxes. In the original post, they use the user and group vmail as a reference to gid and uid:

userdb username set uid=vmail gid=vmail home=/home/vhosts/p3dt.net/username mail=/home/vhosts/p3dt.net/username

Which led to the following error message on my system:

Dec 25 14:26:54 p3dt imapd-ssl: username: Account's mailbox directory is not owned by the correct uid or gid

So, I changed it to the following to work:

userdb username set uid=5000 gid=5000 home=/home/vhosts/p3dt.net/username mail=/home/vhosts/p3dt.net/username

Hint: Don’t forget to run makeuserdb like me ;).

More infos

The main infos I got from

HTTP Server

Virtual hosts: https://httpd.apache.org/docs/2.4/vhosts/name-based.html Details: https://httpd.apache.org/docs/2.4/vhosts/examples.html

Templates

I created sites under /etc/apache2/sites-available/ with the following template:

<VirtualHost p3dt.net:80>
    DocumentRoot "/var/www/p3dt/"
    ServerName p3dt.net
    ErrorLog ${APACHE_LOG_DIR}/error_p3dt_net.log
    CustomLog ${APACHE_LOG_DIR}/access_p3dt_net.log combined
    # Other directives here ...
</VirtualHost>

This gets rewritten to

<VirtualHost p3dt.net:80>
    DocumentRoot "/var/www/p3dt/"
    ServerName p3dt.net
    ErrorLog ${APACHE_LOG_DIR}/error_p3dt_net.log
    CustomLog ${APACHE_LOG_DIR}/access_p3dt_net.log combined
    # Other directives here ...
RewriteEngine on
RewriteCond %{SERVER_NAME} =p3dt.net
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

by /root/certbot-auto --apache, which also creates:

<IfModule mod_ssl.c>
<VirtualHost p3dt.net:443>
    DocumentRoot "/var/www/p3dt/"
    ServerName p3dt.net
    ErrorLog ${APACHE_LOG_DIR}/error_p3dt_net.log
    CustomLog ${APACHE_LOG_DIR}/access_p3dt_net.log combined
    # Other directives here ...
SSLCertificateFile /etc/letsencrypt/live/p3dt.net/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/p3dt.net/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

Certificates

I followed the instructions from: https://certbot.eff.org/lets-encrypt/debianjessie-apache

My cronjob is

0 0,12 * * * /root/certbot-auto renew --post-hook "service apache2 restart"