HTTP Public Key Pinning

Centmin Mod 1.2.3-eva2000.09 beta01 added support to centmin.sh menu option 2 and /usr/bin/nv cmd line tool for the add Nginx vhost site generator for HTTP Public Key Pinning (RFC7469) and the automatic generation of both primary and secondary backup private keys and the automated extraction of base64 encoded hashed pins of the respective private keys' SPKI - Subject Public Key Information fields. The primary and secondary back base64 encoded pin hashes are saved to files in your /usr/local/nginx/conf/ssl/yourdomain.com directory.

The Public Key Pinning Extension for HTTP (HPKP) is a security feature that tells a web client to associate a specific cryptographic public key with a certain web server to prevent MITM attacks with forged certificates.

To ensure the authenticity of a server's public key used in TLS sessions, this public key is wrapped into a X.509 certificate which is usually signed by a certificate authority (CA). Web clients such as browsers trust a lot of these CAs, which can all create certificates for arbitrary domain names. If an attacker is able to compromise a single CA, he can perform MITM attacks on various TLS connections. HPKP can circumvent this threat for the HTTPS protocol by telling the client which public key belongs to a certain web server.

HPKP is a Trust on First Use (TOFU) technique. The first time a web server tells a client via a special HTTP header which public keys belong to it, the client stores this information for a given period of time. When the client visits the server again, it expects a certificate containing a public key whose fingerprint is already known via HPKP. If the server delivers an unknown public key, the client should present a warning to the user.

Notes

The current specification requires including a second pin for a backup key which isn't yet used in production. This allows for changing the server's public key without breaking accessibility for clients that have already noted the pins. This is important for example when the former key gets compromised.

Risks & Security Considerations

Safe guarding the backup private key is important - from https://tools.ietf.org/html/draft-ietf-websec-key-pinning-21#section-4. Also not all security violations are reported - Controversial HTTP Public Key Pinning bypass?.

Centmin Mod Nginx Automated Vhost Setup

Below is an illustrated example for adding a new Nginx vhost domain - newdomain2.com and auto generating the self-signed SSL certificate, primary and secondary backup CSR and private keys and auto generating the HTTP Public Key Pinning hashes and giving you the Nginx add_header needed. This add_header is also automatically inserted into the SSL version of your Nginx vhost but commented out by default i.e. within /usr/local/nginx/conf/conf.d/newdomain2.com.ssl.conf.

HTTP Public Key Pinning Header for Nginx

The example Nginx vhost SSL config for newdomain2.com generated both the primary and backup base64 encoded pin hashes and the add_header needed. This is auto inserted into /usr/local/nginx/conf/conf.d/newdomain2.com.ssl.conf but is commented out by default.

for 7 days max-age including subdomains. Read Using includeSubDomains Safely.

add_header Public-Key-Pins 'pin-sha256="gIm5JM8lPc+uiz995GgIR/9lmo8dkDZ4X3VQJAUvN0s="; pin-sha256="ALeqbO2k1tzkLG3Z0DaQW2QgC8MG9tQZD2sNHVW08GM="; max-age=604800; includeSubDomains';

for 7 days max-age excluding subdomains

add_header Public-Key-Pins 'pin-sha256="gIm5JM8lPc+uiz995GgIR/9lmo8dkDZ4X3VQJAUvN0s="; pin-sha256="ALeqbO2k1tzkLG3Z0DaQW2QgC8MG9tQZD2sNHVW08GM="; max-age=604800';

With HTTP Public Key Pinning enabled in /usr/local/nginx/conf/conf.d/newdomain2.com.ssl.conf

curl -Ik https://newdomain2.com
HTTP/1.1 200 OK
Date: Thu, 27 Aug 2015 09:53:32 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 1368
Last-Modified: Thu, 27 Aug 2015 08:49:21 GMT
Connection: keep-alive
ETag: "55decf11-558"
Server: nginx centminmod
Expires: Fri, 28 Aug 2015 09:53:32 GMT
Cache-Control: max-age=86400
Public-Key-Pins: pin-sha256="gIm5JM8lPc+uiz995GgIR/9lmo8dkDZ4X3VQJAUvN0s="; pin-sha256="ALeqbO2k1tzkLG3Z0DaQW2QgC8MG9tQZD2sNHVW08GM="; max-age=604800
Cache-Control: public, must-revalidate, proxy-revalidate
Accept-Ranges: bytes

Nginx HTTP/2 patched

Output from command /usr/bin/nv cmd line tool or via centmin.sh menu option 2 to create a new Nginx vhost called newdomain2.com with self-signed SSL ( -s y) enabled and Pure-FTPD virtual ftp username = ftpuser02.

nv -d /newdomain2.com -s y -u ftpuser02

nv

Usage: /usr/bin/nv [-d yourdomain.com] [-s y|n] [-u ftpusername]

  -d  yourdomain.com or subdomain.yourdomain.com
  -s  ssl self-signed create = y or n
  -u  your FTP username

  example:

  /usr/bin/nv -d yourdomain.com -s y -u ftpusername

Centmin Mod Nginx vhost generation with SSL and HTTP Public Key Pinning support