TvE 2100 » At 2100 feet above Santa Barbara
Bosque del Apache National Wildlife Refuge, Feb 2004, ©2004 Thorsten von Eicken 

Verifying SSL certs when using Net:HTTP

Posted: December 25th, by tve
Tags: #

What good is an HTTPS web service if you’re not verifying the certificate presented by the web service? That’s what I was wondering when I started to use the Amazon Elastic Compute Cloud web service and used a sample that used simple HTTP. So I looked into the docs and quickly found that the trick is to set http.verify_mode = OpenSSL::SSL::VERIFY_PEER when creating the https connection object. Unfortunately that turned out not to be so simple, because the only effect I got is an error on every connection attempt telling me that the peer’s certificate cannot be validated. Very useful!

Black-necked Stilts
Black-necked Stilts, Devereux Slough, Santa Barbara, CA ©2005 Thorsten von Eicken

Of course my next step was a Google search, but after a long time all I found is that everyone turns the verification off! I then proceeded to look at the source code to figure out what is going on, and I finally gave up after a couple of hours. Finally, the Pragmatic Studio alumni mailing list came to the rescue: Devin Mullins gave me the critical tip that made it work: one has to give the certificate file a special name, duuuh. Here is in detail what I did to get it to work:

I have a file ‘cacert.pem’ that has all the root certs I care about. I ran the following command:

# openssl x509 -hash < cacert.pem
f73e89fd
-----BEGIN CERTIFICATE-----
MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzELMAkG
A1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYD
VQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk0
MTEwOTAwMDAwMFoXDTEwMDEwNzIzNTk1OVowXzELMAkGA1UEBhMCVVMxIDAeBgNV
BAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2Vy
dmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGbMA0GCSqGSIb3DQEBAQUAA4GJ
ADCBhQJ+AJLOesGugz5aqomDV6wlAXYMra6OLDfO6zV4ZFQD5YRAUcm/jwjiioII
0haGN1XpsSECrXZogZoFokvJSyVmIlZsiAeP94FZbYQHZXATcXY+m3dM41CJVphI
uR2nKRoTLkoRWZweFdVJVCxzOmmCsZc5nG1wZ0jl3S3WyB57AgMBAAEwDQYJKoZI
hvcNAQECBQADfgBl3X7hsuyw4jrg7HFGmhkRuNPHoLQDQCYCPgmc4RKz0Vr2N6W3
YQO2WxZpO8ZECAyIUwxrl0nHPjXcbLm7qt9cuzovk2C2qUtN8iD3zV9/ZHuO3ABc
1/p3yjkWWW8O6tO1g39NTUJWdrTJXwT4OPjr0l91X817/OWOgHz8UA==
-----END CERTIFICATE-----

The trick is that the file basename must be the hash printed out by the above command plus an appended .0! So my next move was:

# mv cacert.pem f73e89fd.0

I then adjusted my code as follows:

  http = Net::HTTP.new(link.host, link.port)
  if link.scheme == 'https'
    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_PEER
    http.ca_file = "#{RAILS_ROOT}/lib/ec2/f73e89fd.0" 
  end
  http.start
  response = http.get(link.request_uri)

This now works like a charm! Phew!

Update:

Upon further inspection, it looks like the above only works for the first certificate in my original cacert.pem file and I was lucky that that’s the one I need for EC2. What I need to do to use all the certs in the file is break it up, one cert per file, use openssl to figure out the filenames, and then use http.ca_path instead of http.ca_file to point to the directory with all the cert files.

Course on Scalable Internet Services (in Ruby on Rails)

Posted: December 20th, by tve
Tags: #

Phew, I just finished teaching a graduate course on building scalable internet services at UCSB (Univ. of California At Santa Barbara). This was a very hands-on, learn-by-doing course with a significant project in Ruby on Rails! The goal was for the students to learn about all the technologies that go into a scalable internet service, specifically into dynamic web sites. The lectures provided background information to support the project and they explained technologies beyond the scope of the project.

Hummingbirds
Anna’s Hummingbirds, Joshua Tree, CA, Mar 2005, ©2005 Thorsten von Eicken

The project consisted of building a transactional dynamic web site in Ruby on Rails and running on Amazon’s Elastic Compute Cloud (EC2). Each site had to hold >100’000 database records that could be searched and explored, have user accounts, and include some form of transaction, such as a shopping cart check-out.

Each project then had to be deployed on multiple servers on EC2 and the groups had to use httperf to demonstrate that they could scale the performance of their site by running a front-end load balancer server, a database server, a memcached server, and up to 10 application servers. All this had to fit into a 10-week quarter, with none of the students knowing either Ruby or Rails at the outset!

Note that the emphasis of the course was on the scalability aspect of the sites and not on the web design or feature-set. Thus it was more important to understand the performance characteristics and optimize the core of the site than to have the most eye-candy. (Although eye-candy is always appreciated, of course…)

Please check out the course wiki for more information, including all course materials!

Installing a new version of the EC2 AMI Tools

Posted: November 13th, by tve
Tags: #

The Amazon Web Services EC2 AMi Tools are the set of tools needed to create a new Xen image for Amazon’s Elastic Compute Cloud.

To install a new version, the following commands are recommended:

rpm -q ec2-ami-tools
wget http://s3.amazonaws.com/ec2-downloads/ec2-ami-tools.noarch.rpm
rpm -Uvh ec2-ami-tools.noarch.rpm
rpm -q ec2-ami-tools

That’s it!

Why running mysql on Amazon EC2 and S3 is not that simple

Posted: September 22nd, by tve
Tags: #

Jeff posted a blog entry that implies that it’s not that difficult to run mysql on Amazon EC2. Ha! Possible : yes. Easy: noooo! The devil is in the details, many of them!

For example, MyISAM tables do not replicate correctly because the replication (binary) log does not obey transactions. You can have a transaction that rolls back on the master but it’s in the log and happily executed on the slave. Ouch!

Even if you use InnoDB tables, you are not safe. For example, you can write non-deterministic SQL statements that may produce different results on the slave than on the master. An example is creating a table with an auto-increment key using a select from another table. The keys assigned depend on the order in which the select produces results. This may be different on the slave than the master and you end up with different keys, which is not going to match subsequent operations! (A friend ran into this one, one slave matched the master while two others became inconsistent quickly, he spent hours and hours figuring out what went wrong!)

You also assume multiple EC2 instances in your description, but there is no control over their location. They may well be on the same power circuit that goes out. What about the S3 node? I forget the semantic details: when S3 ACKs the store request, does it guarantee that the data is replicated already or does it only guarantee that it is on persistent storage? In other words, could it be on a machine in the same datacenter on the same UPS that goes down with the EC2 mysql box and doesn’t come back up until the UPS is repaired a few hours later? In that case, yes, the data would be safe on S3, but unavailable for a few hours. That wouldn’t help me in quicly restoring from S3 onto a new mysql instance, would it?

Someone else also mentioned restore time on the EC2 forum. How long would it take to restore a 70GB database? (70GB is probably the max you can put on an EC2 instance if you ever want to be able to make a backup copy without jumping through hoops.) My guess is at least 10-15 minutes, and that doesn’t count the time to apply the logs.

Oh, talking about logs, when do you start your logs? You need a clean full backup and then you can start the (incremental) replication logs. After a while, you really should start afresh so you don’t collect endless logs that would take forever to apply. If your app is not 24/7 it’s easy, but if it’s 24×7 you need to do what’s called a hot-backup. Ahhh, no such support in mysql/innodb unless you pay for it.

And performance? Did you know that a mysql slave can easily be slower than the master? The reason is that the slave reads and applies the replication log using a single thread. So while your app server bangs on your master with high concurrency, your slave performs one operation at a time. Usually this is not an issue because the master has the additional load of reads, but the problem does exist.

The bottom line is that in theory everything is available to set-up a nice mysql installation on EC2/S3, but in practice it’s far from easy to actually pull it off in a reliable manner.

Top missing features for Amazon EC2

Posted: August 25th, by tve
Tags: #

We need Static IPs. Dynamic IPs don’t work for a reliable web server. Hopefully a solution will come combined with a simple load balancing option.

SQL database: I think that what’s really missing is a SQL database service. Yes, I can run mysql or similar on EC2, but it’s really not a good fit. The lack of persistence is not a show-stopper but it is a pain right now. But more importantly, the machine specs for CPU speed, memory size, number of spindles, and disk space just don’t cut it. There isn’t enough oomph there to run a real database-backed web service. Amazon needs to step up and offer a D2B service: Distributed DataBase. I’ll pay for storage at 2x the cost of S3 (since DB storage tends to be more expensive) and $.20 per MegaTransactions (equivalent to $0.20 for 1 hour at 277 tps). Well, 2006 isn’t over yet, is it :-)

The lack of persistence is not an real showstopper issue. The only set-up I could imagine that would really improve things is if they had SAN type of storage attached to their machines. This way the machine can be fried and your data is still intact on the SAN and can be mounted on a fresh machine. Use RAID on the SAN to safeguard against failures there or against datacenter-wide outages. At that point, failures should be down sufficiently in probability that a “disaster recovery” type of backup is sufficient. For example incremental backups to S3 every 10-30 minutes. Alternatively all enterprise class SANs have mirroring options. You could pay Amazon a few more bucks to be allocated on a wide-area mirrored SAN partition. But all this gets into big bucks quickly, even on an Amazon scale, so I don’t think we’ll see that anytime soon.

I believe the persistence issue will be solved though log replication. Replicate database logs to another instance or to S3 in a real-time manner and have EC2 give you some control over the placement of instances so that a cluster pair has some degree of failure isolation. For files use a log-based filesystem and also replicate the logs. Ok, all that will take some time for people to sort out, but when they/we do, everyone will benefit, not just EC2 users because all this is not just an EC2 problem. Your machine at joe-hosting.com is just as affected. Just that usually when it crashes your disk doesn’t get wiped, or if the motherboard dies joe moves the HD to the new box for you. Just wait until something more interesting happens, or the datacenter goes out for a few hours and the data is as good as gone because you have to bring up your disaster recovery datacenter after 30 minutes of outage and once traffic hits it you can’t merge any data recovered from the old box back in anymore.


More thoughts on EC2 pricing

Posted: August 25th, by tve
Tags: #

[This is from a comment I left on Jonathan’s blog.]

I have to admit I am disappointed at the pricing of EC2. At this rate it costs $72/mo for a not so hot machine, without persistent disk storage, and without bandwidth. Once you add bandwidth and storage you easily exceed the costs of a dedicated server at a decent hosting company

Compare this to S3 where you have to pay at least 2x for anything remotely similar. With EC2 there is no such 2x factor.

So the only advantage over another hosting company is that if the thing fails you have a higher chance of being able to get a new box up and running within minutes, and if your usage skyrockets it’s quick to get more machines online. But we really don’t know about the reliability and scalability of EC2 since Amazon doesn’t reveal any details whatsoever. At this point it could well be that they have all of EC2 in a couple of racks at a single location…

Amazon Elastic Compute Cloud just launched

Posted: August 24th, by tve
Tags: #

See the EC2 announcement on the Amazon Web Services site. Pretty cool to have “infinite” compute resources available (credit card limit permitting)! Basically you get a Xen virtual linux image that you store on Amazon S3 and can “intantiate” on a server. The server is actually dedicated, so the Xen virtual image is just used in order to conveniently load the image and control the set-up.

The specs of a server are “the equivalent of a system with a 1.7Ghz Xeon CPU, 1.75GB of RAM, 160GB of local disk, and 250Mb/s of network bandwidth.” The virtual server image that is on S3 and that gets instantiated is limited to 10GB. Once running, there is a swap partition (2GB, I believe) and a 160GB “ephemeral” partition that is mounted as well. The ephmeral partition is lost if the server crashes and the machine instance is restarted on a different server. This means that for persistent storage one better use S3 or multiple instances.

Overall this sounds a bit more expensive than I had hoped. For $120/mo you get a dedicated box with 2TB transfer at various hosting facilities (without trying to get rock-bottom). At Amazon it costs you $72/mo if you run an instance 24/7. If you then did 2TB of transfer that would slap on another $200, ouch! Looks like the a good idea would be to run the base servers at some traditional hosting facility and to leverage Amazon for peaks only.

SOne of the things that is missing from EC2 is static IPs. Every instance gets a dynamic IP allocated. That makes it difficult to run a reliable external-facing web server. One can use dynamic DNS services, but with the amount of caching going on in the DNS system that’s really not a satisfactory solution. Hopefully AWS will add some form of load balancing solution with static IPs soon!