A small POSIX C client/server for invoking a fixed allowlist of commands. It is intended for Linux and macOS.
make
./remoted server.conf
# In another terminal:
./remoter date
./remoter unameThe server listens on 0.0.0.0 port 12345; the client does not listen on a port, so it
cannot collide with the server. Change client.conf and server.conf together
to select another port. Run make test for a localhost integration test on a
separate dynamically chosen port.
make distThis recreates two packages from explicit file allowlists:
dist/client/ dist/server/
remoter remoted
client.conf server.conf
client-commands.conf server-commands.conf
Copy dist/client to the client machine and dist/server to the server
machine. Start each program from its package directory so the relative
commands_file setting resolves correctly:
cd dist/server && ./remoted server.conf
cd dist/client && ./remoter datemake client-dist and make server-dist build only one package. Each target
deletes and recreates its destination first, preventing stale files from an
older package from leaking into it. The binaries are statically linked for the current operating system and CPU;
build separately on each platform when the machines are not binary-compatible.
Static linking with the system libraries is normally available on Linux but not
with the standard macOS toolchain. Override LDFLAGS if a dynamic build is
needed, for example make LDFLAGS=.
client.conf contains the server address and is read only by the client.
client-commands.conf controls what the client may request. The server performs
the authoritative check against server-commands.conf; a mismatched or unknown
name is rejected. Prefix a command value with @stream when it needs live bidirectional PTY I/O; unmarked commands buffer output until completion. Command definitions otherwise contain a name followed by a fixed program
and fixed arguments. Quoting and shell operators are intentionally unsupported.
Each accepted connection runs in a separate server process, so interactive streaming sessions do not block new requests.
The client prints remote stdout on its stdout, reports the remote exit code on stderr, and exits with that code. The protocol limits command output to 16 MiB.
Change the sample password and restrict both configuration files to their
appropriate users. The password and traffic are not encrypted. The default 0.0.0.0 binding exposes the server on every IPv4 interface.
Restrict access with a firewall or bind address to a specific interface. Before
using this service across a network, put it behind a secure authenticated tunnel such as SSH or TLS, add
rate limiting, and run the server as a dedicated unprivileged account. Never add
an unrestricted shell (sh, bash, etc.) to the server allowlist.