The title of this post says it all: GoTTY is a program that lets you share Linux terminal applications into a web browser. It is a simple web server written in Go that runs a non-GUI program and can push it out a socket in such a way that a browser can display it and, optionally, let the user interact with it.
With the emphasis on security these days, that ought to alarm you. After all, why would you want a shell running in a browser? Hang on, though. While that is possible — and not always undesirable — the real value to this technique is to run a specific command line program in a browser window. Here’s a use case: You want users to remotely monitor a system using top
(or htop
, if you are fancy). But you don’t want users logging into the system nor do you want to require them to have ssh
clients. You don’t want to install monitoring tools, just use what you already have.
If you could get the output from top to show up in a browser window — even if the users had no ability to input — that would be an easy solution. Granted, you could just run top
in batch mode, collect the output, and write it somewhere that a web server could find it. Assuming you have a web server installed, of course. But then what if you did want some other features like taking command line options or having the option for (hopefully) authenticated users to interact with the software? Now that would be more complicated. With GoTTY, it is easy.
Installation
You can find complete installation instructions on the GitHub page. But if you have Go already, the easiest thing to do is:
go get github.com/yudai/gotty
This puts the program in your Go binary directory which might not be on your PATH. For me it was in ~/go/bin. You can add that directory to your path, specify it every time you run the program, create an alias, or make a symbolic link somewhere on your path.
Simple Test
Let’s start simple: gotty top
That’s it. That will run top on your current machine on port 8080. You won’t be able to perform any input so you can’t kill processes or anything. If you want options or htop
, you can modify the command line, of course. You can’t see it in a static image, but the screen updates just like it was running in a terminal.
The server will run until you kill it. If you didn’t send it to the background, a Control+C will do the trick. You’ll need two Control+C presses if anyone is still connected to the server. Obviously, there are options to change the port (-p
) and the address (-a
). You can create custom index files and titles, too. There’s even a way to allow the URL to have command line arguments, although be careful with security on that option. The documentation for all the options is on GitHub or ask the program for help.
Encryption and Authentication
In this case, we probably don’t care too much if random strangers can see the output of top
. Of course, too, if the machine you are running gotty
on is behind an incoming firewall, outsiders can’t see it anyway. For some applications, that would be enough. But, for example, if we allowed input (the -w
option to gotty
), people might be able to kill processes remotely. Probably not a great idea to publish that on the Web.
We don’t think much of it, but you can add -r
to get some very low-level security. This adds a random bit to the URL so people who don’t know the URL wouldn’t be able to find the page. We’d rather do something smarter than that. The -c
option lets you do basic authentication.
The downside to -c
is that the security transaction — along with all the data to and from the browser — are in the clear. That’s not ideal. There is a -t
option that can enable TLS/SSL and, of course, you’d need to set up certificates to use that option. You can read more about that setup on the GitHub page.
You really do have to think hard about the security, though. For example, consider this seemingly innocuous command line:
gotty -w emacs -nw /tmp/notes.txt
Sure, we can let people edit a file in a browser tab and it works fine. But if they know how they can also open and edit other files. They can even open a shell! Oops. With a program as flexible as emacs
, you could probably figure out how to restrict that, but you’d want to be very sure you had plugged all the holes. Now if you are secure and authenticated and encrypted, this is no worse than letting someone run emacs
over ssh
. But, as always, you want to be careful.
Multiuser
Another issue is that you could have more than one client connect to the server. There is a --once
option that causes the program to handle one request and then exit. But the GitHub page shows examples of using tmux
and docker to either share one session per user or create new sessions for each user.
With tmux
you can even set up to share your current desktop session over a browser which could be handy. The documentation suggests binding this to Control+T:
# Start GoTTY in a new window with C-t bind-key C-t new-window "gotty tmux attach -t `tmux display -p '#S'`"
For the Shell of It
If you really want a shell and not a program, you might consider using the ssh
app for Chrome or some of the other means of putting an ssh
terminal in a browser window. After all, ssh
is the gold standard for authenticating users and encrypting traffic. You could even get similar functionality to GoTTY
if you set up, say, a specific login that ran a script. Just be careful. Any time you give users access to run programs remotely you are increasing the chance they will be able to run programs you didn’t intend.
The other option would be to browse back in Linux Fu history and read about XPRA. It can share a GUI program in the browser and could just as easily share an Xterm or other terminal program running what you wanted. The same caveats would apply though.
GoTTY
is one of those solutions that isn’t for everything, but when you need what it does, it works well and makes it easy to do things that would be otherwise difficult. Not a bad addition to your Linux toolkit.
Nothing about this actually seems like a good idea due to security. SSH is well vetted and secure. Need it in a browser? There’s an extension for that for Chrome or Firefox.
This sounds perfect for raspi zero w cellphone dongles. you know, getting self hosting capabilities on your phone without jailbreaking. Still have to install android sdk to see if it works–its just theoretical right now.
You heard of it now?
WETTY is the way to go, way before gotty.
https://github.com/krishnasrinivas/wetty I use it since at least 2 years.
hmm I can’t edit my previous comment.. I just noticed that gotty has a different use from wetty.. anyway a small modification of wetty can do this and more.
I recently found cockpit-project.org which has a great integrated terminal and a lot of other web management plugins.
https://hackaday.com/2017/11/09/linux-fu-system-administration-made-easier/
I make sure that all of my linux machines offer a root shell in this way to anyone who might find it useful.
… with password “root” for extra convenience.
OK, but honestly, there’s tons of use cases for quick and dirty, less-than-secure hacks. You just gotta know when (not) to use them.
Ditto.
And sometimes you just need something like this to test some other thing entirely unrelated. Setting a complex solution just for a quick test or bug hunting would be too much of a hassle.
I’m just joking of course, but when I do this, the password is always either empty, root, toor, or admin, just so everyone knows.
Indeed, being able to offer web access to a command line program is a pretty cool hack, albeit one with innumerable risks that need to be carefully managed — or else carelessly mismanaged if you prefer.
Nethack in the browser? Co-op Zork? The possibilities are limitless!
Emacs, M-x eshell, cd to target system, type “ps -aux”… ;-)
Ok… eshell doesn’t like highly interactive commands yet but wait what magic will be added over time. ;-)
Nerver underestimate a harmless looking lisp…
Dear Santa!
Please bring me a Hackaday comments edit button!
Or I’ll be mean in 2019… :-Þ
certainly fascinating, if a tad redundant.
any machine/phone/device That I have a browser on, i also have the capability of using SSH from.
+101010₍₂₎ ;-)
The usecase is explained in the article “… But you don’t want users logging into the system nor do you want to require them to have ssh clients” ;)
The main usecase I see is logging into your server when you are behind a corporate firewall that block outgoing ssh sessions.
Also try:
https://github.com/tsl0922/ttyd (Inspired by Gotty, but written in C)
https://guacamole.apache.org/ (a complete solution for ssh/vnc/rdp/telnet by browser only, but installation is much more complicated).
One more thing I forgot –
Unlike Gotty and other solution, ttyd is available as an openwrt package, and so can be easily installed on any openwrt-based router.
I am definitely not a security expert, so check with your local security guru how to harden this before you run ttyd on your main broadband router.
ttyd has an option to limit max # of concurrent sessions, which I did (set to 1).
I don’t know if TMATE.IO has already been quoted here, but here it is :
https://tmate.io/
It does almost the same, without the need of exposing/opening/NATing a port on the “sharing machine”.
Very clever when you’re behind a firewall you can’t customize !
I’m working on a text and audio based streaming service that uses some of the same idea, except read-only: https://asciiradio.johanv.xyz/