# Remote terminal(rtmn)

- Link: https://ubient.dscloud.biz/docs/ubient-software/rtmn/
- Published: 2026-10-02T07:49:56+09:00
- Author: Ubient

# 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: UbientOfficial site: [https://ubient.dscloud.biz/](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:

    ```ubient-docs-code
    Bashbin/ver.1.1.2/rtmn-1.1.2
    ```

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

    ```ubient-docs-code
    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 thenupdates
that instance instead of creating a new account-name instance.

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

    ```ubient-docs-code
    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:

    ```ubient-docs-code
    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 systemdunit, restarts
the service, and preserves the existing Telegram token and chatID allowlist:

    ```ubient-docs-code
    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` explicitlyto 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

| Flag | Description | Default | 
| `-chat-ids` | Allowed chat IDs (comma-separated, required) | — | 
| `-instance` | Named single instance (`lowercase`, numbers, hyphens) | legacy default service when omitted | 
| `-user` | Service execution user | `$SUDO_USER` | 
| `-shell` | Shell path | `/bin/bash` | 
| `-shell-args` | Shell arguments | (None) | 
| `-audit-log` | Audit log path | layout default | 
| `-prefix` | Binary installation directory | layout default | 
| `-env-file` | Environment file path | layout default | 
| `-force` | Bypass safety checks like 6+ allowlist entries | false |

---

## 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:

    ```ubient-docs-code
    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)

| Command | Description | 
| `/status` | system time, start time, uptime, PID, allowlist, rate counters | 
| `/enter` | Sends Enter to the shell | 
| `/sigint` | Sends Ctrl-C to the shell (Interrupts infinite output) | 
| `/sigterm` | Sends SIGTERM to the shell | 
| `/restart` | Restarts the shell (The program itself is maintained) | 
| `/lock` | Temporarily blocks shell input (Control commands are still received) | 
| `/unlock` | Resumes input | 
| `/reboot` | Requests host reboot via `systemctl reboot` | 
| `/shutdown` | Requests 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 alreadyallowed
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.

    ```ubient-docs-code
    # 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`:

    ```ubient-docs-code
    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

    ```ubient-docs-code
    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

| Risk | Defense | 
| Bot token leak | Logs, errors, and audit records only show the 8-character prefix, masking the rest with `***` | 
| Accidental inclusion of wrong allowlist | Broadcasts to all allowlists on startup → Instantly exposed if wrong chat is included | 
| Telegram 429/ban | Rate 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 growth | 10MB rotation + Keeps max 5 backups | 
| systemd restart loop due to config error | Blocks loop with exit code 78 + `RestartPreventExitStatus=78` | 
| Non-UTF8 binary output | ANSI stripping + UTF-8 validation + Control character filter | 
| Orphan processes | SIGTERM on close → SIGKILL after 5 seconds | 
| Missed abnormal termination notification | Termination broadcast on SIGTERM/SIGINT/panic | 
| Accidental execution in non-Linux env | `//go:build linux` tag | 
| Execution of freeze-inducing TUI programs | Blocked at the input stage via Interactive denylist |

---

## Full Environment Variable Schema

| Variable | Required | Default | 
| `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_BYTES` |  | 10485760 | 
| `RTMN_AUDIT_MAX_BACKUPS` |  | 5 | 
| `RTMN_DEBOUNCE_MS` |  | 200 | 
| `RTMN_MAX_CHUNK_SIZE` |  | 3500 | 
| `RTMN_POLL_TIMEOUT_SEC` |  | 30 | 
| `RTMN_INCOMING_RATE_PER_MIN` |  | 30 | 
| `RTMN_OUTGOING_RATE_PER_SEC` |  | 25 | 
| `RTMN_OUTPUT_OVERFLOW_BYTES` |  | 262144 | 
| `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](https://ubient.dscloud.biz/docs/ubient-software/rtmn/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](https://ubient.dscloud.biz/docs/ubient-software/rtmn/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](https://ubient.dscloud.biz/docs/ubient-software/rtmn/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](https://ubient.dscloud.biz/docs/ubient-software/rtmn/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](https://ubient.dscloud.biz/docs/ubient-software/rtmn/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](https://ubient.dscloud.biz/docs/ubient-software/rtmn/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](https://ubient.dscloud.biz/docs/ubient-software/rtmn/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](https://ubient.dscloud.biz/docs/ubient-software/rtmn/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](https://ubient.dscloud.biz/docs/ubient-software/rtmn/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](https://ubient.dscloud.biz/docs/ubient-software/rtmn/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](https://ubient.dscloud.biz/docs/ubient-software/rtmn/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](https://ubient.dscloud.biz/docs/ubient-software/rtmn/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 […]
