Fork me on GitHub

tmate

Instant terminal sharing

Launch

Pair


Installation

tmate is a fork of tmux. tmate and tmux can coexist on the same system, they do not conflict with each other.

You need to have Homebrew installed as a prerequisite.

brew update             && \
brew tap nviennot/tmate && \
brew install tmate

Here is a boxen recipe:

homebrew::tap {
  'nviennot/tmate':
  } -> package { 'tmate':
  ensure => present,
}

Ubuntu 12.04 and up have published packages for tmate.
Please ask if you need support for more OSes.

sudo apt-get install python-software-properties && \
sudo add-apt-repository ppa:nviennot/tmate      && \
sudo apt-get update                             && \
sudo apt-get install tmate

Unofficial AUR package:
https://aur.archlinux.org/packages/tmate/.

To install, follow instructions from the Arch wiki.

Grab the sources from github: https://github.com/nviennot/tmate.
A few dependencies are required. The Ubuntu packages names are:
git-core build-essential pkg-config libtool libevent-dev libncurses-dev zlib1g-dev automake libssh-dev cmake ruby

./autogen.sh && \
./configure  && \
make         && \
make install

Usage

Once installed, simply launch tmate with tmate.

Your mates will be using your tmux config and your key bindings.

The terminal is forced to 256 colors and UTF-8, so you don't need to pass -2 as you may be used to do with tmux.

tmate uses both ~/.tmux.conf and ~/.tmate.conf configuration files.

Run tmate show-messages in your shell to see tmate's log messages, including the ssh connection string.

tmate also allow you to share a read-only view of your terminal. The read-only connection string can be retreived with tmate show-messages.


Running tmate as a daemon

You can run tmate detached, and retrieve the SSH connection strings as follow:

tmate -S /tmp/tmate.sock new-session -d               # Launch tmate in a detached state
tmate -S /tmp/tmate.sock wait tmate-ready             # Blocks until the SSH connection is established
tmate -S /tmp/tmate.sock display -p '#{tmate_ssh}'    # Prints the SSH connection string
tmate -S /tmp/tmate.sock display -p '#{tmate_ssh_ro}' # Prints the read-only SSH connection string

Note that it is important to specify a socket (e.g. /tmp/dev.sock) as tmate uses a random socket name by default.

You can think of tmate as a reverse ssh tunnel accessible from anywhere.

This feature was added in tmate 1.8.10 (31 Oct. 2014)


Technical Details

Figure 1 depicts the architecture diagram with the different components of the system. The following describes the connection process with its security considerations, the protocol used between the two tmux servers, and the roadmap of tmate.

Connection process

When launching tmate, an ssh connection is established to tmate.io (or your own server) in the background through libssh. The server ssh key signatures are specified upfront and are verified during the DH exchange to prevent man in the middle attacks. The client is authenticated with local ssh keys.

When a connection is established, a 150 bits session token is generated, then a tmux server is spawned in a jail with no file system, with its own PID namespace to isolate the server from other processes, and no user privileges. To allow this, all files required during the tmux server execution are opened before getting jailed. These measures are in place to limit the usefulness of possible exploits targeting the tmux server. The attacker would not be able to access other sessions, ensuring confidentiality.

When a mate connects to tmate.io (or your own server) with the ssh command, the tmux unix socket is looked up on the file system. On lookup failures, a random sleep is performed to prevent timing attacks, otherwise a tmux client is spawned and connected to the remote tmux server.

Figure 1: Simplified Architecture Diagram

Protocol

The local and remote tmux servers communicate with a protocol on top of msgpack, which is gzipped over ssh for network bandwidth efficiency as vim scrolling can generate massive amounts of data.

In order to keep the remote tmux server in sync with the local tmux server, PTY window pane's raw outputs are streamed individually as opposed to synchronizing the entire tmux window. Furthermore, window layouts, status bar changes, and copy mode state are also replicated. Finally, most of the tmux commands (like bind-key) are replicated. This ensures that the key bindings are the same on both side.

The remote client's keystrokes are parsed and the outcome is sent to the local tmux server. This includes tmux commands such as split-window, window pane keystrokes, or window size information.

This protocol ensure portability for future work such as a HTML5 client.

Future Work

This project can take many interesting directions.
Here is what I have on the roadmap:

  • Make the user experience top notch. Please submit bug reports when you see issues.
  • Tolerate network failures. Dealing with reconnections and roaming (IP changes) similarly to what Mosh offers.
  • Support for read-only clients. This would be easy to do by providing another session token, distinct from the read-write access one.
  • Each participants should be able to have their own tmux config.
  • Getting low latencies for everyone requires having nodes spread out all over the globe.
  • HTML5 client with fullscreen support, with audio.
  • Record sessions to provide replay and full text search.
  • Being able to make certain session public. This would be useful to pair people with similar interests, or to do screencasts.

Host your own tmate server

The server sources are located at https://github.com/nviennot/tmate-slave.

You need a Linux distribution as tmate utilizes linux specific features.

tmate also depends on a couple of packages. On Ubuntu, the packages are:
git-core build-essential pkg-config libtool libevent-dev libncurses-dev zlib1g-dev automake libssh-dev cmake ruby

Once all the prerequisites are satisfied, you can install tmate-slave with:

git clone https://github.com/nviennot/tmate-slave.git && cd tmate-slave
./create_keys.sh # This will generate SSH keys, remember the keys fingerprints.
./autogen.sh && ./configure && make
sudo ./tmate-slave

The usage of tmate-slave is:

tmate-slave [-k keys_dir] [-l logfile] [-p port] [-h host] [-v]

Once your server is running, you must configure the clients to use your custom server.
You may specify your custom options in the ~/.tmate.conf file. Here are the default options:

set -g tmate-server-host "master.tmate.io"
set -g tmate-server-port 22
set -g tmate-server-dsa-fingerprint   "f5:26:31:c3:8a:78:6e:5c:77:74:0f:41:5b:5f:21:88"
set -g tmate-server-rsa-fingerprint   "af:2d:81:c1:fe:49:70:2d:7f:09:a9:d7:4b:32:e3:be"
set -g tmate-server-ecdsa-fingerprint "c7:a1:51:36:d2:bb:35:4b:0a:1a:c0:43:97:74:ea:42"
set -g tmate-identity ""              # Can be specified to use a different SSH key.

If you are interested in fault tolerance, you may setup the tmate-server-host host to resolve to multiple IPs.
The tmate client will try them all, and keep to the most responsive one.
master.tmate.io resolves to four servers, one in San Fransisco, one in New York, one in Amsterdam, and one in Singapore.

Useful resources:


Get in touch

If you'd like to get in touch, here are your options:

Enjoy,
Nico.