pmeerw's blog

Sat, 09 Feb 2019

Email security testing, very straightforward, also checks web-server security.

My Email Communications Security Assessment (MECSA), by the European Commission; has postfix setup guide. has a friendly interface and gives suggestions.

posted at: 16:51 | path: /rant | permanent link

Wed, 06 Feb 2019

Linus cares about my DKIM setup :-)

Linus Torvalds points out on LKML that my DKIM setup is broken...

Date: Wed, 6 Feb 2019 08:27:25
From: Linus Torvalds <>
To: Peter Meerwald-Stadler <>
Cc: lkml <>
Subject: Re: [PATCH v3 1/4] staging: iio: ad7780: add gain & filter gpio support


 this email was marked as spam for me (and probably others) because of
this DKIM signature:

   DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple;; s=mail;

where the problem is that when the message goes through the mailing list machinery, the header whitespace will be


posted at: 17:20 | path: /rant | permanent link

Mon, 04 Feb 2019

Setting up DANE

DANE (RFC 6698) basically allows to publish the hash of server certificate as a TLSA record in DNS, signed with DNSSEC. A client can validate that a server's TLS certificate is owned by the same entity which controls DNSSEC signed zone.

The idea is to add a new DNS record of type TLSA to the zone, in particular a Certificate Usage DANE-EE (3).

25._tcp.mail IN TLSA 3 1 1 2c788de8eaf09f6b1f5a704a5e0718206c668f00dfca8f8112608dc25571553c
In the example, 3 is the usage (DANE-EE), 1 the selector (subject public key), 1 the matching type (SHA-256). This for my MX record,, port 25 (wildcard port number * would also be possible). The hash can be conveniently generated (taken from Viktor Dukhovni's tlsagen script):
openssl x509 -in /etc/letsencrypt/live/ -noout -pubkey | \
    openssl pkey -pubin -outform DER | \
    openssl dgst -sha256 -binary | \
    hexdump -ve '/1 "%02x"'

Since my server certificate is issued by Let's Encrypt, the certificate is renewed every 90 days or so. Because DANE essentially puts the certificate's public key into DNS, the DNS record needs to be updated whenever the key changes. Luckily, recent letsencrypt scripts (since >= 0.25.0, June 2018) support the argument renew --reuse-key, so the same keys are reused. The certificate is renewed, but not the underlying keys. Here is my weekly cron job script /etc/cron.weekly/letsencrypt:

letsencrypt renew --reuse-key --pre-hook "systemctl stop apache2" --post-hook "systemctl start apache2"
res=$(find /etc/letsencrypt/live/ -type l -mtime -1)
if [ -n "$res" ]; then
  echo "letsencrypt: new cert"
  systemctl restart apache2
  systemctl restart postfix
  systemctl restart dovecot
  echo "letsencrypt: nothing to do"
Weirdly, the documentation is to be found with certbot -h automation, not certbot -h renew.

To verify, use the DANE SMTP validator (, see the results for

posted at: 00:24 | path: /configuration | permanent link

Sun, 03 Feb 2019

Security checkup for web and email: has a nice & tidy check for IPv6, TLS, HTTPS, DNSSEC, DANE (DNS-based Authentication of Named Entities), DMARC (Domain-based Message Authentication, Reporting & Conformance), DKIM (DomainKeys Identified Mail), SPF (Sender Policy Framework) on web and mail servers.

See the results for web and email.

posted at: 23:44 | path: /configuration | permanent link

Various security updates

  1. Enable HTTP Strict Transport Security (HSTS), easy: simply enable Apache headers module, a2enmod headers, and add Header add Strict-Transport-Security: "max-age=15768000;includeSubdomains"; yeah, finally A+ on SSL Labs!
  2. Permanent redirect from HTTP to HTTPS using Apache rewrite module:
    RewriteEngine on
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=permanent,L]
  3. Turn HTTP compression off in Apache: SetEnv no-gzip 1
  4. Enable DANE (RFC 6698) in postfix: check that the DNS resolver on the mail server supports DNSSEC (e.g. use dig and see if the ad flag is present), then set the following in /etc/postfix/
  5. Update postfix cipher suites to disable insecure ciphers in /etc/postfix/
    smtp_tls_ciphers = high
    smtpd_tls_ciphers = high
    smtp_tls_mandatory_ciphers = high
    smtpd_tls_mandatory_ciphers = high
    smtpd_tls_exclude_ciphers = aNULL
    smtp_tls_exclude_ciphers = aNULL

posted at: 23:33 | path: /configuration | permanent link

Made with PyBlosxom