Trading Fish The blog of Hector Castro

Installing Tor on FreeBSD 11

Tor is a piece of free software and an open network that enables anonymous communication. Combined, these two components help defend against various forms of traffic analysis and network surveillance. Trying to re-explain Tor in a comprehensive way is outside the scope of this post, but please read about it via the literature provided by the project site and The Electronic Frontier Foundation (EFF) before installing.

Installation

The first step toward installing Tor on FreeBSD is deciding whether you want to install the precompiled package with pkg, or you want to compile it yourself from the FreeBSD Ports Collection. The tradeoffs between these two approaches are well-explained within the FreeBSD Handbook. I chose the package because customizing the installation configuration beyond the defaults didn’t seem necessary.

With all of that said, from inside a root shell install the Tor package with:

# pkg install tor

Configuration

From there, copy the sample Tor configuration file into its default location and open it inside your editor:

# cp /usr/local/etc/tor/torrc.sample /usr/local/etc/tor/torrc
# vim /usr/local/etc/tor/torrc

Once inside the file, there are three settings that we want to make explicit. All should be commented out by default (SOCKSPort,Log, and Log again), so we simply need to uncomment them. Below is a diff of the changes between the sample and our desired configuration file:

18c18
< SOCKSPort 9050
---
> #SOCKSPort 9050 # Default: Bind to localhost:9050 for local connections.
38c38
< Log notice file /var/log/tor/notices.log
---
> #Log notice file /var/log/tor/notices.log
42c42
< Log notice syslog
---
> #Log notice syslog

The SOCKSPort setting ensures that we’re binding Tor to 127.0.0.1 on its default port of 9050. The two Log settings ensure that notice level log messages are written to a specific log file, as well as syslog.

Now, we can launch Tor using the tor command to see if things are working properly:

% tor
[notice] Tor v0.2.8.9 running on FreeBSD with Libevent 2.0.22-stable, OpenSSL 1.0.2j-freebsd and Zlib 1.2.8.
[notice] Tor cant help you if you use it wrong! Learn how to be safe at https://www.torproject.org/download/download#warning
[notice] Read configuration file "/usr/local/etc/tor/torrc".
[notice] Opening Socks listener on 127.0.0.1:9050
[notice] Parsing GEOIP IPv4 file /usr/local/share/tor/geoip.
[notice] Parsing GEOIP IPv6 file /usr/local/share/tor/geoip6.
[notice] Bootstrapped 0%: Starting
[notice] Bootstrapped 80%: Connecting to the Tor network
[notice] Bootstrapped 85%: Finishing handshake with first hop
[notice] Bootstrapped 90%: Establishing a Tor circuit
[notice] Tor has successfully opened a circuit. Looks like client functionality is working.
[notice] Bootstrapped 100%: Done

Once satisfied, CTRL+C the process so that control is returned to your shell.

Lastly, let’s enable the Tor service so that it starts on its own after the system boots. To achieve that, all we have to do is ensure that /etc/rc.conf contains the following line:

tor_enable="YES"

Afterwards, launch the Tor service through the service manager if you want it running prior to the next boot cycle:

# service tor start

That’s it. You should now have a fully functional installation of Tor running on FreeBSD.

Raft Leader Election in Consul

A small paper reading group has assembled at work. We give ourselves two to three weeks to read a paper, meetup after hours, eat pizza, and discuss it. Our last paper focused on the Raft consensus algorithm, and I was chosen to lead the discussion.

In order to help the impact of Raft hit closer to home, I put together a small demo of Raft’s leader election process using Consul. The demo spins up a three node Consul cluster using containers, then interleaves all of the debug log output filtered with grep for raft. Reading through parts of the Raft paper, you can see how the logging output of HashiCorp’s implementation lines up.

Reading Along

Section 5.2 of the Raft paper focuses on leader election, and starts off with:

When servers start up, they begin as followers.

Sure enough, the first raft filtered logs start with:

$ docker-compose up | grep raft
consul1 | [INFO] raft: Node at 172.17.0.45:8300 [Follower] entering Follower state
consul2 | [INFO] raft: Node at 172.17.0.44:8300 [Follower] entering Follower state
consul3 | [INFO] raft: Node at 172.17.0.43:8300 [Follower] entering Follower state

Next is the the beginning of an election:

If a follower receives no communication over a period of time called the election timeout, then it assumes there is no viable leader and begins an election to choose a new leader.

That corresponds with:

consul1 | [WARN] raft: Heartbeat timeout reached, starting election

Now that the election started, there needs to be a winner:

A candidate wins an election if it receives votes from a majority of the servers in the full cluster for the same term.

Which goes with:

consul1 | [DEBUG] raft: Votes needed: 2
consul1 | [DEBUG] raft: Vote granted. Tally: 1
consul1 | [DEBUG] raft: Vote granted. Tally: 2
consul1 | [INFO] raft: Election won. Tally: 2
consul1 | [INFO] raft: Node at 172.17.0.45:8300 [Leader] entering Leader state

Lastly, AppendEntries is used to communicate the new leader to all other candidates:

While waiting for votes, a candidate may receive an AppendEntries RPC from another server claiming to be leader.

Logs from consul1 show that it is replicating to consul2 and consul3:

consul1 | [INFO] raft: pipelining replication to peer 172.17.0.44:8300
consul1 | [INFO] raft: pipelining replication to peer 172.17.0.43:8300

Updating the Amazon RDS Certificate Bundle

On March 23rd, 2015 20:00 UTC, Amazon plans to update the SSL certificate for RDS instances. This means that applications attempting to establish secure connections to Amazon RDS databases from servers without an updated RDS certificate bundle may begin to fail. In order to prevent connection failures to Amazon RDS databases, an updated certificate bundle can be installed on client servers in advance.

Test Connections to Amazon RDS

First, I recommend starting a new Amazon RDS database with the rds-ca-2015 certificate authority configured. For this example, I’m going to use a PostgreSQL Amazon RDS database.

Using the psql command, execute the following steps from a server intended to communicate securely with Amazon RDS:

$ export PGSSLROOTCERT="/etc/ssl/certs/ca-certificates.crt"
$ export PGSSLMODE="verify-full"
$ psql -h test.cvg4pxyrtpes.us-east-1.rds.amazonaws.com -U test

If you are met with the following message, then you need to install the updated certificate bundle:

psql: SSL error: certificate verify failed

Updating the Certificate Bundle

On a Ubuntu server, the update-ca-certificates command can be used to update the local CA certificates. First, we need to download the updated Amazon RDS combined CA bundle, then we need to put it in a place where update-ca-certificates knows to pick it up:

$ wget http://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem
$ sudo mv rds-combined-ca-bundle.pem \
    /usr/local/share/ca-certificates/rds-combined-ca-bundle.crt
$ sudo update-ca-certificates

Note: The file extension for rds-combined-ca-bundle changes from .pem to .crt.

Now, if we run the test above once more on the same machine, you should be met with a password prompt, and a successfully established secure connection to the Amazon RDS PostgreSQL database.

Lastly, if you use Ansible for configuration management, take a look at the azavea.rds-ca-bundle role to help automate updating the Amazon RDS certificate bundle on client servers.