{"id":123,"date":"2023-01-31T12:10:44","date_gmt":"2023-01-31T20:10:44","guid":{"rendered":"https:\/\/cloudinsidr.com\/content\/?p=123"},"modified":"2023-01-31T12:11:44","modified_gmt":"2023-01-31T20:11:44","slug":"how-to-activate-http2-with-ssltls-encryption-in-nginx-for-secure-connections","status":"publish","type":"post","link":"https:\/\/www.cloudinsidr.com\/content\/how-to-activate-http2-with-ssltls-encryption-in-nginx-for-secure-connections\/","title":{"rendered":"How to Activate HTTP\/2 with TLS 1.3 Encryption in NGINX for Secure Connections without a Performance Penalty"},"content":{"rendered":"<p>&nbsp;<\/p>\n<p>Are you ready for a better security with no performance penalty? Are you ready for a\u00a0performance bump that can take you places in search engine land? In other words: now that HTTP\/2 reached\u00a0production-grade maturity, nothing should hold you back.<\/p>\n<p>The IoT\u00a0\u00a0revolution will make sure that <em><strong>only the paranoid survive<\/strong><\/em>.<\/p>\n<p><!--more--><\/p>\n<p>In order to upgrade your server to HTTP\/2 and encrypted connections, you will need:<\/p>\n<ul>\n<li>a web server version that supports the protocol (for NGINX, version 1.9.5 or above);<\/li>\n<li>an SSL certificate and key from a respected CA (doesn&#8217;t need to be pricey but has to be SHA-2 if you are serious about it);<\/li>\n<li>a couple of minutes or hours\u00a0to compute your own\u00a0Diffie Hellman group<\/li>\n<li>a few\u00a0battle-tested\u00a0configuration options.<\/li>\n<\/ul>\n<p>Now focus, please.<\/p>\n<h3>Step 1. Activate HTTP\/2<\/h3>\n<p>In Nginx&#8217;s site configuration file, make sure you have this in your server block:<\/p>\n<pre>server {\r\n listen 80;\r\n listen 443 ssl http2;<\/pre>\n<p>The http2 directive will do the trick. The HTTP\/2 spec does not require encryption, but browsers do.<\/p>\n<p>Once this is in place, you have to configure NGINX to handle\u00a0encrypted connections.<\/p>\n<h3>Step 2. Obtain and install an SHA-2 certificate from a respectable CA<\/h3>\n<p>Except for testing (in which case a self-signed certificate is fine), you will have to shell out some pocket change to obtain an SSL certificate from a respectable\u00a0CA (would you like some recommendations? please comment). Whatever you decide to do, make sure the CA doesn&#8217;t issue you an SHA-1 certificate. These are worse than worthless: they have been proven to be susceptible to collision attacks (like the FLAME malware that attacked MD5).<\/p>\n<p>Save the certificate and the key\u00a0on your server and make sure it is owned by root and read-accessible to the group\u00a0NGINX:<\/p>\n<pre>chown root:nginx CA-issued.*<\/pre>\n<h3>Step 3. Point\u00a0your server to your\u00a0SSL certificate and key files<\/h3>\n<p>In the site configuration file in NGINX, point the server to your SHA-2 certificate and the key file:<\/p>\n<pre>ssl_certificate \/etc\/nginx\/CA-issued\/CA-issued.cert;\r\nssl_certificate_key \/etc\/nginx\/CA-issued\/CA-issued.key;<\/pre>\n<h3>Step 4. Specify communications\u00a0protocols for encrypted connections<\/h3>\n<p>If you are serious about security, you should not enable SSL (it&#8217;s been compromised) nor allow a downgrade to TLS 1.0 or TLS 1.1. The only acceptable protocols are TLS 1.3 and TLS 1.2.<\/p>\n<p>Enter this into the configuration\u00a0file of your site in NGINX:<\/p>\n<pre>ssl_protocols TLSv1.3 TLSv1.2;<\/pre>\n<h3>Step 5. Specify cipher suites using ECDHE: (Ephemeral) Elliptic-Curve Diffie-Hellman key exchange and prohibit a compromise<\/h3>\n<p>This directive allows you to specify ciphers in NGINX:<\/p>\n<p>ssl_ciphers &#8216;TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH&#8217;;<\/p>\n<p>Now the question is, how do you figure out which cipher suites are acceptable? Mozilla offers a helpful <a href=\"https:\/\/mozilla.github.io\/server-side-tls\/ssl-config-generator\/\" target=\"_blank\" rel=\"noopener noreferrer\">ssl-config-generator<\/a>\u00a0that will give you recommended (option &#8216;modern profile&#8217;) and\/or supported (&#8216;old profile&#8217;) ciphers for any given version of your web server and OpenSSL.<\/p>\n<p>Make sure you deploy\u00a0(Ephemeral) Elliptic-Curve Diffie-Hellman (ECDHE-) variants and NOT\u00a0the original, finite field, Diffie-Hellman (DHE-). Tweak Mozilla&#8217;s &#8216;modern profile&#8217; output of the NGINX\u00a0ssl_ciphers parameter to that end if you want to be paranoid (why wouldn&#8217;t you want to? no valid\u00a0reasons).<\/p>\n<p>Tell the server to override any preferences the client may report as own by setting\u00a0this parameter:<\/p>\n<pre>ssl_prefer_server_ciphers on;<\/pre>\n<p>Last but not least, specify the curve type. Chose a modern ECDH (elliptic curve DH) in OpenSSL 1.1.1:<\/p>\n<pre>ssl_ecdh_curve secp384r1;<\/pre>\n<h3>Step 6. Replace\u00a0your server&#8217;s Diffie-Hellman group<\/h3>\n<p>By default, many web servers use a weak Diffie-Hellman group that has been\u00a0broken by rogue nation states and cannot be\u00a0considered safe by any stretch of imagination. Do yourself a favor and replace it asap.<\/p>\n<figure id=\"attachment_266\" aria-describedby=\"caption-attachment-266\" style=\"width: 1045px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/cloudinsidr.com\/content\/wp-content\/uploads\/2015\/12\/Diffie_Hellman.jpg\" rel=\"attachment wp-att-266\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-266 size-full\" src=\"https:\/\/cloudinsidr.com\/content\/wp-content\/uploads\/2015\/12\/Diffie_Hellman.jpg\" alt=\"Testing a web server for Diffie Hellman\" width=\"1045\" height=\"511\" srcset=\"https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2015\/12\/Diffie_Hellman.jpg 1045w, https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2015\/12\/Diffie_Hellman-600x293.jpg 600w, https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2015\/12\/Diffie_Hellman-300x147.jpg 300w, https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2015\/12\/Diffie_Hellman-768x376.jpg 768w, https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2015\/12\/Diffie_Hellman-1024x501.jpg 1024w\" sizes=\"(max-width: 1045px) 100vw, 1045px\" \/><\/a><figcaption id=\"caption-attachment-266\" class=\"wp-caption-text\">Testing a web server for Diffie Hellman (weakdh.org): a compromised certificate is the last thing you want<\/figcaption><\/figure>\n<p style=\"padding-left: 30px;\"><em>(If you need a crypto expert to scare you into revving\u00a0up security, so be it: glance over &#8220;<a href=\"https:\/\/www.schneier.com\/blog\/archives\/2015\/10\/breaking_diffie.html\" target=\"_blank\" rel=\"noopener noreferrer\">Breaking Diffie-Hellman with Massive Precomputation (Again)<\/a>&#8221; by Bruce Schneier\u00a0and you&#8217;ll gladly read\u00a0this\u00a0guide on <a href=\"https:\/\/www.eff.org\/deeplinks\/2015\/10\/how-to-protect-yourself-from-nsa-attacks-1024-bit-DH\" target=\"_blank\" rel=\"noopener noreferrer\">how to protect yourself as the end user<\/a>\u00a0and how to protect your end users by <a href=\"https:\/\/stribika.github.io\/2015\/01\/04\/secure-secure-shell.html\" target=\"_blank\" rel=\"noopener noreferrer\">securing your SSH<\/a>, too.)<\/em><\/p>\n<p>In order to generate your new group, you can use openssl directly on your server (ask for a key no shorter than 4096):<\/p>\n<pre>openssl dhparam -out dhparams.pem 4096 &amp; bg<\/pre>\n<p>(The process should take between a few\u00a0minutes and a few\u00a0hours, depending on your system.) Change the permissions to the resulting key file to allow your server\u00a0user&#8217;s group read access only (the owner remains root):<\/p>\n<pre>chown root:nginx\u00a0dhparams.pem<\/pre>\n<p>In the\u00a0site configuration file in NGINX, point the web server to your shiny new Diffie-Hellman key:<\/p>\n<pre> # Diffie-Hellman parameter for DHE cipher suites\r\n ssl_dhparam \/etc\/nginx\/dhparams-4096.pem;<\/pre>\n<p>At this point, you are done. Save the configuration file and restart your server for the changes to take effect:<\/p>\n<pre>service nginx restart<\/pre>\n<h3>Step 7. Disallow\u00a0unencrypted HTTP by enabling HSTS<\/h3>\n<p><strong>HSTS<\/strong> (<em>HTTP Strict Transport Security<\/em>) is a web security policy mechanism designed to help protect HTTPS websites against <strong>downgrade attacks<\/strong> and <strong>cookie hijacking<\/strong> (RFC 6797). With HSTS, the web server sends an HTTP response header field named &#8220;<em>Strict-Transport-Security<\/em>&#8220;, which tells the client\u00a0to interact using HTTPS only.<\/p>\n<p><strong>This only works with compliant user agents,<\/strong>\u00a0however, the setting will\u00a0help protect legitimate visitors but will not\u00a0protect your site from malicious HTTP communications.\u00a0For this reason, you may want to redirect HTTP requests using a server directive (to that end, you will have to temporarily disable HSTS in order to verify that your redirects are\u00a0actually working).<\/p>\n<p>In NGINX, enter this into the configuration file of each site within the server block:<\/p>\n<p>&nbsp;<\/p>\n<pre># HSTS (requires ngx_http_headers_module)\u00a0\r\n# 15768000 seconds = 6 months\r\n# in seconds, 365 days, including subdomains\r\n# do NOT use max-age of zero; it will disable the policy!\r\nadd_header Strict-Transport-Security \"max-age=31536000; includeSubDomains; always\";<\/pre>\n<p>In order to\u00a0enforce https, enter this in the location block (rewrites are not recommended):<\/p>\n<pre> return 301 https:\/\/www.your-domain.tld\/$request_uri;<\/pre>\n<h3>Step 8. Stay vigilant (in perpetuity!)<\/h3>\n<p>Now head over to the <a href=\"https:\/\/www.ssllabs.com\/ssltest\/analyze.html?\" target=\"_blank\" rel=\"noopener noreferrer\">SSL scanner by Qualys SSL Labs<\/a> and run a test on each one of your domains to make sure you haven&#8217;t overlooked anything.<\/p>\n<p><a title=\"Large Rectangle (336 x 280)\" href=\"https:\/\/www.thesslstore.com\/symantec.aspx?btoken=Ds82EweFB%2fXSIm6zhK8bvqBUEab%2bpo4rXpiJfosbOA0%3d\" rel=\"nofollow\"><img decoding=\"async\" src=\"https:\/\/affiliate.thesslstore.com\/Banner.ashx?token=Ds82EweFB%2fXSIm6zhK8bvqBUEab%2bpo4rXpiJfosbOA0%3d\" alt=\"Large Rectangle (336 x 280)\" \/><\/a><\/p>\n<p>Feeling accomplished yet? Well,\u00a0the arms race never ends. Feel free to pat yourself firmly on the shoulder but please remember: ongoing vigilance is not just a virtue in cybersecurity, it is a prerequisite for survival!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Are you ready for a better security with no performance penalty? Are you ready for a\u00a0performance bump that can take you places in search engine land? In other words: now that HTTP\/2 reached\u00a0production-grade maturity, nothing should hold you back. The IoT\u00a0\u00a0revolution will make sure that only the paranoid survive.<\/p>\n","protected":false},"author":101012,"featured_media":2901,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","footnotes":""},"categories":[17,33,6],"tags":[47,40,46,43,49,48,7,44,45,38,37],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v14.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>How to Activate HTTP\/2 with TLS 1.3 Encryption in NGINX for Secure Connections without a Performance Penalty - CloudInsidr<\/title>\n<meta name=\"robots\" content=\"index, follow\" \/>\n<meta name=\"googlebot\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<meta name=\"bingbot\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.cloudinsidr.com\/content\/how-to-activate-http2-with-ssltls-encryption-in-nginx-for-secure-connections\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Activate HTTP\/2 with TLS 1.3 Encryption in NGINX for Secure Connections without a Performance Penalty - CloudInsidr\" \/>\n<meta property=\"og:description\" content=\"&nbsp; Are you ready for a better security with no performance penalty? Are you ready for a\u00a0performance bump that can take you places in search engine land? In other words: now that HTTP\/2 reached\u00a0production-grade maturity, nothing should hold you back. The IoT\u00a0\u00a0revolution will make sure that only the paranoid survive.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.cloudinsidr.com\/content\/how-to-activate-http2-with-ssltls-encryption-in-nginx-for-secure-connections\/\" \/>\n<meta property=\"og:site_name\" content=\"CloudInsidr\" \/>\n<meta property=\"article:published_time\" content=\"2023-01-31T20:10:44+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-01-31T20:11:44+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2018\/10\/CloudInsidr_SSLLabs_2023-01-31.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1878\" \/>\n\t<meta property=\"og:image:height\" content=\"1340\" \/>\n<meta name=\"twitter:card\" content=\"summary\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.cloudinsidr.com\/content\/#website\",\"url\":\"https:\/\/www.cloudinsidr.com\/content\/\",\"name\":\"CloudInsidr\",\"description\":\"Cyber security, infotech\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/www.cloudinsidr.com\/content\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/www.cloudinsidr.com\/content\/how-to-activate-http2-with-ssltls-encryption-in-nginx-for-secure-connections\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/www.cloudinsidr.com\/content\/wp-content\/uploads\/2018\/10\/CloudInsidr_SSLLabs_2023-01-31.png\",\"width\":1878,\"height\":1340},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.cloudinsidr.com\/content\/how-to-activate-http2-with-ssltls-encryption-in-nginx-for-secure-connections\/#webpage\",\"url\":\"https:\/\/www.cloudinsidr.com\/content\/how-to-activate-http2-with-ssltls-encryption-in-nginx-for-secure-connections\/\",\"name\":\"How to Activate HTTP\/2 with TLS 1.3 Encryption in NGINX for Secure Connections without a Performance Penalty - CloudInsidr\",\"isPartOf\":{\"@id\":\"https:\/\/www.cloudinsidr.com\/content\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.cloudinsidr.com\/content\/how-to-activate-http2-with-ssltls-encryption-in-nginx-for-secure-connections\/#primaryimage\"},\"datePublished\":\"2023-01-31T20:10:44+00:00\",\"dateModified\":\"2023-01-31T20:11:44+00:00\",\"author\":{\"@id\":\"https:\/\/www.cloudinsidr.com\/content\/#\/schema\/person\/73723b2da71b6d515d17ca593ea5dc68\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.cloudinsidr.com\/content\/how-to-activate-http2-with-ssltls-encryption-in-nginx-for-secure-connections\/\"]}]},{\"@type\":[\"Person\"],\"@id\":\"https:\/\/www.cloudinsidr.com\/content\/#\/schema\/person\/73723b2da71b6d515d17ca593ea5dc68\",\"name\":\"Filipe Martins\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/www.cloudinsidr.com\/content\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/dbac033b4d26da8ca1fbde233e49c8dc?s=96&d=mm&r=g\",\"caption\":\"Filipe Martins\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/posts\/123"}],"collection":[{"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/users\/101012"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/comments?post=123"}],"version-history":[{"count":58,"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/posts\/123\/revisions"}],"predecessor-version":[{"id":2902,"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/posts\/123\/revisions\/2902"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/media\/2901"}],"wp:attachment":[{"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/media?parent=123"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/categories?post=123"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudinsidr.com\/content\/wp-json\/wp\/v2\/tags?post=123"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}