Skip to content

Commit

Permalink
Update README
Browse files Browse the repository at this point in the history
  • Loading branch information
owenthereal committed Sep 30, 2023
1 parent 9504252 commit d66e8ea
Showing 1 changed file with 76 additions and 125 deletions.
201 changes: 76 additions & 125 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,21 @@
# Upterm
# Upterm: Instant Terminal Sharing

[Upterm](https://github.com/owenthereal/upterm) is an open-source solution for sharing terminal sessions instantly over the public internet via secure tunnels.
Upterm is good for

* Remote pair programming
* Access remote computers behind NATs and firewalls
* Remote debugging
* \<insert your creative use cases\>
[Upterm](https://github.com/owenthereal/upterm) is an open-source tool enabling developers to share terminal sessions securely over the web. It’s perfect for remote pair programming, accessing computers behind NATs/firewalls, remote debugging, and more.

This is a [blog post](https://owenou.com/upterm) to describe Upterm in depth.

## Usage

The host starts a terminal session:

```console
$ upterm host -- bash
```

The host displays the ssh connection string:
## :movie_camera: Quick Demo

```console
$ upterm session current
=== IQKSFOICLSNNXQZTDKOJ
Command: bash
Force Command: n/a
Host: ssh://uptermd.upterm.dev:22
SSH Session: ssh IqKsfoiclsNnxqztDKoj:[email protected]
```

The client opens a terminal and connects to the host's session:
[![asciicast](https://asciinema.org/a/LTwpMqvvV98eo3ueZHoifLHf7.svg)](https://asciinema.org/a/LTwpMqvvV98eo3ueZHoifLHf7)

```console
$ ssh IqKsfoiclsNnxqztDKoj:[email protected]
```
## :rocket: Getting Started

## Installation

### Mac

```console
$ brew install owenthereal/upterm/upterm
brew install owenthereal/upterm/upterm
```

### Standalone
Expand All @@ -50,135 +25,115 @@ $ brew install owenthereal/upterm/upterm
### From source

```console
$ git clone [email protected]:owenthereal/upterm.git
$ cd upterm
$ go install ./cmd/upterm/...
git clone [email protected]:owenthereal/upterm.git
cd upterm
go install ./cmd/upterm/...
```

## Upgrade
## :wrench: Basic Usage

`upterm` comes with a command to upgrade
1. Host starts a terminal session:

Upgrade to the latest version
```console
$ upterm upgrade
upterm host bash
```

Upgrade to a specific version
2. Host retrieves and shares the SSH connection string:

```console
$ upterm upgrade VERSION
upterm session current
```

### Mac
3. Client connects using the shared string:

```console
$ brew upgrade upterm
ssh TOKEN@uptermd.upterm.dev
```

## Quick Reference
## :blue_book: Quick Reference

Host a terminal session that runs `$SHELL` with client's input/output attaching to the host's
```console
$ upterm host
```
Dive into more commands and advanced usage in the [documentation](docs/upterm.md).
Below are some notable highlights:

Display the ssh connection string and share it with the client(s)
```console
$ upterm session current
=== SESSION_ID
Command: /bin/bash
Force Command: n/a
Host: ssh://uptermd.upterm.dev:22
SSH Session: ssh [email protected]
```
### Command Execution

A client connects to the host session with `ssh`
```console
$ ssh [email protected]
```
Host a session with any desired command:

Host a terminal session that only allows specified client public key(s) to connect
```console
$ upterm host --authorized-key PATH_TO_PUBLIC_KEY
upterm host -- docker run --rm -ti ubuntu bash
```

Host a terminal session that only allows specified GitHub user client public key(s) to connect.
This is compatible with `--authorized-keys`.
```console
$ upterm host --github-user username
```
### Access Control

Host a terminal session that only allows specified GitLab user client public key(s) to connect.
This is compatible with `--authorized-keys`.
```console
$ upterm host --gitlab-user username
```
Host a session with specified client public key(s) authorized to connect:

Host a terminal session that only allows specified SourceHut user client public key(s) to connect.
This is compatible with `--authorized-keys`.
```console
$ upterm host --srht-user username
upterm host --authorized-key PATH_TO_PUBLIC_KEY
```

Host a session with a custom command
Authorize specified GitHub, GitLab, or SourceHut users with their corresponding public keys:

```console
$ upterm host -- docker run --rm -ti ubuntu bash
upterm host --github-user username
upterm host --gitlab-user username
upterm host --srht-user username
```

Host a session that runs 'tmux new -t pair-programming' and force clients to join with `tmux attach -t pair-programming`.
This is similar to what tmate offers.
### Force command

Host a session initiating `tmux new -t pair-programming`, while ensuring clients join with `tmux attach -t pair-programming`.
This mirrors functionarity provided by tmate:

```console
$ upterm host --force-command 'tmux attach -t pair-programming' -- tmux new -t pair-programming
upterm host --force-command 'tmux attach -t pair-programming' -- tmux new -t pair-programming
```

Connect to uptermd.upterm.dev via WebSocket
### WebSocket Connection

In scenarios where your host restricts ssh transport, establish a connection to `uptermd.upterm.dev` (or your self-hosted server) via WebSocket:

```console
$ upterm host --server wss://uptermd.upterm.dev -- bash
upterm host --server wss://uptermd.upterm.dev -- bash
```

A client connects to the host session via WebSocket
Clients can connect to the host session via WebSocket as well:

```console
$ ssh -o ProxyCommand='upterm proxy wss://[email protected]' [email protected]:443
ssh -o ProxyCommand='upterm proxy wss://[email protected]' [email protected]:443
```

More advanced usage is [here](https://github.com/owenthereal/upterm/blob/master/docs/upterm.md).
## :bulb: Tips

### Resolving Tmux Session Display Issue

## Tips
**Issue**: The command `upterm session current` does not display the current session when used within Tmux.

**Why doesn't `upterm session current` show current session in Tmux?**
**Cause**: This occurs because `upterm session current` requires the `UPTERM_ADMIN_SOCKET` environment variable, which is set in the specified command. Tmux, however, does not carry over environment variables not on its default list to any Tmux session unless instructed to do so ([Reference](http://man.openbsd.org/i386/tmux.1#GLOBAL_AND_SESSION_ENVIRONMENT)).

`upterm session current` needs the `UPTERM_ADMIN_SOCKET` environment variable to function.
And this env var is set in the specified command.
Unfotunately, Tmux doesn't carry over environment variables that are not in its default list to any Tmux session unless you tell it to ([Ref](http://man.openbsd.org/i386/tmux.1#GLOBAL_AND_SESSION_ENVIRONMENT)).
So to get `upterm session current` to work, add the following line to your `~/.tmux.conf`
**Solution**: To rectify this, add the following line to your `~/.tmux.conf`:

```conf
set-option -ga update-environment " UPTERM_ADMIN_SOCKET"
```

**How to make it obvious that I am in an upterm session?**
### Identifying Upterm Session

**Issue**: It might be unclear whether your shell command is running in an upterm session, especially with common shell commands like `bash` or `zsh`.

It can be confusing whether your shell command is running in an upterm session or not, especially if the shell command is `bash` or `zsh`.
Add the following line to your `~/.bashrc` or `~/.zshrc` and decorate your prompt to show a sign if the shell command is in a terminal session:
**Solution**: To provide a clear indication, amend your `~/.bashrc` or `~/.zshrc` with the following line. This decorates your prompt with an emoji whenever the shell command is running in an upterm session:

```bash
export PS1="$([[ ! -z "${UPTERM_ADMIN_SOCKET}" ]] && echo -e '\xF0\x9F\x86\x99 ')$PS1" # Add an emoji to the prompt if `UPTERM_ADMIN_SOCKET` exists
```

## Demo

[![asciicast](https://asciinema.org/a/LTwpMqvvV98eo3ueZHoifLHf7.svg)](https://asciinema.org/a/LTwpMqvvV98eo3ueZHoifLHf7)

## How it works
## :gear: How it works

You run the `upterm` program by specifying the command for your terminal session.
Upterm starts an SSH server (a.k.a. `sshd`) in the host machine and sets up a reverse SSH tunnel to a [Upterm server](https://github.com/owenthereal/upterm/tree/master/cmd/uptermd) (a.k.a. `uptermd`).
Clients connect to your terminal session over the public internet via `uptermd` using `ssh` using TCP or WebSocket.
A community Upterm server is running at `uptermd.upterm.dev` and `upterm` points to this server by default.
Clients connect to a terminal session over the public internet via `uptermd` using `ssh` or `ssh` over WebSocket.

![upterm flowchart](https://raw.githubusercontent.com/owenthereal/upterm/gh-pages/upterm-flowchart.svg?sanitize=true)

## Deploy Uptermd
## :hammer_and_wrench: Deployment

### Kubernetes

Expand Down Expand Up @@ -207,31 +162,35 @@ The Heroku Terraform scripts are in the [terraform/heroku folder](./terraform/he
A [util script](./bin/heroku-install) is provided for your convenience to automate everything:

```console
$ git clone https://github.com/owenthereal/upterm
$ cd upterm
git clone https://github.com/owenthereal/upterm
cd upterm
```

Provision uptermd in Heroku Common Runtime. Follow instructions.

```console
$ bin/heroku-install
bin/heroku-install
```

Provision uptermd in Heroku Private Spaces. Follow instructions.

```console
$ TF_VAR_heroku_region=REGION TF_VAR_heroku_space=SPACE_NAME TF_VAR_heroku_team=TEAM_NAME bin/heroku-install
TF_VAR_heroku_region=REGION TF_VAR_heroku_space=SPACE_NAME TF_VAR_heroku_team=TEAM_NAME bin/heroku-install
```

You **must** use WebScoket as the protocol for a Heroku-deployed Uptermd server because the platform only support HTTP/HTTPS routing.
This is how you host a session and join a session:

Use the Heroku-deployed Uptermd server via WebSocket

```console
$ upterm host --server wss://YOUR_HEROKU_APP_URL -- YOUR_COMMAND
upterm host --server wss://YOUR_HEROKU_APP_URL -- YOUR_COMMAND
```

A client connects to the host session via WebSocket

```console
$ ssh -o ProxyCommand='upterm proxy wss://TOKEN@YOUR_HEROKU_APP_URL' TOKEN@YOUR_HEROKU_APP_URL:443
ssh -o ProxyCommand='upterm proxy wss://TOKEN@YOUR_HEROKU_APP_URL' TOKEN@YOUR_HEROKU_APP_URL:443
```

### Digital Ocean
Expand All @@ -253,28 +212,20 @@ A hardened systemd service is provided in `systemd/uptermd.service`. You can use
secured `uptermd` on your machine:

```console
$ cp systemd/uptermd.service /etc/systemd/system/uptermd.service
$ systemctl daemon-reload
$ systemctl start uptermd
cp systemd/uptermd.service /etc/systemd/system/uptermd.service
systemctl daemon-reload
systemctl start uptermd
```

## How is Upterm compared to prior arts?
## :balance_scale: Comparasion with Prior Arts

Upterm is an alternative to [Tmate](https://tmate.io).
Upterm stands as a modern alternative to [Tmate](https://tmate.io).

Tmate is a fork of an older version of Tmux. It adds terminal sharing capability on top of Tmux 2.x.
Tmate doesn't intend to catch up with the latest Tmux, so any Tmate & Tmux users must maintain two versions of the configuration.
For example, you must [bind the same keys twice with a condition](https://github.com/tmate-io/tmate/issues/108).
Tmate originates as a fork from an older iteration of Tmux, extending terminal sharing capabilities atop Tmux 2.x. However, Tmate has no plans to align with the latest Tmux updates, compelling Tmate & Tmux users to manage two separate configurations. For instance, the necessity to [bind identical keys twice, conditionally](https://github.com/tmate-io/tmate/issues/108).

Upterm is designed from the group up not to be a fork of anything.
It builds around the concept of linking the input & output of any shell command between a host and its clients.
As you see above, you can share any command besides `tmux`.
This opens up a door for securely sharing a terminal session using containers.
On the flip side, Upterm is architected from the ground up to be an independent solution, not a fork. It embodies the idea of connecting the input & output of any shell command between a host and its clients, transcending beyond merely `tmux`. This paves the way for securely sharing terminal sessions utilizing containers.

Upterm is written in Go.
It is more friendly hackable than Tmate that is written in C because Tmux is C.
The Upterm CLI and server (`uptermd`) are compiled into a single binary.
You can quickly [spawn up your pairing server](#deploy-uptermd) in any cloud environment with zero dependencies.
Written in Go, Upterm is more hack-friendly compared to Tmate, which is crafted in C, akin to Tmux. The seamless compilation of Upterm CLI and server (`uptermd`) into a single binary facilitates swift [deployment of your pairing server](#kubernetes) across any cloud environment, devoid of dependencies.

## License

Expand Down

0 comments on commit d66e8ea

Please sign in to comment.