Secure Shell

跨平台Shell执行器(执行引擎为可选扩展包),带安全白名单与日志审计

工具
管理

一键安装指令

!!MCDR plugin install secure_shell

数据同步于

...

上次更新

...

最新版本

总下载量

7

返回插件仓库

Secure Shell

English | 简体中文

An MCDReforged plugin for panel-hosted servers. It runs shell commands for you — from the MCDR console, and from the game chat too if you turn that on. Comes with a permission gate, a blacklist/allowlist and an audit log.

On a panel host you get a web console whose input goes straight to the game server. No root, no SSH, no terminal of your own. Want to check disk usage or see which process is eating memory? Nowhere to type. I wrote this for exactly that — it runs on my own panel server (SimpFun, a free one), and I use it daily for those little checks.

Requirements

mcdreforged>=2.0.0

The plugin code itself needs Python 3.7+ (subprocess gets a text=True flag that older Pythons don't know). In practice the floor is whatever your MCDR needs — MCDR 2.15+, for example, requires Python 3.9. Written and tested on MCDR 2.15.7 / Python 3.12.

Features

  • Console-first: by default only the MCDR console can run commands; in-game execution is opt-in
  • Two gates for in-game use: allow_player_execution must be on, and the player needs MCDR permission level 4 (required_permission, configurable)
  • No shell involved: input is split with shlex and executed directly, so pipes, redirects, globs and $() never pass through
  • Always-on dangerous-command blacklist, plus an optional allowlist-only mode
  • Every execution and denial is logged to logs/secure_shell.log
  • Cross-platform (Linux / macOS / Windows), per-command timeout with force-kill
  • Pluggable engine: the shell executor itself ships as a signed extension pack — absent by default, installed only on purpose

Usage

By default only the MCDR console can run commands; in-game execution is disabled (since v2.0.2). To let players use !!shell, set allow_player_execution to true in the config — and even then a player still needs MCDR permission level required_permission (default 4). Both checks have to pass. While the switch is off, players who try get told so, and every attempt is logged.

!!shell "<command>"                run a command
!!sh "<command>"                   !!sh is an alias of !!shell
!!shell --timeout=10 "<command>"   override the timeout for one command
!!shellstatus                      show the current switches

The plugin runs on Linux, macOS and Windows, but the commands you can run depend on the host system:

Linux

!!shell "df -h"                    disk usage
!!shell "free -h"                  memory
!!shell "ps aux"                   processes
!!shell "cd /home/container"       then: !!shell "ls"

macOS — mostly the same as Linux, but there is no free; use vm_stat or top -l 1 for memory:

!!shell "df -h"
!!shell "vm_stat"
!!shell "ping -c 4 8.8.8.8"

Windows — the plugin starts programs directly without a shell, so cmd builtins like dir, copy or del cannot run; use real executables instead. Also, ping takes -n here, not -c:

!!shell "tasklist"                 processes
!!shell "ipconfig /all"            network config
!!shell "systeminfo"
!!shell "netstat -an"
!!shell "cd C:\MCDR"               then: !!shell "tree /F"

cd and pwd are handled by the plugin itself on all three systems, so the working directory follows you around and resets when the plugin is reloaded.

Replies come in order: an info line with the effective cwd and timeout, the streamed output, then an exit-code line. [OK] 退出码 0 (exit 0) means success, [FAIL] 退出码 N (exit N) means failure — replies are bilingual, Chinese first with an English gloss. stderr is merged into the output. A blocked command never runs and answers [FAIL] 安全拦截 (blocked): <原因>; a command past its timeout is killed with [FAIL] 命令超时 (timeout >Ns),已强制终止 (killed); unclosed quotes are rejected before anything runs. All of this — denials included — lands in logs/secure_shell.log.

!!shellstatus shows whether the allowlist is enforced, whether in-game execution is on, and reminds you the blacklist always applies.

Configuration

config/secure_shell/config.json, created with defaults on first load:

KeyDefaultWhat it does
required_permission4MCDR permission level needed to run commands
allow_player_executionfalsefalse: MCDR console only. true: players may run commands too, but still need required_permission
default_timeout60Timeout in seconds
enforce_allowlistfalsetrue: only allowlisted programs may run
allowlist(a set of common safe commands)Entries match the program name, i.e. the first word of the command
blacklist(dangerous commands)Checked before the allowlist, always applies
ext_download_url(this repo's release)Where install_ext pulls the engine pack
ext_expected_sha256(empty = pinned in source)Required hash when you host your own pack
ext_password_pbkdf2(empty = off)Second-factor hash, generate with hash_password

Matching works on the actual program name — the first word after splitting. So git status in the allowlist allows git, and rm -rf / in the blacklist blocks rm. The blacklist always wins; the allowlist only matters when enforce_allowlist is true. The bundled allowlist is written for Linux — on Windows or macOS, adjust it to your own system (e.g. tasklist, ipconfig on Windows).

The engine extension

Since v2.1.0 the actual shell engine is a separate, optional pack. The main plugin does not bundle, download or load it on its own — a console admin has to install it explicitly. All !!secure_shell management commands are console-only; every in-game player is rejected, no matter their permission level.

!!secure_shell install_ext [password]    download, verify (SHA-256) and install the pack
!!secure_shell check_ext                 show whether the engine is installed / enabled, and its version
!!secure_shell enable_ext                enable the installed engine (a second, explicit step on purpose)
!!secure_shell disable_ext               disable the engine without removing it
!!secure_shell uninstall_ext [password]  remove the engine files
!!secure_shell hash_password <pw>        print a PBKDF2 hash to paste into the config (if you want a password)

Integrity is enforced, not optional: the downloaded pack must match the SHA-256 pinned in the plugin source (or the one you set in ext_expected_sha256). A mismatched pack is never written to disk. If you ever host packs elsewhere and want more than a pinned hash, RSA signatures can be added later — for the normal setup the hash is the whole story. If you set a password in the config (PBKDF2 hash, never plaintext, never in source), install_ext and uninstall_ext require it as an extra argument.

Security notes

Since v2.0.1 commands no longer go through a shell. Input is split into a program name and arguments (shlex.split) and executed directly — pipes |, redirection >, globs *, ;, &&, $() and backticks no longer work. Plain commands with plain arguments behave as before. If you really need pipes or redirection, write a script, put it on the server and allowlist the script.

Think twice before you set allow_player_execution to true. Whoever can run !!shell runs real commands on the host. The blacklist and allowlist are pattern matching, not a sandbox. Enable it only for your own owner account — MCDR permission level 4 comes from permission.yml, and that list is empty for players by default — and don't lower required_permission just to make it work for someone else.

Keep interpreters (bash, sh, zsh, python, perl, powershell, ...) out of the allowlist. An interpreter can run arbitrary commands on its own, so allowing one defeats the whitelist. The plugin won't stop you — it's your config. Stick to plain tools like ping, df, free, uptime, systemctl.

Every execution is logged to logs/secure_shell.log with time, player, command and result — denials included.

Two things about the extension worth keeping in mind: the MCDR console is as powerful as the host itself, so anyone who can type into it can install the engine — that is the trust boundary, the password only adds a second check against mistakes. And if you build your own pack, the ext_expected_sha256 config is where your own hash goes.

Install

Grab secure_shell.mcdr from the releases, drop it into plugins/, then:

!!MCDR reload plugin

License

MIT. See LICENSE.

自述文件来源:README.md