# ROFLCopTor
ROFLCopTor aims to be a comprehensive Tor control port filter daemon written in golang.
# Introduction
The Tor control port exposes powerful functionality, much more
authority than most applications need when they talk to the Tor
control port. In accordance with the principal of least authority each
software module would ideally have authority over only the resources
needed to perform its tasks. Here in the context of ROFLCopTor, we
seek to eliminate excess authority from applications which utilize the
Tor control port, therefore they will not be in the debian-tor group
or otherwise have access to the tor control port UNIX domain socket or
TCP listener. The only available access to the tor control port being
via ROFLCoptor which exposes a TCP listener and or a UNIX domain
socket listeners. Each listener has a filtration policy which is
applied for bidirectional filtration of Tor control port commands and
responses.
# Usage
A simple usage:
```
./roflcoptor -help
Usage of ./roflcoptor:
-config string
configuration file
-watch
watch-mode of operation will default to unfiltered-allow policy
```
Normally watch-mode is only used when creating new filter rule sets.
# Configuration
Until a debian package does this automatically, here are the steps to manually set things up.
First, create a new user.
```
adduser --system --group --disabled-password --disabled-login --home /etc/roflcoptor/ --no-create-home --quiet roflcoptor
```
In this configuration example tor's control port is NOT set to TCP
port 9051, but instead listens on a UNIX domain socket which only the
debian-tor group has read/write access to, therefore the
``roflcoptor`` user must be in the debian-tor group. After running the
above commands, `grep roflcoptor /etc/group` should look like this:
```
debian-tor:x:111:roflcoptor
roflcoptor:x:119:
```
Create directories and copy files from source repo:
```
mkdir /var/run/roflcoptor
chown roflcoptor:roflcoptor /var/run/roflcoptor
mkdir -p /etc/roflcoptor/filters
cp roflcoptor_config.json /etc/roflcoptor
cp filters/*json /etc/roflcoptor/filters
```
Here we also turn off ``cookie authentication`` because filesystem permissions are sufficient
for limiting access. Configure your ``/etc/tor/torrc`` like this:
```
# ControlPort 9051 # disable this
ControlPort unix:/var/run/tor/control.socket GroupWritable
CookieAuthentication 0
```
Run roflcoptor as the ``roflcoptor`` user and group. Here's my systemd example.
Place the systemd unit file for roflcoptor daemon in /etc/systemd/system/roflcoptor.
It should look something like this:
```
[Unit]
Description=roflcoptor - onion router control port filtration daemon
After=tor.service
[Service]
Type=simple
User=roflcoptor
PermissionsStartOnly=true
ExecStartPre=-/bin/mkdir /var/run/roflcoptor
ExecStartPre=/bin/chown roflcoptor /var/run/roflcoptor
ExecStart=/usr/local/bin/roflcoptor -watch -config /etc/roflcoptor/roflcoptor_config.json
```
NOTE: The ``-watch`` flag was passed to roflcoptor so that applications which do not have a policy yet such as
Oz sandboxed applications will operate in watch-mode where the policy is pass-thru and all other applications
will have their filter policy applied. We must resolve ticket https://github.com/subgraph/oz/issues/37
and implement the Oz UNIX domain socket proxy!
Create and chown the roflcoptor related directories:
```
mkdir -p /etc/roflcoptor/filters /var/run/roflcoptor
chown -R roflcoptor:roflcoptor /etc/roflcoptor /var/run/roflcoptor
```
The json configuration file, /etc/roflcoptor/roflcoptor_config.json should look like this:
```
{
"FiltersPath" : "/etc/roflcoptor/filters",
"TorControlNet" : "unix",
"TorControlAddress" : "/var/run/tor/control",
"Listeners" : [
{
"Net" : "unix",
"Address" : "/var/run/roflcoptor/roflcoptor.socket"
},
{
"Net" : "tcp",
"Address" : "127.0.0.1:9051"
}
]
}
```
# Acknowledgements
ROFLCopTor is derived from @Yawning's [or-ctl-filter](https://github.com/Yawning/or-ctl-filter) and @david415's [or-ctl-sieve](https://github.com/david415/or-ctl-sieve) which was derived from collaboration with Leif Ryge in making this proof of concept filter [twistedcat-armfilter-hax](https://github.com/david415/twistedcat/tree/armfilter-hax).
# Building
Building from source is the same as any golang project. Provided with this project is a debian branch
from which you can build packages:
```
apt install debhelper dh-golang dh-systemd golang-go tor adduser
# # To build the Debian package:
git clone -b debian https://github.com/subgraph/roflcoptor.git
cd roflcoptor
## To build from stable
gbp buildpackage -us -uc
## To build from head
git checkout master
git checkout debian
gbp buildpackage -us -uc --git-upstream-tree=master
## Install the package
dpkg -i /tmp/build-area/roflcoptor-*_amd64.deb
```