An open API service indexing awesome lists of open source software.

https://github.com/shadow/oniontrace

Extracts and logs information from Tor's control port. Records and plays back Tor circuit building and stream assignment.
https://github.com/shadow/oniontrace

Last synced: 11 months ago
JSON representation

Extracts and logs information from Tor's control port. Records and plays back Tor circuit building and stream assignment.

Awesome Lists containing this project

README

          

## OnionTrace

![](https://github.com/shadow/oniontrace/workflows/Builds/badge.svg)

This program records and plays back Tor circuit building and stream assignment.
It can also register for several asynchronous Tor events and logs the events
as they are received from Tor over time.

## Setup

Dependencies in Fedora/RedHat:

sudo yum install cmake glib2 glib2-devel

Dependencies in Ubuntu/Debian:

sudo apt-get install cmake libglib2.0-0 libglib2.0-dev

Build with a custom install prefix:

mkdir build && cd build
cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/.local
make

Optionally install to the prefix:

make install

## Usage

oniontrace arguments should be configured as follows:
arguments="oniontrace key=value ..."

The valid keys and the type of the valid values are listed below, along with
any defaults. The format is:
+ `key`:ValueType (default=`val`) [Mode=`ValidMode`] - explanation

Specifying the run mode is **optional**, the default mode is `log`:

+ `Mode`:String (default=`log`) [Mode=`record`,`play`,`log`]
Valid values for the running mode are `record`, `play`, and `log`.
`record` mode records circuit creation and stream assignment schedules.
`play` mode creates circuits and assigns streams according to a
schedule as previously recorded with `record` mode.
`log` mode registers for async events and logs them to stdout as they occur.

The following are **required** arguments (default values do not exist):

+ `TorControlPort`:Integer [Mode=`record`,`play`,`log`]
The Tor Control server port, set in the torrc file of the Tor instance that
you want to trace.

The following are **optional** arguments (default values exist):

+ `LogLevel`:String (default=`info`) [Mode=`record`,`play`,`log`]
The log level to use while running oniontrace. Valid values are:
`debug` > `info` > `message` > `warning`
Messages logged at a higher level than the one configured will be filtered.

+ `TraceFile`:String (default=`oniontrace.csv`) [Mode=`record`,`play`]
The filename to write the trace when in `record` mode, or read a previously
recorded trace when in `play` mode.

+ `RunTime`:Integer (default=`0`) [Mode=`record`,`play`]
If positive, OnionTrace will stop running after the number of seconds
specified in this value. In `record` mode, this has the effect of recording
all circuits that are being tracked even if those circuits have not yet
been closed by Tor.

+ `Events`:String (default=`BW`) [Mode=`log`]
The asynchronous Tor events for which we should listen and log when
we receive them from Tor. The value string should be a comma-delimited list
of events, e.g., 'BW,CIRC,STREAM'. See Section 4.1 of the
'Tor control protocol' specification for a full list of acceptable events.
(https://gitweb.torproject.org/torspec.git/tree/control-spec.txt)

## Tor Changes Required for record Mode

In order for the `record` mode to work correctly, we need Tor to export the
socks username in all stream control events. That will allow us to keep the
the same streams on the correct circuits when using `playback` mode to play
back a recorded trace file.

If the original stream control event is this:

```
650 STREAM 21 NEW 0 11.0.0.6:18080 SOURCE_ADDR=127.0.0.1:21437
```

We need to change Tor so that it outputs events like:

```
650 STREAM 21 NEW 0 11.0.0.6:18080 SOURCE_ADDR=127.0.0.1:21437 USERNAME=MYUSER
```

Where `MYUSER` is the SOCKS username in use to tie that stream to a circuit.
Here is a patch that was created to do this for `tor-0.3.5.8`, which may help
you understand how to change a newer version of Tor to export the correct info.

```
diff --git a/src/feature/control/control.c b/src/feature/control/control.c
index cc7ecff2f..fac51eb38 100644
--- a/src/feature/control/control.c
+++ b/src/feature/control/control.c
@@ -5904,16 +5904,28 @@ control_event_stream_status(entry_connection_t *conn, stream_status_event_t tp,
purpose = " PURPOSE=USER";
}

+ /* send socks username along with stream events. */
+ char user[64];
+ int do_user = (conn->socks_request && conn->socks_request->username) ? 1 : 0;
+
+ if(do_user) {
+ char* u_null_term = tor_memdup_nulterm(conn->socks_request->username,
+ conn->socks_request->usernamelen);
+ tor_snprintf(user, 64, " USERNAME=%s", u_null_term);
+ free(u_null_term);
+ }
+
circ = circuit_get_by_edge_conn(ENTRY_TO_EDGE_CONN(conn));
if (circ && CIRCUIT_IS_ORIGIN(circ))
origin_circ = TO_ORIGIN_CIRCUIT(circ);
send_control_event(EVENT_STREAM_STATUS,
- "650 STREAM %"PRIu64" %s %lu %s%s%s%s\r\n",
+ "650 STREAM %"PRIu64" %s %lu %s%s%s%s%s\r\n",
(ENTRY_TO_CONN(conn)->global_identifier),
status,
origin_circ?
(unsigned long)origin_circ->global_identifier : 0ul,
- buf, reason_buf, addrport_buf, purpose);
+ buf, reason_buf, addrport_buf, purpose,
+ do_user ? user : "");

/* XXX need to specify its intended exit, etc? */
```