Creating an API for a legacy device over telnet using tmux and nodered

I love API’s. It allows automating processes and linking devices together a breeze. When a device doesn’t have an API usually its game over. Recently I was able to build an API for a legacy device with NodeRED and it worked quite well.

The legacy device I had only communicated via Telnet and SSH. The SSH connection didn’t provide you with a UNIX shell rather another Telnet connection. Sending commands remotely to the Telnet session was an option however there was a 5 second delay on startup. This wouldn’t work as the API would be called multiple times a second via a HTTP listener.

This is where NodeRED shines, it describes itself as:

Node-RED is a programming tool for wiring together hardware devices, APIs and online services in new and interesting ways.

You can find out more at NodeREDs homepage.

I was able to create a flow that achieves the following:

  • On flow start - start a new session
  • Wait for a POST request
  • Configure the parameters and set the correct command
  • Send the command
  • Return an appropriate HTTP response
  • Restart the session at X interval (poor mans error recovery)

NodeRED Flow

This works well, I used tmux for session management because:

  • I can view any errors thrown back from the device should something go wrong
  • It’s an easier way to send commands to an already established SSH tunnel

tmux is an incredible tool:

tmux is a terminal multiplexer. It lets you switch easily between several programs in one terminal, detach them (they keep running in the background) and reattach them to a different terminal.

To start the tmux session:

tmux kill-session -t mysession 2>/dev/null || true && tmux new -d -s mysession '/bin/bash' && tmux send-keys -t mysession.0 "sshpass -f <(printf '%s\n' PASSWORD) ssh -o 'ControlPersist=yes' -o 'ControlMaster=auto' [email protected]" ENTER

  • Kills any previous sessions
  • Starts a new session with a specific session name so we can refer to it later
  • Passes the SSH password and connection information and establishes an SSH shell

You may be thinking its bad security practice to include the password in this command, you’d be right - why not SSH keys? Well the legacy device doesn’t support them.

When sending commands to the session:

tmux send-keys -t mysession "YOUR COMMANDS HERE" ENTER

This utilises tmux’s send-keys command which you can read more about in the man page.

I haven’t designed an error correction system, therefore if tmux or SSH fails for any reason the HTTP response returns a 500 error. This could be solved by delaying the response and restarting the tmux session. For now I restart the session at regular intervals.

So next time you have a device that hasn’t got an API reach for NodeRED and tmux. I’d love to hear if you used this technique - send me an email.