How to access the shell or shell-based applications via the internet?

Satheesh Kumar
3 min readAug 2, 2021

--

Bash shell on browser

In at the start of 2020, we were trying to create new problem types named fullstack and DevOps. In these 2 problem types, the candidate would need shell access to the ECS(Fargate) container in which their code is running…

Providing access to an EC2 machine is always possible. It can be done with the help of SSH/SSM. But in our case, we were using ECS(Fargate) which made it impossible directly. To solve this, we planned to create a lightweight web application that works the same as SSM manager but for our ECS(Fargate) containers. From here the new project webpty started :)

Development

To make development faster nowadays everyone uses web frameworks. For us the application needs to be lightweight also it should support both WebSocket and HTTP together, so I decided to use tornado here.

Server Creation

The above snippet creates a simple web server in the tornado that listens in port 8080.

WebSocket Connection Handler

The above WebSocket handler function handles all the WebSocket request that comes to the terminal from UI. This is responsible for creating a forked process on opening a connection if not already forked. Once forked it stored the process_id and file_descriptor of that process.

On every new message, it gets the data from the message and writes it to file_descriptor of the forked process using os.write()

Reading from the actual shell and sending it via WebSocket

Writing to the file_descriptor is done by the handler, but reading from the file descriptor and sending the output needs to be done in an async fashion. After some testing, I decided to use the gen.coroutine module available in the tornado.

The above read_and_update_web_terminal function is triggered on open of a connection instance. The instance here refers to the WebSocket handler instance. This watches the file_descriptor if any output is generated. If generated, with the help of os.read() it reads and writes it as a message with the handler instance.

The final server.py file looked like this,

And finally to show up that beautiful terminal in the web browser I used xterm.js.

For everyone to enjoy using this, I have published this as a pip package. Follow the simple instructions below to set this up.

Installation

Use python package manager pip to install this package.

$ pip install webpty

Usage

$ webpty --cmd=$SHELL

This $SHELL can be any shell or shell-based application that is present in your system.

Example: Python Shell Sharing :)

$ webpty --cmd=python

Once the web application started head over to http://localhost:8000/ on your browser and use your python shell from the browser.

Python Shell

Other applications

Bash Shell
Vim

There are some cool features in the pipeline. To get an update on the latest releases refer to GitHub.

ChangeLog:

#2.6 Support restricting access with the help of allowed domains.
#3.2 Support copy & paste with new scrollbar.
#3.3 Support securing the web app with the help of a password.

--

--