Radiac's Blog: linuxhttp://radiac.net/blog/linux/Posts tagged linuxen-gbMon, 18 May 2015 12:27:29 +0000Tips for SSL certificateshttp://radiac.net/blog/2015/05/ssl-certificate-tips/<p>Display CSR information:</p> <pre><code>openssl req -text -noout -in foo.csr</code></pre> <p>Display signed cert information:</p> <pre><code>openssl x509 -in foo.crt.pem -noout -text</code></pre> <p>To remove a password from a key:</p> <pre><code>openssl rsa -in foo.key.pem -out foo-unlocked.key.pem</code></pre> <p>To decode a CRL:</p> <pre><code>openssl crl -text -in ca.crl.pem</code></pre> <p>To check a certificate against a CRL:</p> <pre><code>cat ca/ca.crl.pem ca/ca.crt.pem &gt; crl-check.pem openssl verify -CAfile crl-check.pem -crl_check foo.crt.pem</code></pre>Mon, 18 May 2015 12:27:29 +0000http://radiac.net/blog/2015/05/ssl-certificate-tips/Self-Signing Certificate Authoritieshttp://radiac.net/blog/2015/05/self-ca/<h2 id="">Introduction</h2> <p>If you run a website which receives or displays personal information, passwords or other secrets, you need to encrypt your connections using SSL or TLS. This is what puts the &quot;S&quot; into HTTPS, FTPS, IMAPS, POPS etc, and requires private keys and public certificates. Your browser (or other SSL/TLS client) trusts certain CAs (certificate authorities), and they in turn are willing to trust you by issuing you a certificate, if you throw money at them.</p> <p>This is necessary for public-facing production deployments, and these days the cheapest certificates don't cost the earth - for example, Namecheap's <a href="https://www.namecheap.com/security/ssl-certificates.aspx?aff=86027">start at £6/$9</a>, and <a href="https://letsencrypt.org/">Let's Encrypt</a> should also be launching this summer, providing free domain-validated certificates. However, cheap certificates are <em>domain validated</em>, where the CA checks that you own the domain using automated tests; these can be slow and laborious, so it's often not practical or possible to get these for internal services or development environments.</p> <p>The alternative is to set yourself up as a self-signing CA. You won't be trusted by the public, but it's a good option if you're in the position where you're not public-facing, or where you can tell your users to install your root CA before they use your service. You'll be able to issue as many certificates as you want, and your connection should be just as secure as with a &quot;proper&quot; certificate.</p> <h2 id="">The easy way</h2> <p>I've written <a href="/projects/caman/">caman</a> which will do everything for you - it's a bash script with all the commands I'm about to describe in excruciating detail, so if all you want to do is jump to getting your certificates, go over to the project page and start following its instructions.</p> <aside class="download"> <p><a href="/projects/caman/">Get caman</a>, the easy self-signed certificate authority manager</p> </aside> <p>Read on if you want to know how to do it yourself.</p> <h2 id="">What we're aiming for</h2> <p>We're going to create a directory which contains your CA, your host keys, and the certificates you generate. The structure will be:</p> <pre><code>ca/ Your CA information caconfig.cnf CA configuration (modify this) ca.key.pem CA private key (keep this safe) ca.crt.pem CA public certificate (distribute this) ca.crl.pem List of revoked keys (publish this) serial Next serial number index.txt Registered certificates crlnumber Next CRL number newcerts/ A copy of each certificate signed store/ Your certificates host.domain.tld/ One folder per host config.cnf Config for the given host YYYY-MM-DD/ Build date for cert set host.domain.tld.key.pem Key host.domain.tld.csr Signing request host.domain.tld.crt.pem Certificate host.domain.tld.keycrt.pem Key + cert combo</code></pre> <h2 id="">Prepare your CA</h2> <p>Before we start, you'll need <code>openssl</code> to be installed on your system. In Ubuntu, that would be:</p> <pre><code>sudo apt-get install openssl</code></pre> <p>Now we'll create the CA dir, and start the serial number at 1:</p> <pre><code>cd my_ca mkdir ca store mkdir ca/certs ca/private echo '01' &gt; ca/serial touch ca/index.txt</code></pre> <p>You will now need to create your <code>ca/caconfig.cnf</code> file. You can use the caman template:</p> <pre><code>curl https://raw.githubusercontent.com/radiac/caman/master/ca/caconfig.cnf.default &gt; ca/caconfig.cnf</code></pre> <p>You will need to change some lines - look for the comments starting <code># &gt;&gt;</code>. </p> <ul> <li> <p>Change the 6 values under <code>[ req_distinguished_name ]</code>:</p> <ul> <li><code>countryName</code>: your two-character country code</li> <li><code>stateOrProvinceName</code>: your state or province</li> <li><code>organizationName</code>: the name of your organisation</li> <li><code>organizationUnitName</code>: your department in the organisation</li> <li><code>commonName</code>: the name of your organisation</li> <li><code>emailAddress</code>: your e-mail address</li> </ul> </li> <li> <p>Change the CRL distribution points URL under <code>[ usr_cert ]</code> and <code>[ v3_ca ]</code>:</p> <ul> <li><code>crlDistributionPoints</code>: URL where you will publish your <code>ca.crl.pem</code></li> <li>The CRL is a list of revoked certificates which you'll need to update each time you revoke a host certificate; if you don't want to be bothered with this, you can just comment these lines out, as well as <code>crl_extensions</code> and <code>crlnumber</code> under <code>[ CA_default ]</code>.</li> </ul> </li> <li>You can ignore the value for <code>default_days</code> here - caman uses it, but OpenSSL won't; we'll be passing it directly on the command line.</li> </ul> <h2 id="">Create the root certificate</h2> <p>Your CA is identified by its root certificate. First we need to create the private CA key:</p> <pre><code>openssl genrsa -aes256 -out ca/ca.key.pem 4096</code></pre> <p>The <code>openssl genrsa</code> command generates an RSA key, and the other options tell it to encrypt it with AES 256 (<code>-aes256</code>), to use 4096 bits, and to write it to the file <code>ca/ca.key.pem</code>.</p> <p>When you run the command, it will ask you for a password - keep it safe, you'll need it every time you want to generate and sign a new certificate.</p> <p>This will generate the private CA key, <code>ca/ca.key.pem</code>. This is important:</p> <ul> <li>Do not lose this key. Without it, certificates can't be signed or renewed</li> <li> <p>Do not disclose this key to anyone. If it is compromised, others will be able to impersonate the CA.</p> <aside class="idea"> <p>If you're really paranoid, you could take further steps to protect your key, by creating an intermediate authority to sign host certificates, and keeping your root key somewhere more secure, eg on a USB key locked in a safe; that way if your intermediate authority key is compromised, you could revoke it and create a new one, without having to get people to install your new CA certificate. However, we'll assume that's not an issue for you, and won't be using an intermediate authority here.</p> </aside> </li> </ul> <p>Now we can use the key to generate the public CA certificate:</p> <pre><code>openssl req -x509 -new -key ca/ca.key.pem -days 36500 -out ca/ca.crt.pem -config ca/caconfig.cnf</code></pre> <p>The <code>openssl req</code> command with <code>-x509</code> tells OpenSSL to generate a self-signed certificate; the other options tell it to generate a new certificate (<code>-new</code>) and how long the certificate should be valid for - in this case, <code>-days 36500</code> means about 100 years. It then uses the <code>caconfig.cnf</code> which we configured earlier, and puts the certificate in the file <code>ca/ca.crt.pem</code>.</p> <h2 id="">Publishing your CA Certificate and CRL</h2> <p>To get clients to trust certificates signed by the new self-signing authority, they must install the root certificate, <code>ca.crt.pem</code>.</p> <p>The easiest way to do this is to put it on your web server as a normal file for download, called <code>ca.crt</code>. Most browsers will know what to do with it from there.</p> <p>If you're using Apache to serve your page, it may need to know the MIME type - add this to your configuration or <code>.htaccess</code>:</p> <pre><code>AddType application/x-x509-ca-cert .crt</code></pre> <p>You can then generate your CRL with the following command:</p> <pre><code>openssl ca -gencrl -out ca/ca.crl.pem -config ca/caconfig.cnf</code></pre> <p>To publish it, just put it at the URL you defined in your <code>caconfig.cnf</code> above. Remember to update it each time you renew or revoke a certificate.</p> <h2 id="">Preparing for a new host</h2> <p>Before we start creating hosts, lets set up a directory to store them.</p> <p>In this article we'll be creating a certificate for <code>my.example.com</code>:</p> <pre><code>mkdir store/my.example.com</code></pre> <p>To make a wildcard certificate to cover multiple hosts, just use an asterisk - for example, <code>*.example.com</code> would catch any subdomain of example.com.</p> <p>You will now need to create a configuration for this host. Again, you can use the caman template:</p> <pre><code>curl https://raw.githubusercontent.com/radiac/caman/master/ca/host.cnf.default &gt; store/my.example.com/config.cnf</code></pre> <p>You will need to change some lines - look for the comments starting <code># &gt;&gt;</code>. </p> <ul> <li> <p>Change 4 of the values under <code>[ host_distinguished_name ]</code>:</p> <ul> <li><code>countryName</code>: the two-character country code for this host</li> <li><code>stateOrProvinceName</code>: the state or province for this host</li> <li><code>organizationName</code>: the name of the organisation for this host</li> <li><code>emailAddress</code>: the e-mail address for the admin for this host</li> <li>Do not change <code>commonName</code> or <code>organizationUnitName</code> - these are placeholders which will be set by caman</li> </ul> </li> <li>You can ignore the value for <code>default_days</code> here - caman uses it, but OpenSSL won't; we'll be passing it directly on the command line.</li> </ul> <p>You're now ready to make the certificate itself.</p> <h2 id="">Creating a host certificate</h2> <p>First create a new sub-directory to store this set of files - there will be a key, a CSR (certificate signing request) and a certificate. I like to use the date I'm generating the certificate:</p> <pre><code>mkdir store/my.example.com/2015-05-18</code></pre> <p>Now we'll create a new private key and CSR with this command:</p> <pre><code>openssl req -sha256 \ -newkey rsa:2048 -nodes \ -keyout store/my.example.com/2015-05-18/my.example.com.key.pem \ -new -out store/my.example.com/2015-05-18/my.example.com.csr \ -config store/my.example.com/config.cnf</code></pre> <p>This again calls <code>openssl req</code>, but without <code>-x509</code> this time because we don't want it to be self-signed - we want to sign it using our own CA. We then tell it to use SHA256 (<code>-sha256</code>), and generate a new 2048 bit RSA private key (<code>-newkey rsa:2048</code>) which is not encrypted (<code>-nodes</code> - that's &quot;no DES&quot;, not &quot;nodes&quot;) in the file ending <code>.key.pem</code>. It will then use this to create a new CSR (<code>-new</code>) in the file ending <code>.csr</code>. It uses the host config we created earlier to provide any additional settings.</p> <p>Next we need to sign the CSR to generate the certificate:</p> <pre><code>openssl ca \ -in store/my.example.com/2015-05-18/my.example.com.csr \ -out store/my.example.com/2015-05-18/my.example.com.crt.pem \ -days 3650 -config ca/caconfig.cnf</code></pre> <p>This calls <code>openssl ca</code> to use the certificate authority to sign the CSR (<code>-in</code>) and generate the certificate (<code>-out</code>). Here it will be valid for 3650 days (<code>-days</code>), or approximately 10 years. We give it the CA config this time, so it knows where to find all the settings for our CA.</p> <p>You will now have a private key ending <code>.key.pem</code>, and a public certificate ending <code>.crt.pem</code>. In most cases you'll use these separately, but some services may want them merged together in one file (such as Apache wth the <code>SSLCertificateFile</code> directive), so we'll concatenate them just in case it's needed:</p> <pre><code>cat store/my.example.com/2015-05-18/my.example.com.key.pem \ store/my.example.com/2015-05-18/my.example.com.crt.pem \ &gt; store/my.example.com/2015-05-18/my.example.com.keycrt.pem</code></pre> <p>You can now copy those three files to the server (you won't need the <code>.csr</code>) and configure your services to use them. That's a bit beyond the scope of this article, but may be something I'll follow up with in a later one.</p> <h2 id="">Revoking and renewing certificates</h2> <p>If a host's certificate has expired, is no longer needed, or has been compromised, you must revoke the current certificate for that host, and generate and publish a new CRL.</p> <p>First check <code>ca/index.txt</code> for the index corresponding to the host you're revoking:</p> <pre><code>more index.txt | grep my.example.com</code></pre> <p>You will see something like this:</p> <pre><code>R 250513123511Z 150516124528Z 01 unknown /C=CN/ST=State/O=MyOrg/OU=my.example.com/CN=my.example.com/emailAddress=email@example.com R 250513124545Z 150516124604Z 02 unknown /C=CN/ST=State/O=MyOrg/OU=my.example.com/CN=my.example.com/emailAddress=email@example.com V 250513124606Z 03 unknown /C=CN/ST=State/O=MyOrg/OU=my.example.com/CN=my.example.com/emailAddress=email@example.com</code></pre> <p>If a line starts with an <code>R</code> it means that certificate has been revoked; look for the one starting <code>V</code> with <code>CN=</code> which matches your host; it will almost certainly be the last one. Then take the short number in the fourth column; in the example above, the index is <code>03</code>.</p> <p>Now you have the index, you can revoke that certificate:</p> <pre><code>openssl ca -revoke ca/newcerts/03.pem&quot; -config ca/caconfig.cnf</code></pre> <p>replacing <code>03</code> with the index for that certificate.</p> <p>If you are replacing the certificate, you can now create a new host certificate exactly as you did in the <em>Creating a host certificate</em> section above.</p> <p>Don't forget to update and publish a new CRL, as described under <em>Publishing your CA Certificate and CRL</em>.</p>Mon, 18 May 2015 12:08:00 +0000http://radiac.net/blog/2015/05/self-ca/POODLEhttp://radiac.net/blog/2014/10/poodle/<p>I have been meaning to get back on the blogging horse for some time, and what better way than with a new SSL vulnerability.</p> <p><a href="http://googleonlinesecurity.blogspot.co.uk/2014/10/this-poodle-bites-exploiting-ssl-30.html">POODLE</a> was announced this morning. It's a 5/10 on the panic scale, but both users and sysadmins should take action now.</p> <p>This one isn't particularly exciting compared to the recent sky-is-falling <a href="http://heartbleed.com/">heartbleed</a> and <a href="http://en.wikipedia.org/wiki/Shellshock_%28software_bug%29">shellshock</a> - instead of giving away all your secrets and/or shell access to anyone with curl, the worst-case scenario with POODLE is that someone can read your SSL traffic; still bad, but for most people running small sites it's nowhere near the same scale.</p> <p>Unlike shellshock and heartbleed though, this doesn't look like something which is likely to be fixed by a distro patch any time soon, because this vulnerability is <a href="https://www.dfranke.us/posts/2014-10-14-how-poodle-happened.html">inherent in SSLv3</a> (I'm no crypto expert, so I won't attempt to explain it myself). Because it is still used in the wild, distros are unlikely to disable it by default in the immediate future, so sysadmins will need to do something about it themselves.</p> <p>This vulnerability doesn't come as a great surprise - SSLv3 is getting on a bit now, and was superseded by TLSv1 which has been supported by most browsers since IE6. However, most clients and servers are designed to fall back to earlier protocols if the newer ones fail - a good idea in theory, but in practice an attacker who wants you to use SSLv3 can force this to happen.</p> <p>While this fallback strategy is likely to be disabled in future distro patches using <a href="http://marc.info/?l=openssl-dev&m=141333049205629&w=2"><code>TLS_FALLBACK_SCSV</code></a>, it will still leave any use of SSLv3 vulnerable. Although Google is using SCSV for maximum compatibility, based on <a href="https://blog.cloudflare.com/sslv3-support-disabled-by-default-due-to-vulnerability/">Cloudflare's numbers</a> where a trivial amount of valid traffic actually uses SSLv3, most people seem to be advocating the removal of SSLv3 altogether.</p> <p>As a user you're vulnerable if you use SSLv3, so you should disable it - you're extremely unlikely to need it anyway. I won't go into details, but Mozilla will disable SSLv3 <a href="https://blog.mozilla.org/security/2014/10/14/the-poodle-attack-and-the-end-of-ssl-3-0/">in Firefox 34</a>, or you can disable it now in <code>about:config</code> by setting <code>security.tls.version.min == 1</code>.</p> <h3>Steps for sysadmins</h3> <p>Systems' traffic is vulnerable if they're running SSLv3, so a reasonable course of action would therefore be to disable SSLv3 at the top level of your server config, then re-enable it on specific sites if you get reports of problems - although it would be best to wait for a stable <code>TLS_FALLBACK_SCSV</code> patch to land before re-enabling it.</p> <p>Those running nginx can disable SSLv3 with <a href="https://github.com/cloudflare/sslconfig/blob/master/conf">Cloudflare's cipher configuration</a> (add to <code>http</code> or <code>server</code> context):</p> <pre><code>ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:EECDH+RC4:RSA+RC4:!MD5; ssl_prefer_server_ciphers on; </code></pre> <p>Apache users can add (to server or virtual host context):</p> <pre><code>SSLProtocol all -SSLv2 -SSLv3 </code></pre> <p>And dirty IIS users get what they deserve - a <a href="https://www.digicert.com/ssl-support/iis-disabling-ssl-v3.htm">17 step procedure</a> where you have to fiddle with the registry.</p> <p>You should of course also take a look at any other services which are likely to support SSLv3, like mail or VPNs.</p> <h3>Testing your connection</h3> <p>As with heartbleed, <a href="https://www.ssllabs.com/ssltest/">Qualys SSL Labs</a> seems to be the place to go for an easy and comprehensive assessment of your SSL security. Alternatively you could use openssl:</p> <pre><code>openssl s_client -connect [server]:[port] -ssl3 </code></pre> <p>If you run that command and connect successfully, you're still vulnerable.</p>Wed, 15 Oct 2014 07:45:59 +0000http://radiac.net/blog/2014/10/poodle/