Table of Contents

A history of a selfhosted mail server

guide-diary-(blog?) to configure a very mail server. I also try to control and selfhost all possible services I use and related to my needs.

1 TODO Tasks and research

2 <2019-01-11 Fri> new certbot

dns challenge in certbot looks like is not very automatic, let's go to the old school method

certbot certonly -n –keep –agree-tos –email [masked] –webroot -w /var/www/html -d cas.cat

certbot certonly -n –keep –agree-tos –email [masked] –webroot -w /var/www/html -d host.cas.cat

3 <2018-12-05 Wed> review configs

I want to have another host with a similar configuration. Good moment to review missing (not explained) configurations

3.1 postfix

this configuration /etc/postfix/main.cf:

  • works only for encrypted connections both smtp (client) and smtpd (server)
  • enforce only strong encryption ciphers
  • reject mail based on online spam databases
  • attachment limit 100 MB
  • dane compatible
  • dkim compatible
  • connects to imap dovecot
  • uses sasl to authenticate imap
# See /usr/share/postfix/main.cf.dist for a commented, more complete version

# Debian specific:  Specifying a file name will cause the first
# line of that file to be used as the name.  The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname

smtpd_banner = $myhostname ESMTP $mail_name (Debian/GNU)
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h

readme_directory = no

# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 2 on
# fresh installs.
compatibility_level = 2

# TLS parameters
smtpd_tls_cert_file=/etc/letsencrypt/live/cas.cat/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/cas.cat/privkey.pem
smtpd_use_tls = yes
# According to RFC 2487 this MUST NOT be applied in case of a publicly-referenced SMTP server. Instead, this option should be used only on dedicated servers. -> src http://www.postfix.org/postconf.5.html#smtpd_tls_received_header
smtpd_tls_auth_only = yes
smtpd_tls_received_header = yes
smtp_use_tls = yes

#smtp_tls_security_level = encrypt
smtpd_tls_security_level = encrypt
#smtpd_tls_security_level = may

# DANE-Settings 
# src https://tech.feedyourhead.at/content/postfix-verified-tls-with-dane
# and "DANE TLS authentication" -> src http://www.postfix.org/TLS_README.html
smtp_dns_support_level = dnssec 
smtp_host_lookup = dns 
smtp_tls_security_level = dane 

smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache

# See /usr/share/doc/postfix/TLS_README.gz in the postfix-doc package for
# information on enabling SSL in the smtp client.


# move transport to dovecot; NO, this makes /etc/aliases to not work!
# local_transport = lmtp:unix:private/dovecot-lmtp
# src http://postfix.1071664.n5.nabble.com/Problems-with-lmtp-td89453.html
mailbox_transport = lmtp:unix:private/dovecot-lmtp
# src http://www.postfix.org/SASL_README.html#server_sasl_enable
smtpd_sasl_auth_enable = yes
# enforce ONLY TLS -> src https://www.howtoforge.com/community/threads/how-to-force-secure-authentication-over-ssl-or-tls-with-postfix.56860/
# extra http://www.postfix.org/SASL_README.html#server_sasl
smtpd_tls_auth_only = yes
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_security_options = noanonymous
smtpd_sasl_authenticated_header = yes
smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination

# to avoid this error check: Helo command rejected: need fully-qualified hostname
myhostname = host.cas.cat
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = cas.cat, localhost, localhost.localdomain, localhost
relayhost = 
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all
#inet_protocols = all
# (temp) disable ipv6 -> src https://www.admon.org/faqs/how-to-disable-ipv6-in-postfix/
inet_protocols = ipv4

smtpd_recipient_restrictions =
   # whitelist
   # src https://www.serveradminblog.com/2010/03/how-to-whitelist-hosts-or-ip-addresses-in-postfix/
   #check_sender_access hash:/etc/postfix/whitelist

   permit_mynetworks
   # src http://www.postfix.org/SMTPD_ACCESS_README.html
   permit_sasl_authenticated

   reject_invalid_hostname
   reject_non_fqdn_hostname
   reject_non_fqdn_sender
   reject_non_fqdn_recipient
   reject_unknown_sender_domain
   reject_unknown_recipient_domain
   reject_unauth_destination

   # check sender access should be after unauth destination: http://serverfault.com/questions/534174/how-do-i-block-an-email-address-in-postfix
   # src http://serverfault.com/questions/321109/how-to-prevent-remote-hosts-from-delivering-mail-to-postfix-with-spoofed-from-he
   #check_sender_access hash:/etc/postfix/notfromme

   reject_rbl_client zen.spamhaus.org

   # new
   reject_rhsbl_reverse_client dbl.spamhaus.org
   reject_rhsbl_helo dbl.spamhaus.org
   reject_rhsbl_sender dbl.spamhaus.org

   reject_rbl_client b.barracudacentral.org
   permit

# allow up to 100 MB of attachments
message_size_limit=104857600

# dkim
milter_default_action = accept
milter_protocol = 2
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891 

# avoid untrusted TLS -> src https://serverfault.com/questions/858311/postfix-untrusted-tls-connection
smtp_tls_CApath = /etc/ssl/certs
smtpd_tls_CApath = /etc/ssl/certs
# tlsrecos | extra security recomendations -> src https://blog.kruyt.org/postfix-and-tls-encryption/
smtpd_tls_protocols = TLSv1.3, TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3
smtp_tls_protocols = $smtpd_tls_protocols
smtp_tls_ciphers = high
smtpd_tls_ciphers = high
smtpd_tls_mandatory_protocols = $smtpd_tls_protocols
smtp_tls_mandatory_protocols = $smtpd_tls_protocols
smtp_tls_mandatory_ciphers = high
smtpd_tls_mandatory_ciphers = high
# src https://serverfault.com/questions/585452/disable-cipher-ssl3-rsa-with-seed-sha-in-postfix
#tls_high_cipherlist=EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA

smtpd_tls_mandatory_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL
smtpd_tls_exclude_ciphers = $smtpd_tls_mandatory_exclude_ciphers
smtp_tls_mandatory_exclude_ciphers = $smtpd_tls_mandatory_exclude_ciphers
smtp_tls_exclude_ciphers = $smtpd_tls_mandatory_exclude_ciphers
tls_preempt_cipherlist = yes

# Secure Client-Initiated Renegotiation -> src http://www.postfix.org/postconf.5.html#smtpd_client_new_tls_session_rate_limit
# extra src http://postfix.1071664.n5.nabble.com/Disable-SSL-TLS-renegotiation-td96864.html
smtpd_client_new_tls_session_rate_limit = 100

# Check the logs / headers if it is working
smtpd_tls_loglevel = 1
smtp_tls_loglevel = 1
# finish tlsrecos

enable smtps server in /etc/postfix/master.cf

smtps     inet  n       -       y       -       -       smtpd
  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes

3.2 dkim

apt install opendkim opendkim-tools

In file /etc/opendkim.conf replace

Socket                  local:/var/run/opendkim/opendkim.sock

with

Socket                  inet:8891@localhost

In the same file add:

# src https://wiki.debian.org/opendkim
KeyTable file:/etc/postfix/dkim/keytable
SigningTable file:/etc/postfix/dkim/signingtable

# src https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-dkim-with-postfix-on-debian-wheezy
AutoRestart             Yes
AutoRestartRate         10/1h
Canonicalization        relaxed/simple
SignatureAlgorithm      rsa-sha256

Now, let's continue with some commands suggestes by https://wiki.debian.org/opendkim

mkdir /etc/postfix/dkim/
opendkim-genkey -D /etc/postfix/dkim/ -d host.exo.cat -s mail
chgrp opendkim /etc/postfix/dkim/*
chmod g+r /etc/postfix/dkim/*

in /etc/postfix/dkim/keytable add

mail._domainkey.cas.cat cas.cat:mail:/etc/postfix/dkim/mail.private

in /etc/postfix/dkim/signingtable add

cas.cat mail._domainkey.cas.cat

change in /etc/default/opendkim

SOCKET="inet:8891@localhost" 

copy dns part using file /etc/postfix/dkim/mail.txt

finally restart service to apply changes

3.3 dovecot

apt install dovecot-core dovecot-imapd dovecot-lmtpd dovecot-pop3d

in file /etc/dovecot/conf.d/10-auth.conf add login in authmechanisms:

#...
auth_username_format = %n
#...
auth_mechanisms = plain login

in file /etc/dovecot/conf.d/10-mail.conf in namespace inbox explicitly put:

separator = /

and modify

mail_location = mbox:~/mail:INBOX=/var/mail/%u

to

mail_location = maildir:~/mail:INBOX=/var/mail/%u

uncomment and complete following line:

mail_privileged_group = mail

remember that to allow user modify its IMAP directories you have to run gpasswd -a myuser mail (thanks https://serverfault.com/questions/713635/postfix-dovecot-squirrelmail-failed-to-autocreate-mailbox-inbox)

in file /etc/dovecot/conf.d/10-master.conf change following parts to look like this:

service imap-login {
  inet_listener imap {
    #port = 143
  }
  inet_listener imaps {
    #port = 993
    #ssl = yes
  }
#...
service lmtp {
  #orig
  #unix_listener lmtp {
    #mode = 0666
  unix_listener /var/spool/postfix/private/dovecot-lmtp {
    group = postfix
    mode = 0600
    user = postfix
  }

  # Create inet listener only if you can't use the above UNIX socket
  #inet_listener lmtp {
    # Avoid making LMTP visible for the entire internet
    #address =
    #port = 
  #}
}
#...
service auth {
  # auth_socket_path points to this userdb socket by default. It's typically
  # used by dovecot-lda, doveadm, possibly imap process, etc. Users that have
  # full permissions to this socket are able to get a list of all usernames and
  # get the results of everyone's userdb lookups.
  #
  # The default 0666 mode allows anyone to connect to the socket, but the
  # userdb lookups will succeed only if the userdb returns an "uid" field that
  # matches the caller process's UID. Also if caller's uid or gid matches the
  # socket's uid or gid the lookup succeeds. Anything else causes a failure.
  #
  # To give the caller full permissions to lookup all users, set the mode to
  # something else than 0666 and Dovecot lets the kernel enforce the
  # permissions (e.g. 0777 allows everyone full permissions).
  unix_listener auth-userdb {
    #mode = 0666
    #user = 
    #group = 
  }

  # Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    # assuming default postfix user and group
    user = postfix
    group = postfix
  }

  # Auth process is run as this user.
  #user = $default_internal_user
}

prepare ssl certs for dovecot

mkdir /etc/dovecot/tls
cd /etc/dovecot/tls
ln -s /etc/letsencrypt/live/cas.cat/fullchain.pem
ln -s /etc/letsencrypt/live/cas.cat/privkey.pem

in file /etc/dovecot/conf.d/10-ssl.conf change following parts to look like this:

# SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>
ssl = required

# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
# dropping root privileges, so keep the key file unreadable by anyone but
# root. Included doc/mkcert.sh can be used to easily generate self-signed
# certificate, just make sure to update the domains in dovecot-openssl.cnf
#ssl_cert = </etc/dovecot/dovecot.pem
#ssl_key = </etc/dovecot/private/dovecot.pem
ssl_cert = </etc/dovecot/tls/fullchain.pem
ssl_key = </etc/dovecot/tls/privkey.pem

ssl_protocols = !SSLv3 !TLSv1 !TLSv1.1

ssl_cipher_list = AES128+EECDH:AES128+EDH
ssl_prefer_server_ciphers = yes # >Dovecot 2.2.6
# wait dovecot 2.3
#ssl_dh=</etc/dovecot/tls/dhparam.pem # openssl dhparam -out /etc/dovecot/tls/dhparam.pem 4096
ssl_dh_parameters_length = 2048 # >Dovecot 2.2 -> https://www.dovecot.org/list/dovecot/2013-November/093315.html

4 <2018-10-22 Mon> about SMTPS

Thanks to a discussion in https://serverfault.com/questions/523804/is-starttls-less-safe-than-tls-ssl I found a very recent RFC says that we sould move from starttls to implicit tls as we are finding in other protocols -> https://tools.ietf.org/html/rfc8314

let's do that. Let's move from 587 starttls to 465 tls

changes in /etc/firewall4

remove line

-A INPUT -i ens3 -p tcp -m multiport --dports 587 -j ACCEPT -m comment --comment "alternate to 25; RFC 4409 (smtp)"

add line

-A INPUT -i ens3 -p tcp -m multiport --dports 465 -j ACCEPT -m comment --comment "implicit TLS rfc8314"

reload firewall

iptables-restore < /etc/firewall4

removed submission in postfix and added smtps, this part looks like this

#submission inet n       -       y       -       -       smtpd
##submission inet n       -       y       -       -       smtpd -v
#  -o syslog_name=postfix/submission
## src You can ENFORCE the use of TLS, so that the Postfix SMTP server announces STARTTLS and accepts no mail without TLS encryption, by setting "smtpd_tls_security_level = encrypt" -> src http://www.postfix.org/TLS_README.html#server_enable
#  -o smtpd_tls_security_level=encrypt
##  -o smtpd_tls_security_level=may
#  -o smtpd_sasl_auth_enable=yes
##  -o smtpd_reject_unlisted_recipient=no
##  -o smtpd_client_restrictions=$mua_client_restrictions
##  -o smtpd_helo_restrictions=$mua_helo_restrictions
##  -o smtpd_sender_restrictions=$mua_sender_restrictions
##  -o smtpd_recipient_restrictions=
##  -o smtpd_relay_restrictions=permit_sasl_authenticated,reject
##  -o milter_macro_daemon_name=ORIGINATING
smtps     inet  n       -       y       -       -       smtpd
# smtps     inet  n       -       y       -       -       smtpd -v
  -o syslog_name=postfix/smtps
  -o smtpd_tls_wrappermode=yes
  -o smtpd_sasl_auth_enable=yes

tls_wrappermode means that STARTLS is not used, and that's what we want -> http://www.postfix.org/postconf.5.html#smtpd_tls_wrappermode

restart postfix server

service postfix restart

reconfigure clients from submission to smtps

5 <2018-10-14 Sun> TLS ciphers, dmarc and dane

5.1 More TLS: dovecot IMAPS on 993 (IMAP TLS) is C+ to A <2018-10-14 Sun 00:43>

The test I'm caring of is: https://www.htbridge.com/ssl/?id=m0aAbuem

let's fix that in /etc/dovecot/conf.d/10-ssl.conf

##
## SSL settings
##

# inspired by https://cipherli.st/

# SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>
ssl = required

# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
# dropping root privileges, so keep the key file unreadable by anyone but
# root. Included doc/mkcert.sh can be used to easily generate self-signed
# certificate, just make sure to update the domains in dovecot-openssl.cnf
ssl_cert = </etc/dovecot/tls/fullchain.pem
ssl_key = </etc/dovecot/tls/privkey.pem

#verbose_ssl = yes

ssl_protocols = !SSLv3 !TLSv1 !TLSv1.1

ssl_cipher_list = AES128+EECDH:AES128+EDH
ssl_prefer_server_ciphers = yes # >Dovecot 2.2.6
# wait dovecot 2.3
#ssl_dh=</etc/dovecot/tls/dhparam.pem # openssl dhparam -out /etc/dovecot/tls/dhparam.pem 4096
ssl_dh_parameters_length = 2048 # >Dovecot 2.2 -> https://www.dovecot.org/list/dovecot/2013-November/093315.html

To force regeneration of dhparams due to the situation of dovecot 2.2 I removed file /var/lib/dovecot/ssl-parameters.dat, restarted dovecot and waited some minutes

5.2 stronger dmarc <2018-10-14 Sun 15:21>

followed criterion of internet.nl with the help of https://dmarc.org/overview/

-_dmarc.cas.cat. IN TXT "v=DMARC1; p=none"
+_dmarc.cas.cat. IN TXT "v=DMARC1;p=reject;pct=100;rua=mailto:dmarc@cas.cat"

created account and so on

5.3 dane in smtp <2018-10-14 Sun 21:57>

dane improves encryption and security in mailservers

relevant source: https://community.letsencrypt.org/t/please-avoid-3-0-1-and-3-0-2-dane-tlsa-records-with-le-certificates/7022/21

Get TLSA record for postfix with

postfix tls output-server-tlsa

I put that record in /etc/bind/zones/db.cas.cat. Serial goes up and service bind9 restart

Certbot cronjob has to updated to the certificate is not changed and does not affect dane.

In /etc/cron.d/certbot:

-0 */12 * * * letsencrypt test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && su - letsencrypt -s /bin/bash -c "certbot -q renew"
+0 */12 * * * letsencrypt test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && su - letsencrypt -s /bin/bash -c "certbot -q renew --reuse-key"

and in /lib/systemd/system/certbot.service/ the same

Change postfix configuration to work with dane. In /etc/postfix/main.cf put:

# DANE-Settings 
# src https://tech.feedyourhead.at/content/postfix-verified-tls-with-dane
# and "DANE TLS authentication" -> src http://www.postfix.org/TLS_README.html
smtp_dns_support_level = dnssec
smtp_host_lookup = dns
smtp_tls_security_level = dane

and service postfix restart

testers used:

internet.nl detects that there is no rollover scheme but at the moment looks difficult. More info: http://imrryr.org/~viktor/ICANN61-viktor.pdf

6 <2018-10-12 Fri> Checking TLS

6.1 secure postfix following a guide <2018-10-12 Fri 19:20>

https://blog.kruyt.org/postfix-and-tls-encryption/

I changed it to avoid redundancy and because I don't want to accept TLSv1.1 (it is now deprecated)

# extra security recomendations -> src https://blog.kruyt.org/postfix-and-tls-encryption/
smtpd_tls_protocols = TLSv1.3, TLSv1.2, !TLSv1.1, !TLSv1, !SSLv2, !SSLv3
smtp_tls_protocols = $smtpd_tls_protocols
smtp_tls_ciphers = high
smtpd_tls_ciphers = high
smtpd_tls_mandatory_protocols = $smtpd_tls_protocols
smtp_tls_mandatory_protocols = $smtpd_tls_protocols
smtp_tls_mandatory_ciphers = high
smtpd_tls_mandatory_ciphers = high

smtpd_tls_mandatory_exclude_ciphers = MD5, DES, ADH, RC4, PSD, SRP, 3DES, eNULL, aNULL
smtpd_tls_exclude_ciphers = $smtpd_tls_mandatory_exclude_ciphers
smtp_tls_mandatory_exclude_ciphers = $smtpd_tls_mandatory_exclude_ciphers
smtp_tls_exclude_ciphers = $smtpd_tls_mandatory_exclude_ciphers
tls_preempt_cipherlist = yes

6.2 testssl.sh on mx

if I put rate limit to 1 I got errors running testssl.sh thing

# Secure Client-Initiated Renegotiation -> src http://www.postfix.org/postconf.5.html#smtpd_client_new_tls_session_rate_limit
# extra src http://postfix.1071664.n5.nabble.com/Disable-SSL-TLS-renegotiation-td96864.html
smtpd_client_new_tls_session_rate_limit = 100

6.3 updated nginx https config / fixed http headers

Test used in http headers -> https://securityheaders.com/

In /etc/nginx/nginx.conf update SSL settings as here noted:

##
# SSL Settings
##

#ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_protocols TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;

# more ssl settings -> src https://cipherli.st/
ssl_dhparam /etc/nginx/dhparam.pem; # openssl dhparam -out /etc/nginx/dhparam.pem 4096
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
ssl_session_timeout  10m;
# enable session resumption to improve https performance
# http://vincent.bernat.im/en/blog/2011-ssl-session-reuse-rfc5077.html
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Requires nginx >= 1.5.9
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on; # Requires nginx => 1.3.7
# enable if you have own dns and cache
#resolver $DNS-IP-1 $DNS-IP-2 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

# https://securityheaders.com gives me warning but don't know how to fix it -> src https://fearby.com/article/set-up-feature-policy-referrer-policy-and-content-security-policy-headers-in-nginx/
add_header 'Feature-Policy' "geolocation: 'none';midi: none;notifications: none;push: none;sync-xhr: none;microphone: none;camera: none;magnetometer: none;gyroscope: none;speaker: self;vibrate: none;fullscreen: self;payment: none;";
add_header Feature-Policy "geolocation none;midi none;notifications none;push none;sync-xhr none;microphone none;camera none;magnetometer none;gyroscope none;speaker self;vibrate none;fullscreen self;payment none;";

# The "Referrer-Policy" HTTP header is not set to "no-referrer", "no-referrer-when-downgrade", "strict-origin" or "strict-origin-when-cross-origin". This can leak referer information. See the W3C Recommendation ->
#  https://www.w3.org/TR/referrer-policy/#referrer-policy-no-referrer
#  https://stackoverflow.com/questions/43447490/how-to-set-referrer-policy-with-nginx
add_header 'Referrer-Policy' 'no-referrer';

# src https://scotthelme.co.uk/content-security-policy-an-introduction/
add_header 'Content-Security-Policy' "script-src 'self";

## my own research
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
# src https://serverfault.com/questions/544279/nginx-disable-gzip-compression-for-https-only
gzip off;

delete line gzip on that is in the same file (because this is a https only server)

6.4 certbot systemd service

My certbot is nearly used always as a user and not as a root. Except from one thing I found. After a systemd execution /var/log/letsencrypt/letsencrypt.log changes permissions.

Oct 12 12:40:14 cascat-vps systemd[1]: Starting Certbot...
Oct 12 12:40:15 cascat-vps systemd[1]: Started Certbot.
Oct 12 12:40:15 cascat-vps systemd[1]: certbot.timer: Adding 36min 51.815403s random time.
Oct 12 12:40:15 cascat-vps systemd[1]: certbot.timer: Adding 27min 2.436797s random time.

here is a service

root@cascat-vps:~# service certbot status
● certbot.service - Certbot
   Loaded: loaded (/lib/systemd/system/certbot.service; static; vendor preset: enabled)
   Active: inactive (dead) since Fri 2018-10-12 12:40:15 CEST; 6h ago
     Docs: file:///usr/share/doc/python-certbot-doc/html/index.html
	   https://letsencrypt.readthedocs.io/en/latest/
  Process: 9767 ExecStart=/usr/bin/certbot -q renew (code=exited, status=0/SUCCESS)
 Main PID: 9767 (code=exited, status=0/SUCCESS)

changed renew command to run as user /lib/systemd/system/certbot.service

[Unit]
Description=Certbot
Documentation=file:///usr/share/doc/python-certbot-doc/html/index.html
Documentation=https://letsencrypt.readthedocs.io/en/latest/
[Service]
Type=oneshot
#ExecStart=/usr/bin/certbot -q renew
ExecStart=su - letsencrypt -s /bin/bash -c "certbot -q renew"
PrivateTmp=true

on upgrade system advises me if I would like to change cron part, systemd part is overridden without permission

6.5 letsencrypt wildcard certificate

stretch-backports installed, use last version of certbot as suggested by this guide -> src https://community.letsencrypt.org/t/wildcard-domain-step-by-step/58250/4

apt install -t stretch-backports certbot

this is the command I applied (spam email here for obvious reasons)

certbot certonly --email spam@cas.cat --agree-tos --server https://acme-v02.api.letsencrypt.org/directory --manual --preferred-challenges dns -d 'cas.cat,*.cas.cat'

put DNS record in /etc/bind/zones/db.cas.cat

_acme-challenge.cas.cat. IN TXT "f85AB-Q5AhexmVPTOKYSOR2Gh_36yB7y8Zk9Kf-WrOI"

Check before pressing enter. You have to do this step of changin TXT and verifying at least two times. Checked against both dns servers

$ dig -t txt _acme-challenge.cas.cat +short @ns1.cas.cat
$ dig -t txt _acme-challenge.cas.cat +short @ns6.gandi.net

src https://serverfault.com/questions/148721/linux-command-to-inspect-txt-records-of-a-domain

7 <2018-10-11 Thu> DNSSEC <2018-10-11 Thu 19:43>

Discussing the algorithm. DNSSEC tutorial uses NSEC3RSASHA1 (by default option with -3). And without specifying algorithm (by default) uses RSASHA1. Thanks to this serverfault Q&A I find RFC 6944, that says "It is believed that RSA/SHA-256 or RSA/SHA-512 algorithms will replace older algorithms (e.g., RSA/SHA-1) that have a perceived weakness." You can find the same recomendation reading SHA-1 on wikipedia. Conclusion, I'm going to use RSASHA256, also recommended in the comments of DNSSEC tutorial. Then I decided to switch to this other tutorial because looks simpler and solid.

cd /etc/bind
mkdir keys
cd keys
dnssec-keygen -a RSASHA256 -b 2048 -n ZONE cas.cat
dnssec-keygen -f KSK -a RSASHA256 -b 4096 -n ZONE cas.cat
chmod g+r *

In /etc/bind/named.conf.options file put:

// locate dnssec keys -> src https://wiki.debian.org/DNSSEC%20Howto%20for%20BIND%209.9+
key-directory "/etc/bind/keys/";

In /etc/bind/named.conf.options file add:

// dnssec -> src https://wiki.debian.org/DNSSEC%20Howto%20for%20BIND%209.9+
auto-dnssec maintain;
inline-signing yes;

Sign domain

rndc loadkeys cas.cat.
NSECSEED=$(printf "%04x%04x" $RANDOM $RANDOM)
rndc signing -nsec3param 1 0 10 $NSECSEED cas.cat.

As you might see, I did not follow exactly the debian's tutorial because I already set up zones in /etc/bind but then I realized that this will not work, I'm getting a permission error when looking at /var/log/daemon.log:

/etc/bind/db.cas.cat.signed.jnl: create: permission denied

To solve it in a proper way, I followed more closer the debian's tutorial: I moved the cas.cat's records to the zones directory that I created:

mkdir zones
chmod g+w zones
cd zones
mv cas.cat.zone zones

and changed path of the dns records to zones directory in /etc/bind/cas.cat.zone (in debian tutorial is /etc/bind/named.conf.local) file:

file "/etc/bind/zones/db.cas.cat";

and now we go to gandi and put the key

cat /etc/bind/keys/Kcas.cat.<strange numbers>.key

I used 257 (KSK)

I know is 257 because cas.cat. IN DNSKEY 257 3 8 after that comes the stream, that means probably is the public key-

8 <2018-10-09 Tue> Filling things for DNS and fail2ban

8.1 DNS SOA Expire Value <2018-10-09 Tue 00:40>

https://mxtoolbox.com/problem/dns/DNS-SOA-Expire-Value

RFC 1912 recommends 1209600 - 2419200 seconds (14-28 days).

changed SOA expiry to 2419200 in /etc/bind/db.cas.cat

8.2 SPF

in /etc/bind/db.exo.cat

@ 86400 IN TXT "v=spf1 mx ip4:51.68.173.168 -all"

src https://www.cyberciti.biz/faq/howto-bind-djbdns-spf-antispam-dns-configuration/

8.3 SMTP Valid Hostname <2018-10-09 Tue 00:44>

missing reverse resolution of DNS

https://mxtoolbox.com/problem/smtp/SMTP-Valid-Hostname

OK, got it. distinction between domain (cas.cat) and hostname (host.cas.cat). it must be a host, not a domain says https://serverfault.com/questions/799686/mxtoolbox-reverse-dns-is-not-a-valid-hostname

so I changed several things:

  • reverse from cas.cat to host.cas.cat (using hosting provider)
    • this is the record that hosting provider/isp does: 168.173.68.51.in-addr.arpa. IN PTR host.cas.cat.
  • add host.cas.cat as A dns entry (CNAME is not valid)
  • change host in postfix and its cert
  • change host in dovecot and its cert

8.4 DMARC missing <2018-10-09 Tue 00:54>

_dmarc.cas.cat. IN TXT "v=DMARC1; p=none"

8.5 DKIM missing <2018-10-09 Tue 00:54>

followed instructions of https://wiki.debian.org/opendkim?action=recall&rev=12

as an extra, at the end of /etc/opendkim.conf I added (I don't remember why):

# src https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-dkim-with-postfix-on-debian-wheezy
AutoRestart             Yes
AutoRestartRate         10/1h
Canonicalization        relaxed/simple
SignatureAlgorithm      rsa-sha256

/etc/postfix/dkim/mail.txt contains exactly how is the query for bind

8.6 fail2ban <2018-10-09 Tue 17:48>

let's protect a little bit the brute force attempt. Added this lines to /etc/fail2ban/jail.d/mail.conf

[postfix]
enabled = true
port     = smtp,465,submission
logpath  = %(postfix_log)s
backend  = %(postfix_backend)s

[postfix-rbl]
enabled = true
port     = smtp,465,submission
logpath  = %(postfix_log)s
backend  = %(postfix_backend)s
maxretry = 1

[postfix-sasl]
enabled = true
port     = smtp,465,submission,imap3,imaps,pop3,pop3s
# You might consider monitoring /var/log/mail.warn instead if you are
# running postfix since it would provide the same log lines at the
# "warn" level but overall at the smaller filesize.
logpath  = %(postfix_log)s
backend  = %(postfix_backend)s

[dovecot]
enabled = true
port    = pop3,pop3s,imap,imaps,submission,465,sieve
logpath = %(dovecot_log)s
backend = %(dovecot_backend)s

then restart service with service fail2ban restart and check if jails are active with fail2ban-client status

9 <2018-10-07 Sun> Hints from mxtoolbox.com

9.1 DNS local parent mismatch

error:

dig shows incomplete ns servers

$ dig ns cas.cat +short
ns1.cas.cat.

In file /etc/bind/db.cas.cat add

IN NS ns6.gandi.net.

after doing service bind9 restart ns are OK and mx tools confirm that there is no error

$ dig ns cas.cat +short
ns6.gandi.net.
ns1.cas.cat.

10 <2018-10-05 Fri> Official starting to note. And wow, doing server-sid notes <2018-10-05 Fri 21:14>

10.1 orgmode <2018-10-05 Fri 20:50>

Everything here (what you see) started after I installed orgmode

So here I am, doing apt install org-mode to do this kind of notes on server-side.

Sometimes I do notes, but in this case I want to make them public. The reason is:

  • I did not feel interesting to create another file.org in my notes-system for such a specific thing (I prefer to integrate knowledge in bigger systems/notes, that's what I do anyway).
  • Seems that now this is so conscious task but when it gets stable is going to be forgotten. Let's prevent that, at least with this
  • My try to mess internet with (1) shitty English (2) crappy life storytelling. lol
  • Yay! Unknown people is read thiiis! Halooooooooo

10.2 css <2018-10-05 Fri 21:38>

davidam.com inspired me long time ago that I could make notes a somehow amazing page render, today I implement here! thanks!

11 <2018-10-04 Thu> I can receive emails but I cannot send them!

Configured postfix and dovecot inspired and guided by some people that helped me to configure a "corporate" mail server

12 <2018-09-26 Wed> basic certbot

modify certbot so is not running as root

0 */12 * * * letsencrypt test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && su - letsencrypt -s /bin/bash -c "certbot -q renew"

13 <2018-09-19 Wed> OK, let's move on <2018-10-05 Fri 21:05>

Given your personal situation and circunstances you have no "permanent" place for a webmail, but hey, you can rent a server. Found something for 3€/month at ovh. Looks like with this prize you have very interesting server requirements for a mail server!

14 <2018-07-26 Thu> I renewed a domain <2018-10-05 Fri 21:03>

2018-8 is here and wow, and you did nothing just pay like that people that pays the gym every month

15 <2017-08> I reserved a domain <2018-10-05 Fri 21:00>

I bought this domain on 2017-8. I said "I want so much to do my selfhosted mail server"

Author: root

Created: 2019-03-18 Mon 12:45

Validate