Last week I upped the security of this site. Since it is generated with pelican it is generated to plain simple static HTML. So serving the pages relies on DNS, TLS and HTTP. Therefore I have to build the security from the ground up.
Update 2019-02-28: Server security update
Step one: DNSSec and CAA
Everybody viewing the site has to resolve the name estada.ch
.
The system used to do that is DNS.
Sadly it is insecure by default.
Lucky us, there is a well tested solution: DNSSec (How it works)! Everyday more and more ISPs use it to verify the records requested by your operating system.
Unfortunately, the browsers do not use it to check certificates. Certificates accepted by browsers like Firefox still need to be registered with a CA. As history has shown some CAs made bad mistakes.
To request a certificate everyone needs to go through some sort of validation. With the free Let's Encrypt the checks are automated and DNSSec helps to ensure only my systems are able to pass these checks.
However if a CA was not checkin DNSSec it could resolve to a distrusted system if a well organized attacker layed prepared for it. To prevent that from happening there is a new DNS record type: CAA.
The CAA records allow an administrator to limit the CAs from which he/she want's to get a certificate and who they should inform if there was an attempt to get a certificate from a unauthorized CA.
Step two: TLS, HTTP and HTTP2
After all this preparation time for a bit of eye-candy.
I removed the www
with nginx and a permanent redirect.
Another positive benefit is, search engines only index the page once.
This helps with focusing the traffic and simplifies the logging.
server {
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/letsencrypt/live/estada.ch/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/estada.ch/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
server_name www.estada.ch;
rewrite ^(.*) https://estada.ch$1 permanent;
}
On to the long-term improvements.
Enabling HTTP/2 with nginx on Debian 9 is easy, simply add http2
to the listen
line.
Still the speed benefit is very variable.
Sometimes the pages would load faster, sometimes slower.
In conclusion I will enable it for IPv6 for now and see how it goes.
To tell the browsers to use TLS encryption whenever it tries to connects to estada.ch
there is HSTS.
I used this on the domain for over a year without any issue.
Today I extended to include all my subdomains and add the domain to the browsers whitelist with includeSubDomains; preload
.
The new CSP is a huge plus and prevents the site from being embedded with another site via an iframe: default-src 'self'; img-src 'self' data:; frame-ancestors 'none'; object-src 'none';
New Security Headers
The Referrer-Policy gives control over the metadata of outgoing requests. At this time I decided to allow the base referrer on outgoing clicks if the target has HTTPS enabled.
The other is Feature-Policy that allows to enable or disable modern features.
Sadly I was unable to find an easy way to disable everything.
So I decided to allow fullscreen
and hope it blocks everything else.
404 catch all
Finally, every time a document was moved visitors would see a plain 404 error page. From now on the server will display a templated error page.
server {
listen 443 ssl;
listen [::]:443 ssl http2;
server_name estada.ch;
# certs sent to the client in SERVER HELLO are concatenated in ssl_certificate
ssl_certificate /etc/letsencrypt/live/estada.ch/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/estada.ch/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# modern configuration. tweak to your needs.
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:HIGH:!aNULL:!MD5';
ssl_prefer_server_ciphers on;
# HSTS (ngx_http_headers_module is required) (31536000 seconds = 12 months)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
add_header Content-Security-Policy "default-src 'self'; img-src 'self' data:; frame-ancestors 'none'; object-src 'none'";
add_header Referrer-Policy "origin-when-cross-origin";
add_header Feature-Policy "fullscreen 'self'";
add_header X-Content-Type-Options "nosniff";
# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
## verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /etc/letsencrypt/live/data.estada.ch/chain.pem;
root /srv/http/estada.ch/htdocs;
location / {
error_page 404 /404.html;
}
}
Update 2018-11-13
I was asked "Why not disable TLS to gain even more speed?" The simple answer is, there is no real speedup as is TLS fast yet shows.
Update 2019-01-02
Added add_header X-Content-Type-Options "nosniff";
to prevent mistaken content types.
I used the mozilla configuration generator for the initial config and secured it from there on.
Reduced ssl_session_cache
time from 50 to 10 minutes.
Update 2019-02-28
New post Server security update.