How to (sort of) configure a web server
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
- https://dannorth.net/2007/09/09/virtual-mailboxes-with-courier-imap-and-postfix/
- http://www.postfix.org/VIRTUAL_README.html
- http://www.berkes.ca/guides/postfix_virtual.html
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"