SSL And The Future Of Authenticity

A good talk.

Advertisements

Securing My Blog

In order to improve the security of my blog, I have tried a few measures.

A while ago, I bought a Yubi-Key, which generates a one-time-password to be used alongside the regular login. This provided two-factor authentication and it was certainly working for a while. Then, I read up more about the Yubi-Key and found that there might be holes in the implementation of the plugin since it is still quite a new product and relatively untested.

So, I switched to using VPN instead. I configured my web-server to reject all attempts to access the administrative pages unless the connection originated from the local server. Then, I would use SSH to create a tunnel into the server and secure my connection through SSH keys. This also required two-factor authentication and provided the additional fact that the entire connection was secured over SSH.

I added this to my lighttpd configuration.

# Deny access to wordpress admin pages
$HTTP["host"] =~ "blog.sybreon.com|tech.sybreon.com" {
$HTTP["remoteip"] !~ "213\.229\.116\.90$" {
$HTTP["url"] =~ "^/wp-admin/|^/server-" {
url.access-deny = ("")
}
}
}

However, I had troubles accessing my blog from certain places because they blocked SSH connections.

Finally, I switched to SSL instead. I have now configured my web-server to only accept connections that present a valid security certificate over SSL. Again, this is a two-factor authentication using SSL certificates. Once again, the connection is also secured over SSL. I park my web server behind a pound reverse-proxy. So, this is the way I did it.

ListenHTTP
Address ::
Port 80
## allow PUT and DELETE also (by default only GET, POST and HEAD)?:
xHTTP 0

Service
URL "^(?!/wp-admin).*"
HeadRequire "Host:.*(blog|tech).sybreon.com"
BackEnd
Address ::1
Port 8080
End
End

End

ListenHTTPS
Address ::
Port 443

Cert "/etc/ssl/private/blog.crt"
CAlist "/etc/ssl/private/sybreon.ca.asc"
VerifyList "/etc/ssl/private/sybreon.ca.asc"
Ciphers "HIGH"
ClientCert 2 3

Service
HeadRequire "Host:.*(blog|tech).sybreon.com"
BackEnd
Address ::1
Port 8080
End
End
End

What this does is to reject all connections to the admin pages for my blogs if they came over regular HTTP and to only allow connections over HTTPS. However, for HTTPS connections, client certifications are required, which are signed by a my own custom CA. Otherwise, the connection will fail if a client certificate is not presented.

The advantage of doing it this way is that I can actually have collaborators. All I need to do is to generate new certificates for them and email it to them. This process can even be automated if need be.

PS: You can try accessing the admin page over HTTP and HTTPS here, to see how this works.

Lighttpd Server Name Indication (SNI)

I installed a new web-server today and tested out its SNI features. SNI solves the problem of hosting multiple virtual hosts on the same server running SSL. In the past, it was not possible to present a different certificate for each virtual host, necessitating the use of other techniques.

This was how I did it at first:

$SERVER["socket"] == "10.0.0.1:443" {
ssl.engine = "enable"
ssl.pemfile = "www.example.org.pem"
}
$HTTP["host"] == "foo.example.org" {
ssl.pemfile = "foo.example.org.pem"
}
$HTTP["host"] == "bar.example.org" {
ssl.pemfile = "bar.example.org.pem"
}

However, after setting it up, it successfully presented different certificates but it seemed to present the wrong ones for different virtual hosts. After mucking about the Internets, I came to the conclusion that my configuration file was in error. A proper SNI configuration should be configured as such:


$SERVER["socket"] == "10.0.0.1:443" {
ssl.engine = "enable"
ssl.pemfile = "www.example.org.pem"

$HTTP["host"] == "foo.example.org" {
ssl.pemfile = "foo.example.org.pem"
}

$HTTP["host"] == "bar.example.org" {
ssl.pemfile = "bar.example.org.pem"
}
}

After that it worked magically. Wow for nested configs!

Update: Turns out that I spoke too soon. The problem still persists.

SSL CipherSuite

Just read a nice article on speeding up SSL operations on Apache. There were a number of different techniques proposed but the one that caught my eye – being immediately usable – was to replace the ciphers with faster ones.

Security has always been a game of trade-offs. In this case, trading off ciphers with higher security and larger keys with smaller and faster ones. As long as it provides a sufficient amount of security, not everyone needs AES256.

So, after configuring Apache away from AES256 to using RC4 instead, I got about a 20% performance boost in the sense that I could now have increased concurrency since the server was now able to process the SSL connections faster.

This got me thinking about embedded security. I think that for embedded servers, like those found on routers and such, using something like RC4-SHA would be more than sufficient for protecting something like password logins from casual snooping. These small embedded devices are just not made for serving highly secure services – unless they came with hardware accelerators.

Something to think about further.

SSL Key Size

I have been doing some Apache optimisation recently and I thought that I will note down various tweaks for documentation purposes only. These tweaks will be written down as I find them.

Using larger RSA keys slow things down.

In my benchmark system, I only get around 500-600 connections/second for a 4096-bit RSA key but get a 800-900 connections/second for a 1024-bit RSA key. Seeing that our server certificates are issued only annually, there is no reason to use a 4k RSA key. Although a 768-bit RSA key is breakable today, a 1024-bit one still stands for now and will probably do so for a couple more years.

So, stick to using 1024-bit RSA keys for SSL until it gets broken.