IndieWebCamp is a 2-day creator camp focused on growing the independent web

https

HTTPS is an abbreviation for Hypertext Transfer Protocol Secure, a protocol for secure communication, supported by web servers (like Apache & nginx) and browsers. HTTPS layers Hypertext Transfer Protocol (HTTP) on top of the SSL/TLS protocol.

There are two primary types of HTTPS:

  • IP-based is the traditional way. SSL/TLS negotiation happens below HTTP, so the server needs to present a certificate before it knows which host the client is asking for. If the server has multiple certs, it chooses the appropriate one based on the IP address the client connected to.
  • SNI is a newer variant that can serve multiple certs from the same IP. Most modern browsers and libraries support it, including OpenSSL 0.9.8 and up.

Contents

How to

Buy

Buying SSL certificates

  • startssl.com offers free SSL certificates for single domains. If you verify your identity, they will also allow you to register free wildcard certs.
  • namecheap.com offers single-domain SSL certificates for $7.95/year and wildcard certificates for $85/year
  • GlobalSign offers free wildcard certificates (!) for open source projects.
  • ssls.com has inexpensive SSL certificates from multiple providers. As of 2014/03/08, a PositiveSSL certificate was $4.99/yr when buying 5 years.
  • ...

Validating Your Purchase

SSL Certificate providers require some form of verification of you, your domain, and your ownership of your domain.

CSR Generation — A Certificate Signing Request must be generated at your site. For example, on a hosting provider that uses Cpanel, the "SSL/TLS Manager" has a "Certificate Signing Requests" section.

Approver Email — ssls.com asks for an "Approver Email" from a list of administration email addresses and Domain Registration email addresses. Choose one that you use, and receive the Domain Control Validation email, which contains a link and a "validation code". Click the link and enter the code to verify that you own the domain.

Certificate Email — " [http://ssls.com/ ssls.com send the certificate to the "Administrator Email" that you specified during the purchase process. This certificate is used in the process below.

Manage

When you're done with your purchase, you'll have one or more files for each certificate:

  • The certificate itself, e.g. snarfed.org.ssl.crt.
  • The private key you used to generate the certificate, e.g. id_rsa-2048.
  • Optional: Your CA's intermediate cert, e.g. sub.class1.server.ca.pem.
  • Optional: Your CA's root, e.g. ca.pem. Hopefully you picked a CA whose root cert is distributed with most OSes/browsers; if so, you can ignore this. (If you didn't, you should reconsider!)

All of these files are usually X.509 format except the private key, which is RSA or other private key format.

Command line openssl is your friend for inspecting and editing certificates. For example, to dump info about a cert:

openssl x509 -text -in snarfed.org.ssl.crt

If your CA provided an intermediate cert, you'll need to provide it to your web server along with your own cert. For servers that only accept a single file, you'll need to concatenate the certs, e.g.:

cat snarfed.org.ssl.crt sub.class1.server.ca.pem > snarfed.org.unified.ssl.crt

As another example, it seems like this command line should verify that a cert is valid:

openssl verify -verbose -CAfile ca.pem snarfed.org.unified.ssl.crt

...but User:snarfed.org gets this error:

error 20 at 0 depth lookup:unable to get local issuer certificate

Setup

The IETF has a document with recommendations for Secure Use of TLS and DTLS.

Apache

Apache is pretty easy. Here's a good how-to post. TL;DR: Put the certificate files somewhere your Apache user can read, then set the SSLCertificate* config directives, e.g.:

SSLCertificateKeyFile /home/ryan/.ssh/id_rsa-2048
SSLCertificateFile /home/ryan/www/snarfed.org.ssl.crt
SSLCertificateChainFile /home/ryan/www/sub.class1.server.ca.pem

App Engine

If you're serving on Google App Engine's built-in appspot.com domain, you're already done! Just add secure: always (or optional) to the handler(s) in your app.yaml or other app config file, and you'll be able to access your app over https. Details here.

If you're using the java runtime on App Engine, add this stanza to your web.xml file.

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app 
   ...> 

  <security-constraint>
    <web-resource-collection>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
      <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
  </security-constraint>

You may additionally want to send a HSTS header to further improve security. In java, the easiest way from a servlet running on AppEngine is to add this header to all responses when running on the production server.

import com.google.appengine.api.utils.SystemProperty;

...

      if (SystemProperty.environment.value() ==
          SystemProperty.Environment.Value.Production) {
          // force ssl for six months.
          response.addHeader("Strict-Transport-Security", "max-age=15768000");
      }

If you also deliver static content, you may want to enable the HSTS header here as well. An example stanza within your appengine-web.xml file might look like this.

<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
...
    <static-files>
    <include path="/static/**" >
      <http-header name="Strict-Transport-Security" value="max-age=15768000"/>
...



If you're on a custom domain, you can use either SNI or a VIP. Details here. You'll need to upload your SSL cert files to the Google Apps control panel for your domain, then add and configure SNI or VIP slots in App Engine.

nginx

We can setup nginx to listen on port 443 with our SSL sertificate quite easily:

server {
    listen 443 ssl;
    server_name example.org;

     ssl_certificate /path/to/unified.crt;
     ssl_certificate_key /path/to/my-private-decrypted.key;

     //usual nginx config here like location blocks
}

For more detailed nginx config instructions see the page on nginx

Test

Production

Qualys's SSL Server Test is an easy way to test the SSL cert on your live site. See e.g. brid.gy's report card, or for comparison jonnybarnes.net gets slightly different results.

You can use openssl s_client to debug connection issues, e.g.:

openssl s_client -connect snarfed.org:443

If your server uses SNI, you'll need to provide the hostname too:

openssl s_client -servername www.brid.gy -connect www.brid.gy:443

Here's an example of debugging a single SSL issue:

Brand new StartSSL certificates may give an OCSP validation error for 6-24 hours after purchase. This seems to only affect Firefox and resolves itself when the certificate propagates to the validation server[1]. Firefox users can disable the check temporarily with Edit > Preferences > Advanced > Certificates > Validation, and uncheck "Use the Online Certificate Status Protocol"

Local

When developing a website locally, it may be useful to be able to test the site via https. For example, when writing an OAuth client, some providers will not redirect to a page that does not use https.

The easiest way to do this is to temporarily redirect your site to your own localhost (just for yourself) and use your site's cert. Just add a line like this to your hosts file:

127.0.0.1	snarfed.org

This is obviously temporary, though. For a more permanent setup, you can either generate a self-signed SSL certificate for your testing domain (localhost, etc) or you can create your own SSL certificate authority and sign the certificate with that.

To assist with this, aaronpk has created an "IndieWebCamp" root authority that can sign certificates for domains ending in ".dev".

You can add a line to your hosts file for your test domain such as

127.0.0.1   mydomain.dev

And then you can use the IndieWebCamp authority to generate an SSL cert for it. There are instructions on the site for how to install it under Apache and nginx.

Posts about HTTPS

  • Hows my SSL is a tool that rates your own browsers security when dealing with HTTPS sites. Such as will your browser uses encryption schemes known to be weak. Further, check out Kyle Isom's Google+ post about better configuring Firefox.

Why

Why?

IndieMark Levels

Proposed IndieMark Levels of recommended support for HTTPS on your own website, as part of a security component

Level 1 security

Level 1 - "Don't do the wrong thing". (what's the minimal "not wrong thing"?). Possible reasonable behaviors:

  • Refuse the connection, because if you don't support SSL, generally you're not listening on port 443, so clients can't connect. Challenge: the user has no idea what is wrong, nor how to fix it (i.e. retry going to the site with "http:" instead).

Why?

  • Avoid a misleading user experience.

IndieWeb Examples

  • Barnaby Walters on waterpigs.co.uk, if you try to access via https, the browser shows something like:
    Unable to connect

    Firefox can't establish a connection to the server at waterpigs.co.uk.
  • ...


Level 2 security

Level 2 - support it for your admin pages with a self-signed certificate.

  • Your admin pages:
    • MUST be available over https
    • SHOULD redirect from http to https automatically (so you don't accidentally send logged in session cookies in the clear over http).
  • E.g. How to make Wordpress use SSL: http://codex.wordpress.org/Administration_Over_SSL

Note: If you actually get a real SSL cert and serve your admin interface from the same domain, you are actually in Level 3.

Why?

  • Security for write-access to your site! Otherwise anyone can hack your CMS and post stuff as you. (e.g. using a tool like Firesheep to sniff your login session cookies, and re-use them to gain access to your admin pages.)

IndieWeb Examples

Level 3 security

Level 3 - provide your front-end over both http and https with a cert from a trusted CA

Why?

  • You can link from silo profiles to your site via https
  • You can start using (requiring!) your https URL for IndieAuth logins (e.g. into the wiki)
  • Your readers can securely access your site without a scary warning message pop-up.
  • privacy for your readers (what they are choosing to read)[2]
  • "Why not?" - GWG
  • ... add

IndieWeb Examples

Level 4 security

Level 4 - serve everything (home page, permalinks, images etc.) over https and send redirects from http -> https. I.e. your pages automatically get at least a lock icon in the browser address bar (and no warnings).

Why?

IndieWeb Examples in rough order of implementation

Check the browser's address bar where your URL is displayed and make sure:

  1. There's a lock icon before (in front of) the URL in the address bar
  2. There's no warning triangle icon (in front of) the URL in the address bar

FAQ:
How do you ensure that external content is over https? E.g. if I have an avatar for a comment from Tantek Çelik it will be over http since he uses http.

  • When you receive a webmention, download the image from the h-card and serve it from your own server.
  • Unless it's a Twitter mention, in which case link to:

Brainstorming:

  • Move "get at least a lock icon" to a new "level 5" requirement/achievement, and bump existing level 5 to 6. Reasoning: it's much harder to serve all resources via https (e.g. external profile images), than just all your own HTML pages, and it's still greatly beneficial to serve at least all your HTML pages always with https.
    • For now, since all existing Level 4 https examples all serve everything (including resources) using https and thus get the lock icon, no need to create another level until we have real world examples that would benefit.


Level 5 security

Level 5 - use correct ciphers, support forward secrecy, etc. per https://www.ssllabs.com/ssltest/ (all previous levels required, i.e. document method of http to https redirection)

Why?

IndieWeb Examples

Criticism


Sessions

Sessions at IndieWebCamps about https:


See Also