Public Cert Trust Stores in Ruby: What am I trusting and should I be? The internet is scary

When I was a senior in college (longer ago than I should admit to) I did a demonstration about sniffing user’s facebook traffic when they were using wifi at my college. At the time Facebook didn’t redirect HTTP -> HTTPS by default and most users were connecting over plaintext.

Since then Facebook has switched to secure browsing by default, and most companies are encrypting traffic in transit whether it’s internal or external. With that sprawl of encryption it’s can be important to have some understanding of how root signing certificates work, and understand what root certificates your system is trusting. For this post we’ll work with HTTPS clients in Ruby (specifically HTTParty).

When should you care about what your library trusts?

Most of the time you don’t need to worry about it. HTTP libraries and most OS’s come with a default set of public certs they trust. If you’re curious (and on windows) you can check your machine’s listing by running Start -> MMC and adding the certificates snap in for your computer account

It’s a pretty standard list of names you might recognize like DigiCert, GlobalSign, etc. These let your computer trust a normal list of services, and as long as a service takes the time to get a certificate from one of these CA’s you’ll be able to connect to it.

So when should you be worried about what certs your library trusts?

  1. When you might be working with Self Signed certs (like on an internal network)
  2. When you have a very old client that may not have an up to date list
  3. If you’re service is using a newer trust authority like LetsEncrypt

Starting at the top

HTTPary has an initialize method that let’s you set the HTTP scheme (HTTPS/HTTP)

https://www.rubydoc.info/github/jnunemaker/httparty/HTTParty/Request#initialize-instance_method

Which lets you decide if you’re going to make a secure or a plaintext request

Finding our defaults

Now that we know we’re going to make a secure request, we need to understand what our library will do by default. There are two methods for setting a CA file, or a CA path

https://www.rubydoc.info/github/jnunemaker/httparty/HTTParty/ClassMethods#ssl_ca_file-instance_method

https://www.rubydoc.info/github/jnunemaker/httparty/HTTParty/ClassMethods#ssl_ca_path-instance_method

Unfortunately there is no description in the doc of what the library will use by default. That’s not really a knock on the developer, most of the time you don’t have to worry about it.

For let’s dive into the source code: https://github.com/jnunemaker/httparty/blob/master/lib/httparty.rb#L427

And there we see a method that will set the default options.

To be frank, this is where my Ruby knowledge breaks down. The next reference I can find to the default cert store is here

https://github.com/jnunemaker/httparty/blob/master/lib/httparty/connection_adapter.rb#L81

@default_cert_store ||= OpenSSL::X509::Store.new.tap do |cert_store|

Searching that ruby class brings me to this page: https://ruby-doc.org/stdlib-2.4.0/libdoc/openssl/rdoc/OpenSSL/X509/Store.html, which says you can normally find the defaults by looking at OpenSSL::X509::DEFAULT_CERT_DIR

Plenty of searching in Ruby-doc.org hasn’t shown me what that value is – so when all else fails we can just go take a look. Let’s power up a ruby docker container with

docker run -it ruby /bin/bash

Then we jump into the interactive ruby console by typing irb and importing OpenSSL package by typing require 'openssl'. Lastly we can print what the default cert directory with print(OpenSSL::X509::DEFAULT_CERT_DIR)

irb(main):002:0> print(OpenSSL::X509::DEFAULT_CERT_DIR)
/usr/lib/ssl/certs=> nil

And it turns out /us/lib/ssl/certs is a link to /etc/ssl/certs

root@caf6415446ff:/# ls -l /usr/lib/ssl/certs
lrwxrwxrwx 1 root root 14 Oct 12 19:56 /usr/lib/ssl/certs -> /etc/ssl/certs

Which has a ton of certs in it

root@caf6415446ff:/# ls -l /etc/ssl/certs/ | wc -l
258

And there you have it! Now you can comb through the certs in this directory.

Final thoughts

Certs are intimidating when you get started because they seem like magic, and they’re plenty complicated. But at the same time you can abstract some of that complexity away by understanding some basics like when your cert trust store matters.

I went into some detail on finding the default trust store because I think it’s helpful to see that you can make a lot of progress understanding certs just by digging through a repo and looking at source code.

Hosting a User Group on Zoom (when it’s normally in person)

I’m not looking to add to the noise around using zoom to work remotely and connect with people during social distancing, but after spending some time on Google I couldn’t find a guide on how to do this. These are pretty much my own notes while I’m prepping to try and host a user group through zoom.

Here’s my “minimal video call host check list”

  1. Let people know what they’re getting into (state that you’d like people to turn on video in the agenda, tell them what will happen during the meeting, ask for their patience while everyone gets used to the video chat)
  2. Be “that guy” – engage the participants, ask questions, be the energetic one to get the conversation going
  3. A few awkward silences are ok – they happen in real life too
  4. Have fun! We’re all stuck at home, make the best of it

About once a quarter I organize an AWS User Group. We get a group of people together (usually 20 – 30), a sponsor brings pizza, someone spends a few minutes talking about a tech topic, and we nerds get some social time.

With social distancing we cancelled our in person Meetup, but it’s hard to tell how long that will go on, so I’m working on getting some kind of virtual gathering on zoom. Here’s my current plan

  1. Start an open zoom meeting (I have a licensed account from work)
  2. Prevent participants from sharing (Next to screen share click up arrow -> Advanced Sharing Options -> Who can share -> Only Host (this lets cohosts share too)
  3. Let people social network for the first few minutes – I looked into breakout rooms, but I think that’s a different license level

At this point you have a pretty normal zoom meeting where people can chat. Our user groups start with 20 or so minutes of social networking at the beginning. When we’re ready to start the presentation

  1. Make the presenter the cohost (under Manage Participants -> Hover over the name -> Click more -> Click “Make Cohost”
  2. On the manage participants tab click “Mute all” and uncheck “Allow participants to unmute themselves”

At this point you have as close to a “presenter up front, audience watching” setup as I could get with zoom. People can watch and listen, but not interrupt. The host can glance at the audience reactions, but they can ignore them if they choose.

If you want to have more social time at the end have the presenter stop sharing (so people can switch back to speaker view or gallery) and

  1. Click Mute all and make sure “Allow participants to unmute themselves” is checked, that will let people jump back into audio
  2. Be social as long as everyone is interested!