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
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