so you want to learn to make an ssh app pt. 1
basics
It’s cool and fun! I promise! This guide is by no means a comprehensive one, but I hope it helps nonetheless.
how
First of all, pick a language which has an SSH server library. This is how you make your app accessible over SSH. Here are some examples.
- Go: github.com/gliderlabs/ssh (simplest)
- Python: github.com/paramiko/paramiko
- JavaScript (Node.js): github.com/mscdex/ssh2
- Rust: github.com/Eugeny/russh
For more cool links, check here (and specifically here for libraries). In my experience, gliderlab’s SSH package in Go is a higher-level wrapper around another package which makes it super simple to use.
You don’t have to go super low-level - for instance Wish is a framework made specifically for creating SSH apps! - but if you choose not to, don’t just make an app which just prints stuff. A more complex and feature-rich SSH app is expected. Here’s some examples/fun ideas of what I’m looking for in submissions.
| yes! | no |
|---|---|
| App that you can journal in to leave notes for the next person who SSHes in | App that prints a bit of text and has no interactivity |
| App that acts like you have root access to the server running it | A clone of charmbracelet/wish or charmbracelet/bubbletea’s tutorial |
| App that you can use to order coffee | Basic calculator/to-do list/terminal apps (come on you can do better than that!) |
| A game (CYOA, RPG, roguelike, anything works!) over SSH, bonus points if it’s multiplayer | |
| A secret way for people to leave comments on your website/customise something about it | |
| Port an existing thing to SSH (like Slack/Discord/Twitter/your website/#meta) so that people can browse it in their terminal | |
| One of those fake hacker typer dashboards |
interfaces
TUI libraries can make your programs look great, particularly if you want to handle user interactions.
- Go: github.com/charmbracelet/bubbletea
- Python: github.com/Textualize/textual
- JavaScript (Node.js): github.com/chjj/blessed
- Rust: github.com/ratatui/ratatui
what to make?
Literally anything! Don’t restrict yourself to basic CLI apps. You can get a lot of information about the user simply from them SSH’ing (a good example of this is ssh whoami.filippo.io). You can make:
- Games (
ssh -p 8080 -l magnetic magneticscrolls.net,ssh sshtron.zachlatta.com) - Chatrooms (
ssh devzat.hackclub.com,ssh ssh.chat) - CTF-style challenges (
ssh bandit0@bandit.labs.overthewire.org -p 2220) - Other things (
ssh guestbook.phthallo.com -p 2222,Sylviettee/ssh-llm)
Remember that your final app will be something that’s online all (ish) of the time, so think about how this can be used to create cool interactive, multiplayer/multi-user experiences for others.
Also, consider how you’ll be handling user inputs and interactions (in a typical app you’ll want to redirect stdin and stdout from the server and to the client) and other functionality like window resizing, which may be covered by the library you’re using.
need a database?
A lot of the more complex app ideas will need some kind of database to persist data. You can set up a Postgres database with Nest.
notes
- If you intend on using colours to theme your app, note that some terminals can’t render them correctly at all. Try printing
\u001b[32mfoobar\u001b[39mto your console to see if your terminal does. If it’s green, it does support colours. When SSHing, you may also need to runexport TERM=xterm-256color/otherwise set the environment variable TERM to force colours in your session. - If you are Dockerising your app, you’ll probably need to set
tty: truein yourdocker-compose.ymlfile for the app to work as intended. - You may come across
REMOTE HOST IDENTIFICATIONerrors after you SSH for the first time, when testing locally. This is because your SSH server does not have a set host key of its own and will keep regenerating it every time it restarts, confusing SSH clients. To alleviate this, you can generate a SSH key in the directory of your SSH server (make sure that these are included in your .gitignore) and instruct your SSH server to use that, or use an existing SSH key.