--- layout: post title: Hardening TLS webserver to be 100% with internet.nl date: 2021-04-28 14:53 author: rick categories: security --- Following the SIDN blogposts on [implementing SPF, DKIM and DMARC in PostFix](https://www.sidn.nl/en/news-and-blogs/hands-on-implementing-spf-dkim-and-dmarc-in-postfix) and [implementing DANE in Postfix](https://www.sidn.nl/en/news-and-blogs/hands-on-implementing-dane-in-postfix) I got myself interested in getting two times an 100% score at the testing service [internet.nl](https://internet.nl). The first badge is earned for mail services and secondly for web services. Unfortually I cannot find a guide available which implements the [IT Security Guidelines for Transport Layer Security (TLS) from National Cyber Security Centre (NCSC)](https://english.ncsc.nl/binaries/ncsc-en/documents/publications/2021/january/19/it-security-guidelines-for-transport-layer-security-2.1/IT+Security+Guidelines+for+Transport+Layer+Security+v2.1.pdf) within Apache HTTPD 2.4, which is my default webserver of choice. I went for 'good'-ish instead of 'suffient', since I can manage the fall-out if stuff breaks in unexpected ways. Alter change `ssl_module` settings, I am running FreeBSD www/apache24, so mine are found at `/usr/local/etc/apache24/extra/httpd-ssl.conf`: ``` SSLCipherSuite 'HIGH:-EXP:-LOW:-MEDIUM:-aNULL:-eNULL:-SRP:-PSK:-kDH:-ADH:-AECDH:-kRSA:-DSS:-RC4:-DES:-IDEA:-SEED:-ARIA:-AESCCM8:-3DES:-MD5:-DH' SSLProxyCipherSuite 'HIGH:-EXP:-LOW:-MEDIUM:-aNULL:-eNULL:-SRP:-PSK:-kDH:-ADH:-AECDH:-kRSA:-DSS:-RC4:-DES:-IDEA:-SEED:-ARIA:-AESCCM8:-3DES:-MD5:-DH' SSLHonorCipherOrder on SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 SSLProxyProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 SSLPassPhraseDialog builtin SSLSessionCache "shmcb:/var/run/ssl_scache(512000)" SSLSessionCacheTimeout 300 SSLUseStapling On SSLStaplingCache "shmcb:/var/run/ssl_stapling(32768)" SSLStaplingStandardCacheTimeout 3600 SSLStaplingErrorCacheTimeout 600 ``` The 'magic' value posted at SSLCipherSuite is [interpreted](https://www.openssl.org/docs/man1.0.2/man1/ciphers.html) by openSSL to a list of available ciphers to use. For example: ``` openssl ciphers -v 'HIGH:-EXP:-LOW:-MEDIUM:-aNULL:-eNULL:-SRP:-PSK:-kDH:-ADH:-AECDH:-kRSA:-DSS:-RC4:-DES:-IDEA:-SEED:-ARIA:-AESCCM8:-3DES:-MD5:-DH' TLS_AES_256_GCM_SHA384 TLSv1.3 Kx=any Au=any Enc=AESGCM(256) Mac=AEAD TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any Au=any Enc=CHACHA20/POLY1305(256) Mac=AEAD TLS_AES_128_GCM_SHA256 TLSv1.3 Kx=any Au=any Enc=AESGCM(128) Mac=AEAD ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(256) Mac=AEAD ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=ECDSA Enc=CHACHA20/POLY1305(256) Mac=AEAD ECDHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH Au=RSA Enc=CHACHA20/POLY1305(256) Mac=AEAD ECDHE-ECDSA-AES256-CCM TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESCCM(256) Mac=AEAD ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD ECDHE-ECDSA-AES128-CCM TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESCCM(128) Mac=AEAD ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA384 ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA384 ECDHE-ECDSA-CAMELLIA256-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=Camellia(256) Mac=SHA384 ECDHE-RSA-CAMELLIA256-SHA384 TLSv1.2 Kx=ECDH Au=RSA Enc=Camellia(256) Mac=SHA384 ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA256 ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AES(128) Mac=SHA256 ECDHE-ECDSA-CAMELLIA128-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=Camellia(128) Mac=SHA256 ECDHE-RSA-CAMELLIA128-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=Camellia(128) Mac=SHA256 ECDHE-ECDSA-AES256-SHA TLSv1 Kx=ECDH Au=ECDSA Enc=AES(256) Mac=SHA1 ECDHE-RSA-AES256-SHA TLSv1 Kx=ECDH Au=RSA Enc=AES(256) Mac=SHA1 ECDHE-ECDSA-AES128-SHA TLSv1 Kx=ECDH Au=ECDSA Enc=AES(128) Mac=SHA1 ``` The optional features of hardening websites was a bit more troublesome. Take a good read at the documentation at Mozilla Developer Network (MDN) of [Access-Control-Allow-Origin](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin), [X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options), [X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options), [X-Content-Type-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options), [Content-Security-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy) and [Referrer-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy). Especially `Content-Security-Policy` is troublesome since it disallows inline javascripts, which broke some unexpected functionality. To enable include snippet in VirtualHost entry or `httpd.conf` root if you like to have it enabled globally. ``` # Make sure headers_module is loaded/enabled Header always set Access-Control-Allow-Origin "*" Header always set X-Frame-Options "DENY" Header always set X-Content-Type-Options "nosniff" Header always set Content-Security-Policy "default-src 'self'; frame-ancestors 'self'" Header always set Referrer-Policy "same-origin" ``` Restart your Apache HTTPD webserver and get yourself tested at [internet.nl](https://internet.nl/).