Remote terminal(rtmn)

rtmn is a lightweight Telegram to Terminal gateway for Linux servers. Built as a single Go binary managed by systemd, it allows authorized users to execute shell commands remotely from allowed Telegram chats and receive output directly in their chat. It includes built-in security features like chat allowlists, interactive program blocking, and detailed audit logging.

rtmn

As a Telegram ↔ Terminal gateway, when installed on a Linux server, it executes messages sent from allowed Telegram chats as shell commands on the server and returns the shell output to Telegram. It is a static single Go binary with zero external dependencies, featuring built-in systemd service self-registration, automatic boot start, and automatic crash restart.

This gateway was designed to alleviate the inconvenience of always having to use a Terminal via a PC or console. While security and reliability are prioritized, we strongly recommend using it only in guaranteed safe environments.

Latest Version: 1.1.2
Developer: Ubient
Official site: https://ubient.dscloud.biz/


Architecture

  • Gateway: Telegram ↔ Terminal command gateway
  • Runtime: systemd managed service
  • Implementation: Static single-binary Go program

System Requirements

  • Linux (using systemd — Ubuntu, Debian, RHEL families, etc.)
  • x86_64 (Custom build required for ARM)
  • Root privileges (during installation)
  • Outbound HTTPS (Telegram Bot API)

Prerequisites

  1. Create a Telegram Bot — Chat with @BotFather on Telegram → /newbot → Follow instructions to set a name → Obtain the Bot Token (Format: numbers:alphanumerics)
  2. Check your Chat ID — Send /start to @userinfobot on Telegram → Check the returned Id: numbers

Installation

The release artifact includes the version in the file name:

Bashbin/ver.1.1.2/rtmn-1.1.2

The recommended first-time setup path is the interactive wizard:

Bash./rtmn-1.1.2

Run the wizard as the Linux account that should execute commands. The wizard uses that account as the service user, asks for the Telegram token with terminal echo disabled, and uses sudo only for the installation steps that need root privileges.

If exactly one existing named rtmn service already targets that Linux account,
the wizard uses that existing instance name as the default. Pressing Enter then
updates that instance instead of creating a new account-name instance.

The wizard installs a single named instance using the account-isolated layout:

Bashrtmn-<instance>.service
/home/<account>/.rtmn-<instance>/rtmn-<instance>
/etc/rtmn/env-<instance>
/var/log/rtmn/<instance>/audit.log

For non-interactive installation, read the token as hidden input inside a root shell and pass it only through the environment:

Bashsudo bash -c '
read -r -s -p "Telegram bot token: " RTMN_TELEGRAM_TOKEN
echo
export RTMN_TELEGRAM_TOKEN
exec "$1" install -chat-ids "$2" -user "$3" -instance "$4"
' _ "$(pwd)/rtmn-1.1.2" "<CHAT_ID_1>,<CHAT_ID_2>" "<LINUX_USER>" "<INSTANCE>"

If the target instance already has an environment file, running the newer
binary with the same instance name updates the installed binary and systemd
unit, restarts the service, and preserves the existing Telegram token and chat
ID allowlist:

Bashsudo ./rtmn-1.1.2 install -user <LINUX_USER> -instance <INSTANCE>

For non-interactive updates, if -instance is omitted, -chat-ids is omitted,
and exactly one named rtmn service already targets the selected service user,
the installer detects that instance and updates it. Pass -instance explicitly
to override the detection.

What happens during installation:

  • Verification of systemd availability, execution user, token validity (getMe), and chat ID syntax
  • Copies the binary to the selected layout
  • Atomic write of the environment file (mode 0600, owned by root)
  • Creates the audit log directory (owned by the execution user)
  • Registers or rewrites the systemd unit, starts new installs, and restarts existing updates
  • Verifies service active status + outputs token SHA-256 prefix (for log matching)

Upon successful installation, a startup notification is automatically sent to the allowlist chats (including hostname, PID, start time, shell path, and allowlist). If you receive the notification, it is operating normally.

Installation Flags

FlagDescriptionDefault
-chat-idsAllowed chat IDs (comma-separated, required)—
-instanceNamed single instance (lowercase, numbers, hyphens)legacy default service when omitted
-userService execution user$SUDO_USER
-shellShell path/bin/bash
-shell-argsShell arguments(None)
-audit-logAudit log pathlayout default
-prefixBinary installation directorylayout default
-env-fileEnvironment file pathlayout default
-forceBypass safety checks like 6+ allowlist entriesfalse

Execution

Since it is registered as a service, no separate run command is required. It starts automatically upon server boot, and systemd automatically restarts it within 5 seconds upon a crash.

Manual control:

Bashsudo systemctl status "rtmn-<INSTANCE>"      # Named instance status
sudo systemctl restart "rtmn-<INSTANCE>"     # Restart
sudo systemctl stop "rtmn-<INSTANCE>"        # Stop
sudo journalctl -u "rtmn-<INSTANCE>" -f      # Real-time logs

Usage in Telegram

Sending plain text from an allowed chat forwards it as input to the server’s shell (Use freely like ls -la, tail -f /var/log/syslog, etc.).

Control Commands (Also exposed via / menu)

CommandDescription
/statussystem time, start time, uptime, PID, allowlist, rate counters
/enterSends Enter to the shell
/sigintSends Ctrl-C to the shell (Interrupts infinite output)
/sigtermSends SIGTERM to the shell
/restartRestarts the shell (The program itself is maintained)
/lockTemporarily blocks shell input (Control commands are still received)
/unlockResumes input
/rebootRequests host reboot via systemctl reboot
/shutdownRequests host poweroff via systemctl poweroff

Pressing the / icon on the left side of the input field will display the above commands as a menu with descriptions.

/reboot and /shutdown use the service user’s system permissions. Configure
the host’s sudoers or polkit policy explicitly if that account is not already
allowed to run the corresponding systemctl operation.

Blocking Interactive Programs

TUI/editors and pagers like nano, vim, top, less, man take over the PTY upon execution and wait for real-time keystrokes like arrow keys or Ctrl sequences. Since Telegram operates on message-based I/O, these programs cannot be controlled. Moreover, the sanitizer filters out the ANSI escape codes used to draw the screen, resulting in a frozen state.

rtmn automatically compares the first token (wrapper/env var prefixes like sudo, time, VAR=... are automatically skipped) against a default denylist to block the execution of such programs at the input stage. When blocked, it returns a blocked: <program> is interactive and cannot be controlled via Telegram message to Telegram and records reject reason=interactive_blocked:<program> in the audit log.

Default Denylist: nano, vim, vi, nvim, emacs, pico, joe, jed, ne, mcedit, less, more, most, man, top, htop, btop, atop, iotop, iftop, mc, ranger, lf, screen, tmux, w3m, lynx, links, elinks, alsamixer

Customization: Specifying a comma-separated list in the RTMN_BLOCKED_INTERACTIVE environment variable completely replaces the default list. Leaving it empty applies the default list.

# If you want to block a few more in addition to the defaults, list all defaults + additions
RTMN_BLOCKED_INTERACTIVE=nano,vim,vi,top,htop,mysql,psql,python3

After modifying the setting, apply it with sudo systemctl restart rtmn.

⚠️ This feature is a convenience guardrail, not a security boundary. Bypasses like n=nano; $n are intentionally not blocked. The true trust boundary is the chat ID allowlist.


Token Rotation

When the token is leaked or needs replacement, do it within 1 second without uninstall:

Bashsudo bash -c '
read -r -s -p "New Telegram bot token: " RTMN_TELEGRAM_TOKEN
echo
export RTMN_TELEGRAM_TOKEN
exec "$1" rotate-token -instance "$2"
' _ "/home/<account>/.rtmn-<INSTANCE>/rtmn-<INSTANCE>" "<INSTANCE>"
  • Replaces only upon successful getMe validation of the new token
  • Atomic rewrite of the environment file → Service restart
  • Automatically rolls back to the previous token if restart fails

Uninstallation

Bashsudo /home/<account>/.rtmn-<INSTANCE>/rtmn-<INSTANCE> uninstall -instance <INSTANCE>
sudo /home/<account>/.rtmn-<INSTANCE>/rtmn-<INSTANCE> uninstall -instance <INSTANCE> -purge

Built-in Self-Defense

RiskDefense
Bot token leakLogs, errors, and audit records only show the 8-character prefix, masking the rest with ***
Accidental inclusion of wrong allowlistBroadcasts to all allowlists on startup → Instantly exposed if wrong chat is included
Telegram 429/banRate limit per incoming chat + Global outgoing rate limit + Retry-After compliance + Exponential backoff
Output flood (yes, tail -f)Automatic SIGINT upon exceeding 256KB + User notification
Infinite audit log growth10MB rotation + Keeps max 5 backups
systemd restart loop due to config errorBlocks loop with exit code 78 + RestartPreventExitStatus=78
Non-UTF8 binary outputANSI stripping + UTF-8 validation + Control character filter
Orphan processesSIGTERM on close → SIGKILL after 5 seconds
Missed abnormal termination notificationTermination broadcast on SIGTERM/SIGINT/panic
Accidental execution in non-Linux env//go:build linux tag
Execution of freeze-inducing TUI programsBlocked at the input stage via Interactive denylist

Full Environment Variable Schema

VariableRequiredDefault
RTMN_TELEGRAM_TOKEN✅—
RTMN_ALLOWED_CHAT_IDS✅—
RTMN_SHELL_PATH/bin/bash
RTMN_SHELL_ARGS“”
RTMN_AUDIT_LOG_PATH/var/log/rtmn/audit.log
RTMN_AUDIT_MAX_BYTES10485760
RTMN_AUDIT_MAX_BACKUPS5
RTMN_DEBOUNCE_MS200
RTMN_MAX_CHUNK_SIZE3500
RTMN_POLL_TIMEOUT_SEC30
RTMN_INCOMING_RATE_PER_MIN30
RTMN_OUTGOING_RATE_PER_SEC25
RTMN_OUTPUT_OVERFLOW_BYTES262144
RTMN_BLOCKED_INTERACTIVE(Default list; refer to “Blocking Interactive Programs” above)

Precautions when deploying to multiple servers

You must not run this program on two servers simultaneously with a single bot token. Telegram long polling creates a race condition, making it unpredictable which server the message will go to. Create and use a separate bot (different token) for each server.


Audit Log

Recorded in JSONL format. Named instances default to /var/log/rtmn/<INSTANCE>/audit.log; the legacy default instance uses /var/log/rtmn/audit.log. Entry types:

  • cmd — Command sent by the user
  • event — Service lifecycle (startup, shutdown, 429, shell restart, etc.)
  • reject — Dropped message (reason: not_allowed, rate_limited, locked, interactive_blocked:<program>)
  • overflow — Automatic interrupt triggered by output flood

License

Copyright © Ubient. All rights reserved

  • Overview

    Remote terminal(rtmn) is… rtmn is a terminal gateway between Telegram and a Linux shell. When an allowed Telegram chat sends plain text, rtmn forwards that text to the configured Linux shell and returns the command output to Telegram. Basic Flow Components Component Description Gateway Telegram Bot API long polling Runtime systemd service Program Static Go […]

  • Requirements

    Supported Environments The built-in installer targets common systemd-based Linux distributions. System Requirements Item Requirement OS systemd-based Linux CPU architecture Must match the provided binary. The common distributed binary targets x86_64 Privilege Root privilege during installation Network Outbound HTTPS access to api.telegram.org Account A local Linux account that will run the shell Outside the Built-In Installer […]

  • Telegram Setup

    Before installation, prepare a Telegram bot token and the chat IDs that will be allowed to control the gateway. Create a Bot The bot token is a secret. Do not expose it in shell history, documents, tickets, chats, or logs. Find the Chat ID Identify the Telegram chat ID that should be allowed. For a […]

  • Binary Preparation

    Prepare the downloaded Linux binary before installation. Preparation for Single-Instance Installation When using the built-in installer, name the local executable rtmn. The installer copies the binary that is currently being executed, so a mismatched download filename can make the installed result confusing. A valid binary should show these top-level commands: Preparation for Account-Isolated Installation Account-isolated […]

  • Single-Instance Installation

    Use the built-in install command when one server needs one rtmn gateway. Install Command Do not type the bot token directly into the command line. The following command reads the token as hidden input inside a root shell and passes it only through the environment. Replace <CHAT_ID_1>,<CHAT_ID_2> and <LINUX_USER> with real values. If -user is […]

  • Account-Isolated Installation

    Use this model when one Linux server needs multiple rtmn instances separated by Linux account. Each instance must have its own: Example Layout Why Manual Installation Is Needed The built-in rtmn install command is designed for a single default service. The default service name is rtmn.service. In account-isolated operation, each service name, environment file, log […]

  • Service Operations

    rtmn runs as a systemd service. Single-Instance Service Check status: Restart: Stop: Follow logs: Show recent logs: Account-Isolated Services In account-isolated installations, service names use the rtmn-<instance>.service format. Check status: Restart: Stop: Follow logs: Show recent logs: Confirm a Healthy Start A healthy service start sends a startup notification to the allowed Telegram chats. Check […]

  • Telegram Usage

    Plain text sent from an allowed Telegram chat is forwarded to the configured Linux account’s shell. Examples: Control Commands Command Description /status Show uptime, PID, allowlist, and rate counters /sigint Send Ctrl-C to the shell /sigterm Send SIGTERM to the shell /restart Restart only the shell while keeping the program running /lock Temporarily block shell […]

  • Environment Variables

    rtmn reads RTMN_* environment variables from the systemd EnvironmentFile. Variable List Variable Required Default Description RTMN_TELEGRAM_TOKEN Yes None Telegram bot token RTMN_ALLOWED_CHAT_IDS Yes None Allowed chat ID list RTMN_SHELL_PATH No /bin/bash Shell to execute RTMN_SHELL_ARGS No Empty Shell arguments RTMN_AUDIT_LOG_PATH No /var/log/rtmn/audit.log Audit log path RTMN_AUDIT_MAX_BYTES No 10485760 Audit log rotation size RTMN_AUDIT_MAX_BACKUPS No 5 […]

  • Update and Uninstall

    Rotate the Token for a Single Instance For the default single-instance installation, use rotate-token. This command validates the new token, rewrites the environment file atomically, and restarts the service. If restart fails, it rolls back to the previous token. Rotate the Token for an Account-Isolated Instance For account-isolated installations, edit only that instance’s environment file […]

  • Security Guide

    rtmn runs Linux shell commands through Telegram. Treat an allowed Telegram chat as shell access to the configured Linux account. Core Rules Account Permissions The service account should have only the permissions needed for its operational role. Not recommended: Recommended: Environment File Permissions Environment files contain bot tokens. Recommended permissions: Verification commands: Token Isolation Do […]

  • Troubleshooting

    Check a Single-Instance Service Check an Account-Isolated Service Common Causes Symptom Possible Cause Service exits immediately Environment file error, shell path error, token error No Telegram response Wrong chat ID, wrong token, outbound HTTPS blocked Message goes to another server The same token is active in another instance Audit log write failure Audit log directory […]

Was this page helpful?

Last update