Give your helpdesk a diagnostic check, not SSH access
A Linux example using Bash and jq; the code was checked locally.
"Could you check whether the VPN hostname resolves?" It's a simple question with a ten-second answer. But if you have to
track down the on-call network engineer first, those ten seconds can easily turn into a separate ticket and a wait.
The helpdesk can answer questions like this on its own. What it needs is a check with clear boundaries.
Shell access doesn't automatically make someone an administrator: that depends on the account's permissions. But even
an unprivileged shell lets its user run commands, read accessible files and connect to accessible services. For a question
like "does this host respond?", that's usually more access than the job needs.
You can start with a small diagnostic script and three rules:
- Only known targets. The network team maintains the host list; neither the helpdesk nor the process running the check can change it.
- Only named checks. The user chooses
dns,port443orping. - Validate the input before running the check. Return the result, including the reason for a refusal, in a clear format.
The allowed hostnames go in /etc/diag/hosts.allow, one per line:
vpn.internal intranet.internal Here's the script:
#!/bin/bash # diag.sh HOST CHECK — only allowed hosts and checks. set -uo pipefail export PATH=/usr/bin:/bin LC_ALL=C readonly ALLOWLIST=/etc/diag/hosts.allow host="${1:-}"; check="${2:-}" emit() { jq -nc --arg host "$host" --arg check "$check" \ --arg result "$1" --arg reason "${2:-}" \ '{host:$host, check:$check, result:$result} + (if $reason == "" then {} else {reason:$reason} end)' } fail() { emit refused "$1"; exit 2; } [[ $# -eq 2 ]] || fail "expected HOST CHECK" [[ "$host" =~ ^[A-Za-z0-9][A-Za-z0-9.-]{0,252}$ ]] || fail "invalid host name" [[ -r "$ALLOWLIST" ]] || { emit error "allowlist is unavailable"; exit 1; } grep -qxF -- "$host" "$ALLOWLIST" || fail "host is not on the allowlist" case "$check" in dns) out=$(timeout 5 getent hosts "$host") || { emit error "name lookup failed or timed out"; exit 1; } out=$(printf '%s\n' "$out" | awk '{print $1}' | paste -sd, -) || { emit error "name lookup output could not be formatted"; exit 1; } ;; port443) out=$(timeout 5 bash -c 'exec 3<>"/dev/tcp/$1/443"' diag "$host" \ 2>/dev/null && echo open || echo no_connection) ;; ping) out=$(timeout 5 ping -c1 -W2 "$host" >/dev/null 2>&1 \ && echo reachable || echo no_reply) ;; *) fail "unknown check (use dns, port443 or ping)" ;; esac emit "${out:-none}" The allowlist path is fixed in the script: DIAG_ALLOWLIST cannot be used to substitute another file. The script, the list
and their parent directories must be protected against writes by both the helpdesk and the account that runs the check.
A fixed path is no help if the caller can replace the file at that path.
Here's what the helpdesk gets back:
{"host":"vpn.internal","check":"dns","result":"10.0.4.12"} {"host":"vpn.internal","check":"port443","result":"open"} {"host":"vpn.internal;reboot","check":"dns","result":"refused","reason":"invalid host name"} {"host":"db-prod","check":"dns","result":"refused","reason":"host is not on the allowlist"} An attempt to append ;reboot stops at the character check. A name starting with - is rejected too, and -- tells
grep where command options end and the name begins. The script refuses db-prod because that host isn't on the list.
Read the results literally. Here, dns checks the system's name resolution, including /etc/hosts.
open means a TCP connection to port 443 was established; it doesn't prove that TLS or the application itself is healthy.
no_connection and no_reply mean no response was obtained under the conditions of the check. There can be several reasons for that.
Now for the important part: how do you use this without SSH?
An existing internal form or company bot needs just two fields: "Host" and "Check". The employee signs in through the
company's usual mechanism, and the handler verifies that they are allowed to run diagnostics. Dropdowns make things
convenient for the user; the server still needs to validate the arguments.
The handler runs the script as a separate, unprivileged account on a machine that can reach the required hosts. That
account cannot change the script, the target list or service settings. The employee gets no shell access to the machine.
The command and its path are set on the server; the user supplies only the two values.
For example, after checking access, the Python call looks like this:
import subprocess completed = subprocess.run( ["/opt/diag/diag.sh", host, check], shell=False, stdin=subprocess.DEVNULL, capture_output=True, text=True, timeout=8, cwd="/", env={"PATH": "/usr/bin:/bin", "LC_ALL": "C"}, ) The arguments are passed as a list, without building a shell command from the request text. The standard
subprocess.run supports this directly.
The server also supplies the environment: the user doesn't choose the program path, the host list or Bash settings.
The handler returns the script's JSON to the employee and reports a launch error or timeout separately. The log records
the user, target, check and result. The form or bot provides authorization and logging; the script itself doesn't implement them.
That makes for a short path: choose vpn.internal → click "Check DNS" → get an answer you can attach to a ticket.
Restarting a service remains a separate action with separate permissions. It doesn't accidentally end up inside the diagnostics button.
Whenever I get the chance to make my geeky thoughts more pleasant for a wider audience, I don't shy away from what modern AI can do.
原文:https://www.a8q9.cn/en/article/give-your-helpdesk-a-diagnostic-check-not-ssh-access-bf9e63.html