[HLCC-ICE-000001][ZY-CONTRIB-20260723-001] feat: 以来光者贡献链启用冰朔第五域个人子频道
This commit is contained in:
commit
5615453e4e
660 changed files with 122355 additions and 0 deletions
86
server-tools/lake-lamp-authz/owner-access-broker.js
Normal file
86
server-tools/lake-lamp-authz/owner-access-broker.js
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
"use strict";
|
||||
|
||||
const fs = require("node:fs");
|
||||
const net = require("node:net");
|
||||
const path = require("node:path");
|
||||
const { execFile } = require("node:child_process");
|
||||
|
||||
const SOCKET_PATH = process.env.LAKE_LAMP_OWNER_ACCESS_SOCKET || "/run/guanghu-owner-access/owner-access.sock";
|
||||
const SSH_CONFIG = process.env.LAKE_LAMP_SSH_CONFIG || "/etc/guanghu/action-broker-ssh-config";
|
||||
|
||||
const RESTORE_OWNER_PASSWORD_LOGIN = String.raw`set -eu
|
||||
test "$(id -u)" = "0"
|
||||
cfg=/etc/ssh/sshd_config.d/90-guanghu-key-only.conf
|
||||
test -f "$cfg"
|
||||
backup_dir=/root/guanghu-security-backup-$(date -u +%Y%m%dT%H%M%SZ)
|
||||
mkdir -p "$backup_dir"
|
||||
chmod 0700 "$backup_dir"
|
||||
cp -a "$cfg" "$backup_dir/90-guanghu-key-only.conf.before"
|
||||
rollback() {
|
||||
cp -a "$backup_dir/90-guanghu-key-only.conf.before" "$cfg"
|
||||
/usr/sbin/sshd -t
|
||||
systemctl reload ssh 2>/dev/null || systemctl reload sshd
|
||||
}
|
||||
trap 'rc=$?; if [ "$rc" -ne 0 ]; then rollback; fi; exit "$rc"' EXIT
|
||||
/usr/bin/python3 - "$cfg" <<'PY'
|
||||
from pathlib import Path
|
||||
import re, sys
|
||||
|
||||
path = Path(sys.argv[1])
|
||||
text = path.read_text()
|
||||
pattern = re.compile(r"(?im)^\s*PasswordAuthentication\s+\S+\s*$")
|
||||
if pattern.search(text):
|
||||
text = pattern.sub("PasswordAuthentication yes", text)
|
||||
else:
|
||||
text = text.rstrip() + "\nPasswordAuthentication yes\n"
|
||||
path.write_text(text)
|
||||
PY
|
||||
/usr/sbin/sshd -t
|
||||
password=$(/usr/sbin/sshd -T | awk '$1 == "passwordauthentication" {print $2; exit}')
|
||||
root_login=$(/usr/sbin/sshd -T | awk '$1 == "permitrootlogin" {print $2; exit}')
|
||||
test "$password" = "yes"
|
||||
test "$root_login" != "yes"
|
||||
systemctl reload ssh 2>/dev/null || systemctl reload sshd
|
||||
printf 'PASSWORD_AUTH=%s\nROOT_PASSWORD_AUTH=%s\nSSH=%s\nBACKUP=%s\n' \
|
||||
"$password" "$root_login" \
|
||||
"$(systemctl is-active ssh 2>/dev/null || systemctl is-active sshd)" \
|
||||
"$backup_dir/90-guanghu-key-only.conf.before"
|
||||
trap - EXIT`;
|
||||
|
||||
function run(file, args) {
|
||||
return new Promise(resolve => execFile(file, args, { timeout: 30000, maxBuffer: 100000 }, (error, stdout, stderr) => resolve({
|
||||
ok: !error,
|
||||
exit_code: error ? (Number.isInteger(error.code) ? error.code : 1) : 0,
|
||||
stdout: String(stdout || "").slice(0, 100000),
|
||||
stderr: String(stderr || "").slice(0, 10000),
|
||||
})));
|
||||
}
|
||||
|
||||
async function execute(request) {
|
||||
if (!request || request.cmd || request.command || request.shell || request.args) return { ok: false, error: "arbitrary_command_forbidden" };
|
||||
if (request.target !== "JD-FD-PRIMARY" || request.action !== "restore-owner-password-login") return { ok: false, error: "action_not_registered" };
|
||||
return run("/usr/bin/ssh", ["-F", SSH_CONFIG, "-o", "BatchMode=yes", "-o", "ConnectTimeout=10", "enterprise-lighthouse", RESTORE_OWNER_PASSWORD_LOGIN]);
|
||||
}
|
||||
|
||||
function reply(socket, value) { socket.end(`${JSON.stringify(value)}\n`); }
|
||||
|
||||
if (require.main === module) {
|
||||
fs.mkdirSync(path.dirname(SOCKET_PATH), { recursive: true, mode: 0o755 });
|
||||
try { fs.unlinkSync(SOCKET_PATH); } catch (error) { if (error.code !== "ENOENT") throw error; }
|
||||
const server = net.createServer({ allowHalfOpen: true }, socket => {
|
||||
let input = "";
|
||||
socket.setTimeout(5000, () => socket.destroy());
|
||||
socket.on("data", chunk => { input += chunk.toString("utf8"); if (input.length > 4096) socket.destroy(); });
|
||||
socket.on("end", async () => {
|
||||
let request;
|
||||
try { request = JSON.parse(input); } catch { return reply(socket, { ok: false, error: "invalid_request" }); }
|
||||
reply(socket, await execute(request));
|
||||
});
|
||||
});
|
||||
server.listen(SOCKET_PATH, () => {
|
||||
fs.chownSync(SOCKET_PATH, 0, Number(process.env.LAKE_LAMP_AUTHZ_GID || 0));
|
||||
fs.chmodSync(SOCKET_PATH, 0o660);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { execute, RESTORE_OWNER_PASSWORD_LOGIN, SOCKET_PATH };
|
||||
Loading…
Reference in a new issue