secubox-openwrt/secubox-tools/rpcd/vhost-manager

335 lines
10 KiB
Plaintext
Raw Normal View History

2025-12-23 00:30:26 +00:00
#!/bin/sh
# /usr/libexec/rpcd/vhost-manager
# RPCD backend for VHost Manager module
# Provides ubus interface: luci.vhost-manager
. /lib/functions.sh
. /usr/share/libubox/jshn.sh
# Configuration
UCI_CONFIG="vhost_manager"
NGINX_VHOSTS_DIR="/etc/nginx/conf.d"
ACME_DIR="/etc/acme"
# Helper: Check if nginx is running
nginx_running() {
pgrep -x nginx > /dev/null 2>&1
}
# Helper: Get nginx status
get_nginx_status() {
if nginx_running; then
echo "running"
else
echo "stopped"
fi
}
# Helper: Count vhosts
count_vhosts() {
if [ -d "$NGINX_VHOSTS_DIR" ]; then
ls -1 "$NGINX_VHOSTS_DIR"/*.conf 2>/dev/null | wc -l
else
echo "0"
fi
}
# Helper: List vhosts
list_vhosts() {
json_add_array "vhosts"
if [ -d "$NGINX_VHOSTS_DIR" ]; then
for conf in "$NGINX_VHOSTS_DIR"/*.conf; do
[ -f "$conf" ] || continue
# Extract server_name from config
SERVER_NAME=$(grep -m1 "server_name" "$conf" | awk '{print $2}' | tr -d ';')
PROXY_PASS=$(grep -m1 "proxy_pass" "$conf" | awk '{print $2}' | tr -d ';')
SSL_ENABLED="false"
if grep -q "ssl_certificate" "$conf"; then
SSL_ENABLED="true"
fi
json_add_object ""
json_add_string "name" "$(basename "$conf" .conf)"
json_add_string "domain" "$SERVER_NAME"
json_add_string "backend" "$PROXY_PASS"
json_add_boolean "ssl" "$SSL_ENABLED"
json_add_boolean "enabled" 1
json_close_object
done
fi
json_close_array
}
# Helper: Get SSL certificates
list_certificates() {
json_add_array "certificates"
if [ -d "$ACME_DIR" ]; then
for cert_dir in "$ACME_DIR"/*/; do
[ -d "$cert_dir" ] || continue
DOMAIN=$(basename "$cert_dir")
CERT_FILE="$cert_dir/fullchain.cer"
if [ -f "$CERT_FILE" ]; then
# Get expiry date
EXPIRY=$(openssl x509 -enddate -noout -in "$CERT_FILE" 2>/dev/null | cut -d= -f2)
json_add_object ""
json_add_string "domain" "$DOMAIN"
json_add_string "expiry" "$EXPIRY"
json_add_boolean "valid" 1
json_close_object
fi
done
fi
json_close_array
}
# Initialize JSON
json_init
case "$1" in
list)
# List available methods
json_add_object "status"
json_close_object
json_add_object "get_vhosts"
json_close_object
json_add_object "get_vhost"
json_add_string "name" "string"
json_close_object
json_add_object "add_vhost"
json_add_string "domain" "string"
json_add_string "backend" "string"
json_add_boolean "ssl" false
json_close_object
json_add_object "delete_vhost"
json_add_string "name" "string"
json_close_object
json_add_object "get_certificates"
json_close_object
json_add_object "request_certificate"
json_add_string "domain" "string"
json_close_object
json_add_object "reload_nginx"
json_close_object
json_add_object "test_config"
json_close_object
json_dump
;;
call)
case "$2" in
status)
# Return module status
json_add_string "module" "vhost-manager"
json_add_string "version" "2.0.0"
json_add_string "nginx_status" "$(get_nginx_status)"
json_add_boolean "nginx_running" $(nginx_running && echo 1 || echo 0)
json_add_int "vhost_count" "$(count_vhosts)"
json_add_string "config_dir" "$NGINX_VHOSTS_DIR"
json_add_string "acme_dir" "$ACME_DIR"
# Check nginx version
if command -v nginx > /dev/null 2>&1; then
NGINX_VERSION=$(nginx -v 2>&1 | cut -d/ -f2)
json_add_string "nginx_version" "$NGINX_VERSION"
fi
json_dump
;;
get_vhosts)
# Return list of vhosts
list_vhosts
json_dump
;;
get_vhost)
# Get single vhost details
read -r input
json_load "$input"
json_get_var vhost_name name
CONF_FILE="$NGINX_VHOSTS_DIR/${vhost_name}.conf"
if [ -f "$CONF_FILE" ]; then
json_add_boolean "found" 1
json_add_string "name" "$vhost_name"
json_add_string "config" "$(cat "$CONF_FILE")"
else
json_add_boolean "found" 0
json_add_string "error" "VHost not found"
fi
json_dump
;;
add_vhost)
# Add new vhost
read -r input
json_load "$input"
json_get_var domain domain
json_get_var backend backend
json_get_var ssl ssl
# Validate
if [ -z "$domain" ] || [ -z "$backend" ]; then
json_init
json_add_boolean "success" 0
json_add_string "error" "Domain and backend are required"
json_dump
exit 0
fi
# Create config
VHOST_NAME=$(echo "$domain" | tr '.' '-')
CONF_FILE="$NGINX_VHOSTS_DIR/${VHOST_NAME}.conf"
mkdir -p "$NGINX_VHOSTS_DIR"
cat > "$CONF_FILE" << NGINX_EOF
server {
listen 80;
listen [::]:80;
server_name $domain;
location / {
proxy_pass $backend;
proxy_http_version 1.1;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
}
}
NGINX_EOF
json_init
json_add_boolean "success" 1
json_add_string "message" "VHost created"
json_add_string "config_file" "$CONF_FILE"
json_dump
;;
delete_vhost)
# Delete vhost
read -r input
json_load "$input"
json_get_var vhost_name name
CONF_FILE="$NGINX_VHOSTS_DIR/${vhost_name}.conf"
if [ -f "$CONF_FILE" ]; then
rm -f "$CONF_FILE"
json_init
json_add_boolean "success" 1
json_add_string "message" "VHost deleted"
else
json_init
json_add_boolean "success" 0
json_add_string "error" "VHost not found"
fi
json_dump
;;
get_certificates)
# List SSL certificates
list_certificates
json_dump
;;
request_certificate)
# Request Let's Encrypt certificate
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
exit 0
fi
# Check if acme.sh is available
if command -v acme.sh > /dev/null 2>&1; then
# Request certificate (async - just start the process)
acme.sh --issue -d "$domain" --webroot /www --keylength ec-256 &
json_init
json_add_boolean "success" 1
json_add_string "message" "Certificate request started"
json_add_string "domain" "$domain"
else
json_init
json_add_boolean "success" 0
json_add_string "error" "acme.sh not installed"
fi
json_dump
;;
reload_nginx)
# Reload nginx configuration
if nginx -t > /dev/null 2>&1; then
/etc/init.d/nginx reload
json_add_boolean "success" 1
json_add_string "message" "Nginx reloaded"
else
json_add_boolean "success" 0
json_add_string "error" "Configuration test failed"
json_add_string "details" "$(nginx -t 2>&1)"
fi
json_dump
;;
test_config)
# Test nginx configuration
TEST_OUTPUT=$(nginx -t 2>&1)
TEST_RESULT=$?
if [ $TEST_RESULT -eq 0 ]; then
json_add_boolean "valid" 1
json_add_string "message" "Configuration OK"
else
json_add_boolean "valid" 0
json_add_string "error" "$TEST_OUTPUT"
fi
json_dump
;;
*)
# Unknown method
json_add_int "error" -32601
json_add_string "message" "Method not found: $2"
json_dump
;;
esac
;;
*)
echo "Usage: $0 {list|call}"
exit 1
;;
esac