Sunday, December 14, 2014

StartSSL in AWS

Update Nov 2016: I am now using Lets Encrypt.

I've been using a non-publicly trusted SSL cert on this website for a long time. But now that Google is replacing OpenID with OpenID Connect, my sign-in process will need to receive an OAuth2 code, and I didn't want visitors to have to transmit that in the clear.

StartSSL is a publicly trusted Certificate Authority headquartered in Israel that seems to have generally positive reviews. They offer free publicly trusted SSL certs. Since I know how easy it is to produce these, and since they have add-on pay services, and since my site doesn't transfer money, I'm willing to trust them. Looking forward, Let's Encrypt is probably a better solution.

Here's how to issue and install a free StartSSL cert in Lighttpd in AWS.

Go to startssl.com. Click "Control Panel" (near top right). Click "Express Lane". Fill out real personal details and click "Continue" (for me it took several minutes to process that click). Be patient.

They have sent you a registration code by email. This may take another few minutes to arrive. Retrieve the code and enter it and click "Continue".

Accept the default 2048 (High Grade) key and click "Continue".

Click "Install". This is a personal client-auth SSL certificate, not a certificate for your website. After clicking "Install" in Chrome, I got a Chrome bubble that said "Successfully stored client certificate issued by StartCom Class 1 Primary intermediate Client CA. [View]". Clicking [View] shows that this is a RSA-2048-SHA1 certificate issued to my personal e-mail address. In Windows7, you can run certmgr.msc from the Start Menu to see this certificate and and private key stored under Personal/Certificates. You should [right-click, All Tasks, Export] this key-pair to a pkcs12 (.pfx) format for backup before proceeding.

Back on the StartSSL page, click "Continue". I think there's a bug here. this took me to their FAQ page. I had to click "Classic View" then "Control Panel" (top right) to get back to the page that lets you do work.

Click "Validations Wizard". Select "Domain Name Validation" and click "Continue". Enter your domain name and click "Continue". They show a list of emails (presumably from your whois). Select one you control and click "Continue". They will send an authentication code to the selected email. Enter the received code and click "Continue". Click "Finish".

Click "Certificates Wizard". Select "Web Server SSL/TLS Certificate" and click "Continue". You are new ready to perform a standard certificate request.

On your AWS box perform the following. I'm assuming your Lighttpd is already running from self-signed SSL /etc/lighttpd/ssl/ssl.pem. If that's not the case you can get more details here and here.

# go to wherever you keep your credentials
cd /etc/lighttpd/ssl

# generate the key and cert-request
sudo openssl req -nodes -subj "/DC=holtstrom/DC=com" -keyout key.pem -newkey rsa:2048 -new -out req.pem

# have a look at what you've generated
cat key.pem
cat req.pem

That says:

req     // generate a key-pair and cert-request
-nodes  // don't password protect the output
-subj "/DC=holtstrom/DC=com" // the subject of the cert should be holtstrom.com
-keyout key.pem  // output the private key here
-newkey rsa:2048 // generate an RSA-2048 key
-new             
-out req.pem     // output the cert-request here

The key.pem contains your raw private key. This is a secret. Don't give that PEM blob to anyone. The req.pem contains the matching public key wrapped as a certificate request. That's what you'll give to StartSSL. They'll wrap your public key in a certificate. That's what your webserver will show to the world.

Back on startssl.com, in the Certificates Wizard, click "Skip" on the "Generate Private Key" page. You should never give anyone your private key. Never let anyone generate it for you.

Paste your certificate request (i.e. CSR), (i.e. the contents of req.pem) into the form. They show a warning that SHA2 may not be supported on old systems and indicate that they will ignore most parameters in your request. Click "Continue". Select your domain. Click "Continue". Add the www subdomain. Click "Continue". Click "Continue" again. I got the following warning at 10:41am on a sunday:

You successfully finished the process for your certificate. However your certificate request has been marked for approval by our personnel. Please wait for a mail notification from us within the next 3 hours (the most). We might contact you for further questions or issue the certificate within that time.

The confirmation email arrived to the email with which I validated the domain at 10:44am.

Back on startssl.com, click "Tool Box" then "Retrieve Certificate". Select the certificate you just requested and click "Continue". Copy the certificate, which will look like this:

-----BEGIN CERTIFICATE-----
MIIGQDCCBSigAwIBAgIDFQR5MA0GCSqGSIb3DQEBCwUAMIGMMQswCQYDVQQGEwJJ
TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0
YWwgQ2VydGlmaWNhdGUgU2lnbmluZzE4MDYGA1UEAxMvU3RhcnRDb20gQ2xhc3Mg
MSBQcmltYXJ5IEludGVybWVkaWF0ZSBTZXJ2ZXIgQ0EwHhcNMTQxMjE0MDM0NjM3
WhcNMTUxMjE1MDcyMDEwWjBPMQswCQYDVQQGEwJDQTEaMBgGA1UEAxMRd3d3Lmhv
bHRzdHJvbS5jb20xJDAiBgkqhkiG9w0BCQEWFWRvbWFpbnNAaG9sdHN0cm9tLmNv
bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM0NZw6kyCxQZQliDGKW
9Z2NyqZH+jbjKoef3gUB4fSOnGaFOnbOrxxSOtNHzP+2nvdEZFRYrWtXu7hDRmxk
Rg+le8zKjYkFGGwsnNHH9OjnfGXVTfhlAm8T2NNAhob9tHTIuUveXmHCcdAJop5W
ibmds7bSX4UUAw0cAccnz+OY8iUvUud+P2YQy/ZisFta/amcLhakfntughGjCPzJ
n2I7rieK6qb4wie1yuDg3CrSqCPdvp4iK5IBxhaNP9AMeCcJIFrmv84GSOpc70Rd
/ZHhNdqYLscF9l2Jrqtv2+w2X13Jd3ArHJj6pmKR2P5ofIEFzb6TJoVcmh/8YDuB
8PECAwEAAaOCAuUwggLhMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgOoMBMGA1UdJQQM
MAoGCCsGAQUFBwMBMB0GA1UdDgQWBBQ9GC27OUV5P0xL7NeJOpWmBGNTDjAfBgNV
HSMEGDAWgBTrQjTQmLCrn/Qbawj3zGQu7w4sRTArBgNVHREEJDAighF3d3cuaG9s
dHN0cm9tLmNvbYINaG9sdHN0cm9tLmNvbTCCAVYGA1UdIASCAU0wggFJMAgGBmeB
DAECATCCATsGCysGAQQBgbU3AQIDMIIBKjAuBggrBgEFBQcCARYiaHR0cDovL3d3
dy5zdGFydHNzbC5jb20vcG9saWN5LnBkZjCB9wYIKwYBBQUHAgIwgeowJxYgU3Rh
cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwAwIBARqBvlRoaXMgY2VydGlm
aWNhdGUgd2FzIGlzc3VlZCBhY2NvcmRpbmcgdG8gdGhlIENsYXNzIDEgVmFsaWRh
dGlvbiByZXF1aXJlbWVudHMgb2YgdGhlIFN0YXJ0Q29tIENBIHBvbGljeSwgcmVs
aWFuY2Ugb25seSBmb3IgdGhlIGludGVuZGVkIHB1cnBvc2UgaW4gY29tcGxpYW5j
ZSBvZiB0aGUgcmVseWluZyBwYXJ0eSBvYmxpZ2F0aW9ucy4wNQYDVR0fBC4wLDAq
oCigJoYkaHR0cDovL2NybC5zdGFydHNzbC5jb20vY3J0MS1jcmwuY3JsMIGOBggr
BgEFBQcBAQSBgTB/MDkGCCsGAQUFBzABhi1odHRwOi8vb2NzcC5zdGFydHNzbC5j
b20vc3ViL2NsYXNzMS9zZXJ2ZXIvY2EwQgYIKwYBBQUHMAKGNmh0dHA6Ly9haWEu
c3RhcnRzc2wuY29tL2NlcnRzL3N1Yi5jbGFzczEuc2VydmVyLmNhLmNydDAjBgNV
HRIEHDAahhhodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS8wDQYJKoZIhvcNAQELBQAD
ggEBAEISnt0iPzLtbznlw1LUXjZ77fjQ6bQJfxrRL/gw2s6AMGBhK9bIRBpZ6nBC
kG4q5KGOjb24eB77/kMFZ/RW+/+zB+3slTRYT24BBgfgpL1VKkDeFQMS4O/0S6wx
omFm2agMDJzUdEdTeuWwMY8xoT54fh7YADbe0y6yXTzKLmyK5tPtkMDy3XXHMPxi
andZMoHayoC63TE+5Px1089tphk+SGPJWSH9jskmVXsAW395GGg7y/MRItn3/6Wq
6Fi9Ckpl8fSp/sTmA9vSihpt+OAejFT7CR864RS9Lns3T/gNI1KVw8ApsZXT32pE
XcVJPBPZsu0Axhb0+B6GchindPo=
-----END CERTIFICATE-----

Then you need to get it on the server.

# go to wherever you keep your credentials
cd /etc/lighttpd/ssl

# paste in the new certificate
sudo vi cert.pem
i
[right-click]
[esc]:wq

# backup the old one
sudo mv ssl.pem ssl.old.pem

# combine the key and cert into one file
sudo cat key.pem cert.pem > /tmp/ssl.pem
sudo mv /tmp/ssl.pem /etc/lighttpd/ssl

# give safe permissions
sudo chmod 400 key.pem
sudo chmod 400 cert.pem
sudo chmod 400 ssl.pem
sudo chown root:root ssl.pem

# restart
sudo service lighttpd restart

Your ssl.pem should look like this

-----BEGIN PRIVATE KEY-----
[secret pem here]
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIGQDCCBSigAwIBAgIDFQR5MA0GCSqGSIb3DQEBCwUAMIGMMQswCQYDVQQGEwJJ
TDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0
YWwgQ2VydGlmaWNhdGUgU2lnbmluZzE4MDYGA1UEAxMvU3RhcnRDb20gQ2xhc3Mg
MSBQcmltYXJ5IEludGVybWVkaWF0ZSBTZXJ2ZXIgQ0EwHhcNMTQxMjE0MDM0NjM3
WhcNMTUxMjE1MDcyMDEwWjBPMQswCQYDVQQGEwJDQTEaMBgGA1UEAxMRd3d3Lmhv
bHRzdHJvbS5jb20xJDAiBgkqhkiG9w0BCQEWFWRvbWFpbnNAaG9sdHN0cm9tLmNv
bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM0NZw6kyCxQZQliDGKW
9Z2NyqZH+jbjKoef3gUB4fSOnGaFOnbOrxxSOtNHzP+2nvdEZFRYrWtXu7hDRmxk
Rg+le8zKjYkFGGwsnNHH9OjnfGXVTfhlAm8T2NNAhob9tHTIuUveXmHCcdAJop5W
ibmds7bSX4UUAw0cAccnz+OY8iUvUud+P2YQy/ZisFta/amcLhakfntughGjCPzJ
n2I7rieK6qb4wie1yuDg3CrSqCPdvp4iK5IBxhaNP9AMeCcJIFrmv84GSOpc70Rd
/ZHhNdqYLscF9l2Jrqtv2+w2X13Jd3ArHJj6pmKR2P5ofIEFzb6TJoVcmh/8YDuB
8PECAwEAAaOCAuUwggLhMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgOoMBMGA1UdJQQM
MAoGCCsGAQUFBwMBMB0GA1UdDgQWBBQ9GC27OUV5P0xL7NeJOpWmBGNTDjAfBgNV
HSMEGDAWgBTrQjTQmLCrn/Qbawj3zGQu7w4sRTArBgNVHREEJDAighF3d3cuaG9s
dHN0cm9tLmNvbYINaG9sdHN0cm9tLmNvbTCCAVYGA1UdIASCAU0wggFJMAgGBmeB
DAECATCCATsGCysGAQQBgbU3AQIDMIIBKjAuBggrBgEFBQcCARYiaHR0cDovL3d3
dy5zdGFydHNzbC5jb20vcG9saWN5LnBkZjCB9wYIKwYBBQUHAgIwgeowJxYgU3Rh
cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwAwIBARqBvlRoaXMgY2VydGlm
aWNhdGUgd2FzIGlzc3VlZCBhY2NvcmRpbmcgdG8gdGhlIENsYXNzIDEgVmFsaWRh
dGlvbiByZXF1aXJlbWVudHMgb2YgdGhlIFN0YXJ0Q29tIENBIHBvbGljeSwgcmVs
aWFuY2Ugb25seSBmb3IgdGhlIGludGVuZGVkIHB1cnBvc2UgaW4gY29tcGxpYW5j
ZSBvZiB0aGUgcmVseWluZyBwYXJ0eSBvYmxpZ2F0aW9ucy4wNQYDVR0fBC4wLDAq
oCigJoYkaHR0cDovL2NybC5zdGFydHNzbC5jb20vY3J0MS1jcmwuY3JsMIGOBggr
BgEFBQcBAQSBgTB/MDkGCCsGAQUFBzABhi1odHRwOi8vb2NzcC5zdGFydHNzbC5j
b20vc3ViL2NsYXNzMS9zZXJ2ZXIvY2EwQgYIKwYBBQUHMAKGNmh0dHA6Ly9haWEu
c3RhcnRzc2wuY29tL2NlcnRzL3N1Yi5jbGFzczEuc2VydmVyLmNhLmNydDAjBgNV
HRIEHDAahhhodHRwOi8vd3d3LnN0YXJ0c3NsLmNvbS8wDQYJKoZIhvcNAQELBQAD
ggEBAEISnt0iPzLtbznlw1LUXjZ77fjQ6bQJfxrRL/gw2s6AMGBhK9bIRBpZ6nBC
kG4q5KGOjb24eB77/kMFZ/RW+/+zB+3slTRYT24BBgfgpL1VKkDeFQMS4O/0S6wx
omFm2agMDJzUdEdTeuWwMY8xoT54fh7YADbe0y6yXTzKLmyK5tPtkMDy3XXHMPxi
andZMoHayoC63TE+5Px1089tphk+SGPJWSH9jskmVXsAW395GGg7y/MRItn3/6Wq
6Fi9Ckpl8fSp/sTmA9vSihpt+OAejFT7CR864RS9Lns3T/gNI1KVw8ApsZXT32pE
XcVJPBPZsu0Axhb0+B6GchindPo=
-----END CERTIFICATE-----

That worked great in Chrome, IE and Safari, but Firefox rejected it with the following warning: "The certificate is not trusted because no issuer chain was provided".

I opened the same page in IE and clicked on the lock in the url and saw the following chain.

I ran certmgr.msc and exported that certificate as follows:

-----BEGIN CERTIFICATE-----
MIIGNDCCBBygAwIBAgIBGDANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
dGlvbiBBdXRob3JpdHkwHhcNMDcxMDI0MjA1NDE3WhcNMTcxMDI0MjA1NDE3WjCB
jDELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsT
IlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNpZ25pbmcxODA2BgNVBAMTL1N0
YXJ0Q29tIENsYXNzIDEgUHJpbWFyeSBJbnRlcm1lZGlhdGUgU2VydmVyIENBMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtonGrO8JUngHrJJj0PREGBiE
gFYfka7hh/oyULTTRwbw5gdfcA4Q9x3AzhA2NIVaD5Ksg8asWFI/ujjo/OenJOJA
pgh2wJJuniptTT9uYSAK21ne0n1jsz5G/vohURjXzTCm7QduO3CHtPn66+6CPAVv
kvek3AowHpNz/gfK11+AnSJYUq4G2ouHI2mw5CrY6oPSvfNx23BaKA+vWjhwRRI/
ME3NO68X5Q/LoKldSKqxYVDLNM08XMML6BDAjJvwAwNi/rJsPnIO7hxDKslIDlc5
xDEhyBDBLIf+VJVSH1I8MRKbf+fAoKVZ1eKPPvDVqOHXcDGpxLPPr21TLwb0pwID
AQABo4IBrTCCAakwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
VR0OBBYEFOtCNNCYsKuf9BtrCPfMZC7vDixFMB8GA1UdIwQYMBaAFE4L7xqkQFul
F2mHMMo0aEPQQa7yMGYGCCsGAQUFBwEBBFowWDAnBggrBgEFBQcwAYYbaHR0cDov
L29jc3Auc3RhcnRzc2wuY29tL2NhMC0GCCsGAQUFBzAChiFodHRwOi8vd3d3LnN0
YXJ0c3NsLmNvbS9zZnNjYS5jcnQwWwYDVR0fBFQwUjAnoCWgI4YhaHR0cDovL3d3
dy5zdGFydHNzbC5jb20vc2ZzY2EuY3JsMCegJaAjhiFodHRwOi8vY3JsLnN0YXJ0
c3NsLmNvbS9zZnNjYS5jcmwwgYAGA1UdIAR5MHcwdQYLKwYBBAGBtTcBAgEwZjAu
BggrBgEFBQcCARYiaHR0cDovL3d3dy5zdGFydHNzbC5jb20vcG9saWN5LnBkZjA0
BggrBgEFBQcCARYoaHR0cDovL3d3dy5zdGFydHNzbC5jb20vaW50ZXJtZWRpYXRl
LnBkZjANBgkqhkiG9w0BAQUFAAOCAgEAIQlJPqWIbuALi0jaMU2P91ZXouHTYlfp
tVbzhUV1O+VQHwSL5qBaPucAroXQ+/8gA2TLrQLhxpFy+KNN1t7ozD+hiqLjfDen
xk+PNdb01m4Ge90h2c9W/8swIkn+iQTzheWq8ecf6HWQTd35RvdCNPdFWAwRDYSw
xtpdPvkBnufh2lWVvnQce/xNFE+sflVHfXv0pQ1JHpXo9xLBzP92piVH0PN1Nb6X
t1gW66pceG/sUzCv6gRNzKkC4/C2BBL2MLERPZBOVmTX3DxDX3M570uvh+v2/miI
RHLq0gfGabDBoYvvF0nXYbFFSF87ICHpW7LM9NfpMfULFWE7epTj69m8f5SuauNi
YpaoZHy4h/OZMn6SolK+u/hlz8nyMPyLwcKmltdfieFcNID1j0cHL7SRv7Gifl9L
WtBbnySGBVFaaQNlQ0lxxeBvlDRr9hvYqbBMflPrj0jfyjO1SPo2ShpTpjMM0InN
SRXNiTE8kMBy12VLUjWKRhFEuT2OKGWmPnmeXAhEKa2wNREuIU640ucQPl2Eg7PD
wuTSxv0JS3QJ3fGz0xk+gA2iCxnwOOfFwq/iI9th4p1cbiCJSS4jarJiwUW0n6+L
p/EiO/h94pDQehn7Skzj0n1fSoMD7SfWI55rjbRZotnvbIIp3XUZPD9MEI3vu3Un
0q6Dp6jOW6c=
-----END CERTIFICATE-----

Then I updated my Lighttpd to be aware of that cert as follows:

sudo vi /etc/lighttpd/lighttpd.conf

# my existing 443 block looked like this
$SERVER["socket"] == ":443" {
  ssl.engine  = "enable"
  ssl.pemfile = "/etc/lighttpd/ssl/ssl.pem"
}

# I updated it to look like this
$SERVER["socket"] == ":443" {
  ssl.engine  = "enable"
  ssl.pemfile = "/etc/lighttpd/ssl/ssl.pem"
  ssl.ca-file = "/etc/lighttpd/ssl/intermediate.pem"
}

# then I created this file with the contents from above
sudo vi /etc/lighttpd/ssl/intermediate.pem
i
[right-click]
[esc]:wq

# then update the permissions
sudo chmod 400 /etc/lighttpd/ssl/intermediate.pem

# then restart
sudo service lighttpd restart

Then Firefox stopped complaining.

aws
{ "loggedin": false, "owner": false, "avatar": "", "render": "nothing", "trackingID": "UA-36983794-1", "description": "", "page": { "blogIds": [ 523 ] }, "domain": "holtstrom.com", "base": "\/michael", "url": "https:\/\/holtstrom.com\/michael\/", "frameworkFiles": "https:\/\/holtstrom.com\/michael\/_framework\/_files.4\/", "commonFiles": "https:\/\/holtstrom.com\/michael\/_common\/_files.3\/", "mediaFiles": "https:\/\/holtstrom.com\/michael\/media\/_files.3\/", "tmdbUrl": "http:\/\/www.themoviedb.org\/", "tmdbPoster": "http:\/\/image.tmdb.org\/t\/p\/w342" }