Enable HTTPS on your servers

Chris Palmer
Chris Palmer
Matt Gaunt

This page provides guidance for setting up HTTPS on your servers, including the following steps:

  • Creating a 2048-bit RSA public/private key pair.
  • Generating a certificate signing request (CSR) that embeds your public key.
  • Sharing your CSR with your Certificate Authority (CA) to receive a final certificate or a certificate chain.
  • Installing your final certificate in a non-web-accessible place such as /etc/ssl (Linux and Unix) or wherever IIS requires it (Windows).

This section uses the openssl command-line program, which comes with most Linux, BSD, and Mac OS X systems, to generate private and public keys and a CSR.

Generate a public/private key pair

To start, generate a 2,048-bit RSA key pair. A shorter key can be broken by brute-force guessing attacks, and longer keys use unnecessary resources.

Use the following command to generate an RSA key pair:

openssl genrsa -out www.example.com.key 2048

This gives the following output:

Generating RSA private key, 2048 bit long modulus
.+++
.......................................................................................+++
e is 65537 (0x10001)

Generate a certificate signing request

In this step, you embed your public key and information about your organization and your website into a certificate signing request or CSR. The openssl command asks you for the required metadata.

Running the following command:

openssl req -new -sha256 -key www.example.com.key -out www.example.com.csr

Outputs the following:

You are about to be asked to enter information that will be incorporated
into your certificate request

What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CA
State or Province Name (full name) [Some-State]:California
Locality Name (for example, city) []:Mountain View
Organization Name (for example, company) [Internet Widgits Pty Ltd]:Example, Inc.
Organizational Unit Name (for example, section) []:Webmaster Help Center Example
Team
Common Name (e.g. server FQDN or YOUR name) []:www.example.com
Email Address []:webmaster@example.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

To ensure the validity of the CSR, run this command:

openssl req -text -in www.example.com.csr -noout

The response should look like this:

Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=CA, ST=California, L=Mountain View, O=Google, Inc.,
OU=Webmaster Help Center Example Team,
CN=www.example.com/emailAddress=webmaster@example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:ad:fc:58:e0:da:f2:0b:73:51:93:29:a5:d3:9e:
                    f8:f1:14:13:64:cc:e0:bc:be:26:5d:04:e1:58:dc:
                    ...
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
         5f:05:f3:71:d5:f7:b7:b6:dc:17:cc:88:03:b8:87:29:f6:87:
         2f:7f:00:49:08:0a:20:41:0b:70:03:04:7d:94:af:69:3d:f4:
         ...

Submit your CSR to a certificate authority

Different certificate authorities (CAs) require you to submit your CSRs to them in different ways. These can include using a form on their website or sending the CSR by email. Some CAs, or their resellers, might even automate some or all of the process, including, in some cases, key pair and CSR generation.

Send the CSR to your CA and follow their instructions to receive your final certificate or certificate chain.

Different CAs charge different amounts of money for the service of vouching for your public key.

There are also options for mapping your key to more than one DNS name, including several distinct names (e.g. all of example.com, www.example.com, example.net, and www.example.net) or "wildcard" names such as *.example.com.

Copy the certificates to all your front-end servers in a non-web-accessible place such as /etc/ssl (Linux and Unix) or wherever IIS (Windows) requires them.

Enable HTTPS on your servers

Enabling HTTPS on your servers is a critical step in providing security for your web pages.

  • Use Mozilla's Server Configuration tool to set up your server for HTTPS support.
  • Regularly test your site with the Qualys' SSL Server Test and ensure you get at least an A or A+.

At this point, you must make a crucial operations decision. Choose one of the following:

  • Dedicate a distinct IP address to each hostname your web server serves content from.
  • Use name-based virtual hosting.

If you've been using distinct IP addresses for each hostname, you can support both HTTP and HTTPS for all clients. However, most site operators use name-based virtual hosting to conserve IP addresses and because it's more convenient in general.

If you don't already have HTTPS service available on your servers, enable it now (without redirecting HTTP to HTTPS. See Redirect HTTP to HTTPS for more information). Configure your web server to use the certificates you bought and installed. You might find Mozilla's configuration generator useful.

If you have many hostnames or subdomains, they each need to use the right certificate.

Now, and regularly throughout your site's lifetime, check your HTTPS configuration with Qualys' SSL Server Test. Your site should score an A or A+. Treat anything that causes a lower grade as a bug, and stay diligent, because new attacks against algorithms and protocols are always being developed.

Make intrasite URLs relative

Now that you're serving your site on both HTTP and HTTPS, things need to work as smoothly as possible regardless of protocol. An important factor is using relative URLs for intrasite links.

Make sure intrasite URLs and external URLs don't depend on a specific protocol. Use relative paths or leave out the protocol as in //example.com/something.js.

Serving a page that contains HTTP resources using HTTPS can cause issues. When a browser encounters an otherwise secure page using insecure resources, it warns users that the page isn't completely secure, and some browsers refuse to load or execute the HTTP resources, which breaks the page. However, you can safely include HTTPS resources in an HTTP page. For more guidance on fixing these issues, see Fixing Mixed Content.

Following HTTP-based links to other pages on your site can also downgrade the user experience from HTTPS to HTTP. To fix this, make your intrasite URLs as relative as possible, by making them either protocol-relative (lacking a protocol, starting with //example.com) or host-relative (starting with just the path, like /jquery.js).

Do
<h1>Welcome To Example.com</h1>
<script src="/jquery.js"></script>
<link rel="stylesheet" href="/assets/style.css"/>
<img src="/images/logo.png"/>;
<p>A <a href="/2014/12/24">new post on cats!</a></p>
Use relative intrasite URLs.
Do
<h1>Welcome To Example.com</h1>
<script src="//example.com/jquery.js"></script>
<link rel="stylesheet" href="//assets.example.com/style.css"/>
<img src="//img.example.com/logo.png"/>;
<p>A <a href="//example.com/2014/12/24/">new post on cats!</a></p>
Or, use protocol-relative intrasite URLs.
Do
<h1>Welcome To Example.com</h1>
<script src="/jquery.js"></script>
<link rel="stylesheet" href="/assets/style.css"/>
<img src="/images/logo.png"/>;
<p>A <a href="/2014/12/24">new post on cats!</a></p>
<p>Check out this <a href="https://foo.com/"><b>other cool site.</b></a></p>
Use HTTPS URLs for links to other sites where possible.

Update your links with a script, not by hand, to avoid making mistakes. If your site's content is in a database, test your script on a development copy of the database. If your site's content consists of only simple files, test your script on a development copy of the files. Push the changes to production only after the changes pass QA, as normal. You can use Bram van Damme's script or something similar to detect mixed content in your site.

When linking to other sites (as opposed to including resources from them), don't change the protocol. You don't have control over how those sites operate.

To make migration smoother for large sites, we recommend protocol-relative URLs. If you aren't sure whether you can fully deploy HTTPS yet, forcing your site to use HTTPS for all subresources can backfire. There is likely to be a period of time in which HTTPS is new and weird for you, and the HTTP site must still work as well as ever. Over time, you'll complete the migration and lock in HTTPS (see the next two sections).

If your site depends on scripts, images, or other resources served from a third party, such as a CDN or jquery.com, you have two options:

  • Use protocol-relative URLs for these resources. If the third party doesn't serve HTTPS, ask them to. Most already do, including jquery.com.
  • Serve the resources from a server that you control, which offers both HTTP and HTTPS. This is often a good idea anyway, because then you have better control over your site's appearance, performance, and security, and don't have to trust a third party to keep your site secure.

Redirect HTTP to HTTPS

To tell search engines to use HTTPS to access your site, put a canonical link at the head of each page using <link rel="canonical" href="https://…"/> tags.

Turn on Strict Transport Security and secure cookies

At this point, you're ready to "lock in" the use of HTTPS:

  • Use HTTP Strict Transport Security (HSTS) to avoid the cost of the 301 redirect.
  • Always set the Secure flag on cookies.

First, use Strict Transport Security to tell clients they should always connect to your server using HTTPS, even when following an http:// reference. This defeats attacks like SSL Stripping, and avoids the round-trip cost of the 301 redirect that we enabled in Redirect HTTP to HTTPS.

To turn on HSTS, set the Strict-Transport-Security header. OWASP's HSTS page has links to instructions for various kinds of server software.

Most web servers offer a similar ability to add custom headers.

It's also important to make sure clients never send cookies (such as for authentication or site preferences) over HTTP. For example, if a user's authentication cookie were to be exposed in plain text, your security guarantee for their entire session is destroyed, even if you've done everything else right!

To avoid this, change your web app to always set the Secure flag on cookies it sets. This OWASP page explains how to set the Secure flag in several app frameworks. Every appl framework has a way to set the flag.

Most web servers offer a simple redirect feature. Use 301 (Moved Permanently) to indicate to search engines and browsers that the HTTPS version is canonical, and redirect your users to the HTTPS version of your site from HTTP.

Search ranking

Google uses HTTPS as a positive search quality indicator. Google also publishes a guide to how to transferring, moving, or migrating your site while maintaining its search rank. Bing also publishes guidelines for webmasters.

Performance

When the content and application layers are well-tuned (refer to Steve Souders' books for advice), the remaining TLS performance concerns are generally small relative to the overall cost of the application. You can also reduce and amortize those costs. For advice on TLS optimization, see High Performance Browser Networking by Ilya Grigorik, as well as Ivan Ristic's OpenSSL Cookbook and Bulletproof SSL And TLS.

In some cases, TLS can improve performance, mostly as a result of making HTTP/2 possible. For more information, refer to Chris Palmer's' talk on HTTPS and HTTP/2 performance at Chrome Dev Summit 2014.

Referer headers

When users follow links from your HTTPS site to other HTTP sites, user agents don't send the Referer header. If this is a problem, there are several ways to solve it:

  • The other sites should migrate to HTTPS. If referee sites complete the Enable HTTPS on your servers section of this guide, you can change links in your site to theirs from http:// to https:// or use protocol-relative links.
  • To work around a variety of problems with Referer headers, use the new Referrer Policy standard.

Ad revenue

Site operators that monetize their site by showing ads want to make sure migrating to HTTPS doesn't reduce ad impressions. However, because of mixed content security concerns, an HTTP <iframe> doesn't work on an HTTPS page. Until advertisers publish over HTTPS, site operators can't migrate to HTTPS without losing ad revenue; but until site operators migrate to HTTPS, advertisers have little motivation to publish HTTPS.

You can start the process of breaking this stalemate by using advertisers that offer ad services over HTTPS, and asking advertisers that don't serve HTTPS at all to at least make it an option. You might need to defer completing Make IntraSite URLs relative until enough advertisers interoperate properly.