- Add enhanced instant ban for critical threats (SQL injection, CVE exploits, RCE) - CrowdSec trigger scenario for single-hit bans on severity=critical - Instant ban daemon (10s polling) for rapid response - UCI options: instant_ban_enabled, instant_ban_duration (48h default) - WAF addon updated to route critical threats to instant-ban.log - Add centralized user management (secubox-core-users, luci-app-secubox-users) - CLI tool: secubox-users add/del/passwd/list/sync/status - LuCI dashboard under System > SecuBox Users - Unified user provisioning across Nextcloud, PeerTube, Matrix, Jabber, Email - Add Matrix/Conduit integration (secubox-app-matrix, luci-app-matrix) - LXC-based Conduit homeserver deployment - Full RPCD handler with user/room management - HAProxy integration for federation - Add provision-users.sh script for bulk user creation - Update secubox-feed with new IPKs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
461 lines
9.9 KiB
Bash
461 lines
9.9 KiB
Bash
#!/bin/sh
|
|
|
|
# RPCD backend for Matrix Homeserver LuCI app
|
|
|
|
. /usr/share/libubox/jshn.sh
|
|
|
|
MATRIXCTL="/usr/sbin/matrixctl"
|
|
|
|
# Helper to get UCI value
|
|
uci_get() {
|
|
local section="$1"
|
|
local option="$2"
|
|
local default="$3"
|
|
local val
|
|
val=$(uci -q get "matrix.${section}.${option}")
|
|
echo "${val:-$default}"
|
|
}
|
|
|
|
# Get container status
|
|
get_container_status() {
|
|
local state="not_installed"
|
|
local running="false"
|
|
local lxc_info=""
|
|
|
|
if [ -d "/srv/lxc/matrix" ]; then
|
|
state="installed"
|
|
lxc_info=$(lxc-info -n matrix 2>/dev/null)
|
|
if echo "$lxc_info" | grep -q "State:.*RUNNING"; then
|
|
running="true"
|
|
fi
|
|
fi
|
|
|
|
echo "$state $running"
|
|
}
|
|
|
|
# Method: status
|
|
method_status() {
|
|
local enabled hostname http_port port
|
|
local container_state running version
|
|
local info
|
|
|
|
enabled=$(uci_get main enabled 0)
|
|
hostname=$(uci_get server hostname "matrix.local")
|
|
http_port=$(uci_get server http_port "8008")
|
|
port=$(uci_get server port "8448")
|
|
|
|
info=$(get_container_status)
|
|
container_state=$(echo "$info" | awk '{print $1}')
|
|
running=$(echo "$info" | awk '{print $2}')
|
|
|
|
# Get version if running
|
|
version=""
|
|
if [ "$running" = "true" ]; then
|
|
version=$(lxc-attach -n matrix -- /usr/local/bin/conduit --version 2>/dev/null | head -1)
|
|
fi
|
|
|
|
# Get configured domain if emancipated
|
|
local domain haproxy federation_enabled registration_enabled
|
|
domain=$(uci_get network domain "")
|
|
haproxy=$(uci_get network haproxy "0")
|
|
federation_enabled=$(uci_get federation enabled "1")
|
|
registration_enabled=$(uci_get server registration_enabled "0")
|
|
|
|
# Identity and mesh
|
|
local did_linked mesh_published
|
|
did_linked=$(uci_get identity did_linked "0")
|
|
mesh_published=$(uci_get mesh published "0")
|
|
|
|
json_init
|
|
json_add_string "enabled" "$enabled"
|
|
json_add_string "container_state" "$container_state"
|
|
json_add_string "running" "$running"
|
|
json_add_string "hostname" "$hostname"
|
|
json_add_string "http_port" "$http_port"
|
|
json_add_string "port" "$port"
|
|
json_add_string "version" "$version"
|
|
json_add_string "domain" "$domain"
|
|
json_add_string "haproxy" "$haproxy"
|
|
json_add_string "federation_enabled" "$federation_enabled"
|
|
json_add_string "registration_enabled" "$registration_enabled"
|
|
json_add_string "did_linked" "$did_linked"
|
|
json_add_string "mesh_published" "$mesh_published"
|
|
json_dump
|
|
}
|
|
|
|
# Method: start
|
|
method_start() {
|
|
local output
|
|
output=$($MATRIXCTL start 2>&1)
|
|
local rc=$?
|
|
|
|
json_init
|
|
if [ $rc -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Matrix homeserver started successfully"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "$output"
|
|
fi
|
|
json_dump
|
|
}
|
|
|
|
# Method: stop
|
|
method_stop() {
|
|
local output
|
|
output=$($MATRIXCTL stop 2>&1)
|
|
local rc=$?
|
|
|
|
json_init
|
|
if [ $rc -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Matrix homeserver stopped successfully"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "$output"
|
|
fi
|
|
json_dump
|
|
}
|
|
|
|
# Method: install
|
|
method_install() {
|
|
local output
|
|
output=$($MATRIXCTL install 2>&1)
|
|
local rc=$?
|
|
|
|
json_init
|
|
if [ $rc -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Matrix homeserver installed successfully"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "$output"
|
|
fi
|
|
json_dump
|
|
}
|
|
|
|
# Method: uninstall
|
|
method_uninstall() {
|
|
local output
|
|
output=$($MATRIXCTL uninstall 2>&1)
|
|
local rc=$?
|
|
|
|
json_init
|
|
if [ $rc -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Matrix homeserver uninstalled successfully"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "$output"
|
|
fi
|
|
json_dump
|
|
}
|
|
|
|
# Method: update
|
|
method_update() {
|
|
local output
|
|
output=$($MATRIXCTL update 2>&1)
|
|
local rc=$?
|
|
|
|
json_init
|
|
if [ $rc -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Matrix homeserver updated successfully"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "$output"
|
|
fi
|
|
json_dump
|
|
}
|
|
|
|
# Method: logs
|
|
method_logs() {
|
|
local lines="${1:-50}"
|
|
local output
|
|
|
|
if [ -d "/srv/lxc/matrix" ]; then
|
|
output=$($MATRIXCTL logs "$lines" 2>&1 | tail -n "$lines")
|
|
else
|
|
output="Container not installed"
|
|
fi
|
|
|
|
json_init
|
|
json_add_string "logs" "$output"
|
|
json_dump
|
|
}
|
|
|
|
# Method: emancipate
|
|
method_emancipate() {
|
|
read -r input
|
|
json_load "$input"
|
|
json_get_var domain domain
|
|
|
|
if [ -z "$domain" ]; then
|
|
json_init
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Domain is required"
|
|
json_dump
|
|
return
|
|
fi
|
|
|
|
local output
|
|
output=$($MATRIXCTL emancipate "$domain" 2>&1)
|
|
local rc=$?
|
|
|
|
json_init
|
|
if [ $rc -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Matrix homeserver emancipated at $domain"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "$output"
|
|
fi
|
|
json_dump
|
|
}
|
|
|
|
# Method: configure_haproxy
|
|
method_configure_haproxy() {
|
|
local output
|
|
output=$($MATRIXCTL configure-haproxy 2>&1)
|
|
local rc=$?
|
|
|
|
json_init
|
|
if [ $rc -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "HAProxy configured successfully"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "$output"
|
|
fi
|
|
json_dump
|
|
}
|
|
|
|
# Method: user_add
|
|
method_user_add() {
|
|
read -r input
|
|
json_load "$input"
|
|
json_get_var mxid mxid
|
|
json_get_var password password
|
|
|
|
if [ -z "$mxid" ]; then
|
|
json_init
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Matrix ID is required"
|
|
json_dump
|
|
return
|
|
fi
|
|
|
|
local output
|
|
output=$($MATRIXCTL user add "$mxid" "$password" 2>&1)
|
|
local rc=$?
|
|
|
|
# Extract password from output
|
|
local new_password
|
|
new_password=$(echo "$output" | grep -oE 'Password: [a-zA-Z0-9]+' | cut -d' ' -f2)
|
|
|
|
json_init
|
|
if [ $rc -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "User created successfully"
|
|
[ -n "$new_password" ] && json_add_string "password" "$new_password"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "$output"
|
|
fi
|
|
json_dump
|
|
}
|
|
|
|
# Method: user_del
|
|
method_user_del() {
|
|
read -r input
|
|
json_load "$input"
|
|
json_get_var mxid mxid
|
|
|
|
if [ -z "$mxid" ]; then
|
|
json_init
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Matrix ID is required"
|
|
json_dump
|
|
return
|
|
fi
|
|
|
|
local output
|
|
output=$($MATRIXCTL user del "$mxid" 2>&1)
|
|
|
|
json_init
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "$output"
|
|
json_dump
|
|
}
|
|
|
|
# Method: federation_status
|
|
method_federation_status() {
|
|
local enabled allow_public trusted
|
|
enabled=$(uci_get federation enabled "1")
|
|
allow_public=$(uci_get federation allow_public_rooms "1")
|
|
trusted=$(uci_get federation trusted_servers "matrix.org")
|
|
|
|
json_init
|
|
json_add_string "enabled" "$enabled"
|
|
json_add_string "allow_public_rooms" "$allow_public"
|
|
json_add_string "trusted_servers" "$trusted"
|
|
json_dump
|
|
}
|
|
|
|
# Method: identity_status
|
|
method_identity_status() {
|
|
local linked mxid did
|
|
linked=$(uci_get identity did_linked "0")
|
|
mxid=$(uci_get identity did_user "")
|
|
did=$(uci -q get "matrix.identity._did")
|
|
|
|
json_init
|
|
json_add_string "linked" "$linked"
|
|
json_add_string "mxid" "$mxid"
|
|
json_add_string "did" "$did"
|
|
json_dump
|
|
}
|
|
|
|
# Method: identity_link
|
|
method_identity_link() {
|
|
read -r input
|
|
json_load "$input"
|
|
json_get_var mxid mxid
|
|
|
|
if [ -z "$mxid" ]; then
|
|
json_init
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Matrix ID is required"
|
|
json_dump
|
|
return
|
|
fi
|
|
|
|
local output
|
|
output=$($MATRIXCTL identity link "$mxid" 2>&1)
|
|
local rc=$?
|
|
|
|
json_init
|
|
if [ $rc -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Identity linked successfully"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "$output"
|
|
fi
|
|
json_dump
|
|
}
|
|
|
|
# Method: identity_unlink
|
|
method_identity_unlink() {
|
|
local output
|
|
output=$($MATRIXCTL identity unlink 2>&1)
|
|
local rc=$?
|
|
|
|
json_init
|
|
if [ $rc -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Identity unlinked"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "$output"
|
|
fi
|
|
json_dump
|
|
}
|
|
|
|
# Method: mesh_status
|
|
method_mesh_status() {
|
|
local published service_name
|
|
published=$(uci_get mesh published "0")
|
|
service_name=$(uci_get mesh service_name "matrix")
|
|
|
|
json_init
|
|
json_add_string "published" "$published"
|
|
json_add_string "service_name" "$service_name"
|
|
json_dump
|
|
}
|
|
|
|
# Method: mesh_publish
|
|
method_mesh_publish() {
|
|
local output
|
|
output=$($MATRIXCTL mesh publish 2>&1)
|
|
local rc=$?
|
|
|
|
json_init
|
|
if [ $rc -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Published to mesh"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "$output"
|
|
fi
|
|
json_dump
|
|
}
|
|
|
|
# Method: mesh_unpublish
|
|
method_mesh_unpublish() {
|
|
local output
|
|
output=$($MATRIXCTL mesh unpublish 2>&1)
|
|
local rc=$?
|
|
|
|
json_init
|
|
if [ $rc -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Removed from mesh"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "$output"
|
|
fi
|
|
json_dump
|
|
}
|
|
|
|
# Main RPC handler
|
|
case "$1" in
|
|
list)
|
|
cat <<'JSON'
|
|
{
|
|
"status": {},
|
|
"logs": {"lines": 50},
|
|
"start": {},
|
|
"stop": {},
|
|
"install": {},
|
|
"uninstall": {},
|
|
"update": {},
|
|
"emancipate": {"domain": "string"},
|
|
"configure_haproxy": {},
|
|
"user_add": {"mxid": "string", "password": "string"},
|
|
"user_del": {"mxid": "string"},
|
|
"federation_status": {},
|
|
"identity_status": {},
|
|
"identity_link": {"mxid": "string"},
|
|
"identity_unlink": {},
|
|
"mesh_status": {},
|
|
"mesh_publish": {},
|
|
"mesh_unpublish": {}
|
|
}
|
|
JSON
|
|
;;
|
|
call)
|
|
case "$2" in
|
|
status) method_status ;;
|
|
logs) method_logs ;;
|
|
start) method_start ;;
|
|
stop) method_stop ;;
|
|
install) method_install ;;
|
|
uninstall) method_uninstall ;;
|
|
update) method_update ;;
|
|
emancipate) method_emancipate ;;
|
|
configure_haproxy) method_configure_haproxy ;;
|
|
user_add) method_user_add ;;
|
|
user_del) method_user_del ;;
|
|
federation_status) method_federation_status ;;
|
|
identity_status) method_identity_status ;;
|
|
identity_link) method_identity_link ;;
|
|
identity_unlink) method_identity_unlink ;;
|
|
mesh_status) method_mesh_status ;;
|
|
mesh_publish) method_mesh_publish ;;
|
|
mesh_unpublish) method_mesh_unpublish ;;
|
|
*) echo '{"error":"Unknown method"}' ;;
|
|
esac
|
|
;;
|
|
esac
|