Transport security for HTTP/2 protocol with Nginx
With Google sunsetting the SPDY protocol, and broad support for HTTP/2 shipping with most modern browsers, I began investigating moving our SPDY support over to HTTP/2.
Nginx recently released official support for HTTP/2 with the mainline repository version 1.9.5. While upgrading to the new release and enabling the http2
module we ran into an issue with transport security, as reported by Google Chrome:
# google chrome client error
ERR_SPDY_INADEQUATE_TRANSPORT_SECURITY
# or more generically
INADEQUATE_SECURITY (0xc)
According to the HTTP/2 specification, over TLS 1.2 HTTP/2 SHOULD NOT use any of the cipher suites that are listed in the cipher suite black list, found here.
The following settings (with changes to the ssl_ciphers
directive) addressed the transport security issue reported by the browser.
server {
listen 9443 ssl http2 proxy_protocol;
port_in_redirect off;
real_ip_header proxy_protocol;
set_real_ip_from 10.0.0.0/16;
server_name acme.com www.acme.com;
ssl on;
ssl_certificate /path/to/full-chain.pem;
ssl_certificate_key /path/to/pivate-key.pem;
# disable unsupported ciphers
ssl_ciphers AESGCM:HIGH:!aNULL:!MD5;
# ssl optimizations
ssl_session_cache shared:SSL:30m;
ssl_session_timeout 30m;
add_header Strict-Transport-Security "max-age=31536000";
}
In the example, we are also opting into the HTTP Strict Transport Security (HSTS) enhancement to prevent client communications from being sent over standard HTTP. The proxy_protocol
configuration in use by the load balancer (ELB) continues to work as expected without any changes. You can read more about using proxy protocol with Nginx here.