In & Out – A file based protocol

Yesterday I begun to work on an rest API for my Humble Server project.

The general idea is to be able to start/stop Docker Humble apps as well as backup/restore or
investigate informations on the running services with a point ‘n’ click interface.

Do you remember CPanel?
Well I’m going to do a similar product to manage a Docker server.

I’m building it as an ExpressJS/ReactJS and wrapping it up as Docker Humble project itself.

Therefore it will be running inside Docker!

The problem is that when a user hits the REST endpoint /api/my-blog/ps the app needs to execute ./humble-server my-blog ps on the host machine, from outside Docker! How to do so?

File Protocol

I knew I could mess around with the Docker socket but on my host machine at the moment I have a simple bash script that does most of the magic for me and I would like to keep it as simple as it is right now.

My solution is for the API app to produce bash scripts that are then executed by a bash daemon on the host machine.

The API App

write "./humble-server my-blog ps
" to volume "/api/queue/cmd.{timestamp}"
wait for volume "/api/logs/cmd.{timestamp}.output"

The Daemon

pick the latest cmd file in ".humble-server/api/queue"
evaluate it and redirect output to "./humble-server/api/running"
when done move the cmd file and relative output to "./humble-server/api/logs"

It works well!

Honestly I am surprised how good this solutions appears to be. It’s fairly simple but it allows me to run whatever kind of commands from inside the container and receive output.

I’m working on a Cmd class that will emulate the interface of a child_process.spawn and it should be possible to pull for dynamic logs while the process is being executed.

So far the daemon script is a ridiculously simple bash script and I believe it will need more love to work better in the future. For sure I would like to run the commands as separated processes with their own PID so to be able to kill it if needed (es timeout).

What about security?

Whaaat? You write in a file what to do and a bash script will do it? Whaaaaaaaaat dude???

Yes I know, it looks like the heaven for malicious attacks, does it?

So far I am investigating the possibilities of this approach and I’m not much concern about security or performances. It is a damn proof of concept 🙂

Anyway I believe the solution to be reasonably safe:

  1. The commands are build by the API and we can mitigate “cmd injection” attempts with middlewares
  2. The daemon should implement filters of which set of commands can be executed
  3. The daemon should be able to start/stop the REST service based on events (like an sms?) to limit the uptime of that specific service

Guys, it’s being fun!