At the heart of how Argus works is SSH, the Secure Shell. It's the gold standard for communicating with a remote server: it's fast, easy to use, and secure. While most Linux users are familiar with SSH on the command line as a way to readily access a terminal, SSH has a bunch of tricks in its bag.
For Argus, SSH provides three distinct superpowers:
- A "tunnel", a secure connection to a specific port on the target Linux machine. On that machine, argusd is listening only to that port, so it doesn't respond to hosts on the Internet.
- A command executor, firing requests to the target machine and getting responses immediately.
- A shell, to give users that traditional interface in a text-based console.
SSH is hard. The most common way for a programmer to integrate SSH into their application is with a C-based library called libssh2. (To clarify, libssh2 is entirely unrelated to libssh, a completely separate open source project that most programmers seem to avoid.) It's a pretty low-level library, in that you need to know a lot about the OpenSSH specification. So for Apple developers, we've often relied on wrapper frameworks such as Frugghi's SwiftSH.
I began Argus' development using SwiftSH, but this project, while the most feature-complete and popular framework available, hasn't been updated in years, and doesn't support all the features that I need, specifically tunnelling. My initial versions of Argus therefore rely on the SSH client on your Mac, which is a bit hacky. It also handcuffed me because I couldn't support public key authentication with passphrases.
This problem was like a splinter in my brain from the very inception of Argus' development. I wasn't a good enough programmer to implement tunnelling myself, or integrate it into SwiftSH, and I didn't know of any other SSH library that provided all the functionality I wanted.
For a time, it seemed that I could use SwiftNIO-SSH, an Apple-built SSH implementation, and have a pure-Swift solution to my problem. That flamed out when I realized that there's no support for OpenSSH-style keys (and don't hold your breath on that support arriving, alas).
I had all but given up on the problem when my good friend Stefan Arentz came up with a novel solution.
Rather than rely on the old-and-inscrutable C-based libssh2, he would flex his powers with Go, and use its much newer and comprehensible SSH implementation to produce a Swift framework for me. The great thing about Go is how portable its code is: you can generate a C-compatible static library, and then write a thin Swift wrapper to talk to it. Finally! 😅
It was the work of a couple weeks, but I'm delighted to say that ArguSSH, a fast, flexible and feature-perfect SSH implementation, now lies at the heart of Argus.
The latest build of Argus Public Beta now has ArguSSH inside. Take it for a spin today and enjoy the peformance and flexibility! I'll be putting a band-aid on my brain, now that that splinter's gone. 😂