Linux Fu: Share Terminal In Browser

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.

20 thoughts on “Linux Fu: Share Terminal In Browser

  1. 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.

      1. 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.

    1. 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.

  2. 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…

    1. 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).

Leave a Reply to Al WilliamsCancel reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.