grep -c returns exit code 1 when no matches found (even though it
outputs 0), causing `|| echo 0` to append an extra 0 and corrupt
the JSON response. This broke ubus calls and LuCI status display.
Use `: ${var:=0}` pattern instead to provide defaults.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
691 lines
22 KiB
Bash
Executable File
691 lines
22 KiB
Bash
Executable File
#!/bin/sh
|
|
# RPCD backend for mitmproxy LuCI app
|
|
|
|
. /usr/share/libubox/jshn.sh
|
|
|
|
CONFIG="mitmproxy"
|
|
LXC_NAME="mitmproxy"
|
|
LXC_PATH="/srv/lxc"
|
|
LXC_ROOTFS="$LXC_PATH/$LXC_NAME/rootfs"
|
|
|
|
uci_get() { uci -q get ${CONFIG}.$1; }
|
|
uci_set() { uci set ${CONFIG}.$1="$2"; }
|
|
|
|
get_status() {
|
|
local enabled=$(uci_get main.enabled)
|
|
local web_port=$(uci_get main.web_port)
|
|
local proxy_port=$(uci_get main.proxy_port)
|
|
local data_path=$(uci_get main.data_path)
|
|
local mode=$(uci_get main.mode)
|
|
local haproxy_router_enabled=$(uci_get haproxy_router.enabled)
|
|
local haproxy_listen_port=$(uci_get haproxy_router.listen_port)
|
|
|
|
# WAN Protection settings
|
|
local wan_protection_enabled=$(uci_get wan_protection.enabled)
|
|
local wan_interface=$(uci_get wan_protection.wan_interface)
|
|
local crowdsec_feed=$(uci_get wan_protection.crowdsec_feed)
|
|
local block_bots=$(uci_get wan_protection.block_bots)
|
|
|
|
# Check for LXC availability
|
|
local lxc_available=0
|
|
command -v lxc-start >/dev/null 2>&1 && lxc_available=1
|
|
|
|
# Check if container is running
|
|
local running=0
|
|
if [ "$lxc_available" = "1" ]; then
|
|
lxc-info -n "$LXC_NAME" -s 2>/dev/null | grep -q "RUNNING" && running=1
|
|
fi
|
|
|
|
# Check if installed (rootfs exists)
|
|
local installed=0
|
|
[ -d "$LXC_ROOTFS" ] && [ -x "$LXC_ROOTFS/usr/bin/mitmproxy" ] && installed=1
|
|
|
|
# Check nftables status for transparent mode
|
|
local nft_active=0
|
|
if [ "$mode" = "transparent" ] && command -v nft >/dev/null 2>&1; then
|
|
nft list table inet mitmproxy >/dev/null 2>&1 && nft_active=1
|
|
fi
|
|
|
|
# Check nftables status for WAN protection mode
|
|
local nft_wan_active=0
|
|
if [ "$wan_protection_enabled" = "1" ] && command -v nft >/dev/null 2>&1; then
|
|
nft list table inet mitmproxy_wan >/dev/null 2>&1 && nft_wan_active=1
|
|
fi
|
|
|
|
# Get authentication token from container data path
|
|
local token=""
|
|
local token_file="${data_path:-/srv/mitmproxy}/.mitmproxy_token"
|
|
[ -f "$token_file" ] && token=$(cat "$token_file" 2>/dev/null | tr -d '\n')
|
|
|
|
# Auto-ban stats
|
|
local autoban_enabled=$(uci_get autoban.enabled)
|
|
local autoban_sensitivity=$(uci_get autoban.sensitivity)
|
|
local autoban_duration=$(uci_get autoban.ban_duration)
|
|
|
|
# Count threats today
|
|
local threats_today=0
|
|
local threats_log="${data_path:-/srv/mitmproxy}/threats.log"
|
|
if [ -f "$threats_log" ]; then
|
|
local today=$(date -u +%Y-%m-%d)
|
|
threats_today=$(grep -c "\"timestamp\": \"$today" "$threats_log" 2>/dev/null)
|
|
: ${threats_today:=0}
|
|
fi
|
|
|
|
# Count processed autobans
|
|
local autobans_total=0
|
|
local autobans_today=0
|
|
local autoban_log="${data_path:-/srv/mitmproxy}/autoban-processed.log"
|
|
if [ -f "$autoban_log" ]; then
|
|
autobans_total=$(wc -l < "$autoban_log" 2>/dev/null || echo 0)
|
|
local today=$(date +%Y-%m-%d)
|
|
autobans_today=$(grep -c "^$today" "$autoban_log" 2>/dev/null)
|
|
: ${autobans_today:=0}
|
|
fi
|
|
|
|
# Pending autoban requests
|
|
local autobans_pending=0
|
|
local autoban_requests="${data_path:-/srv/mitmproxy}/autoban-requests.log"
|
|
if [ -f "$autoban_requests" ] && [ -s "$autoban_requests" ]; then
|
|
autobans_pending=$(wc -l < "$autoban_requests" 2>/dev/null || echo 0)
|
|
fi
|
|
|
|
cat <<EOFJ
|
|
{
|
|
"enabled": $([ "$enabled" = "1" ] && echo "true" || echo "false"),
|
|
"running": $([ "$running" = "1" ] && echo "true" || echo "false"),
|
|
"installed": $([ "$installed" = "1" ] && echo "true" || echo "false"),
|
|
"lxc_available": $([ "$lxc_available" = "1" ] && echo "true" || echo "false"),
|
|
"docker_available": $([ "$lxc_available" = "1" ] && echo "true" || echo "false"),
|
|
"web_port": ${web_port:-8081},
|
|
"proxy_port": ${proxy_port:-8888},
|
|
"data_path": "${data_path:-/srv/mitmproxy}",
|
|
"mode": "${mode:-regular}",
|
|
"nft_active": $([ "$nft_active" = "1" ] && echo "true" || echo "false"),
|
|
"nft_wan_active": $([ "$nft_wan_active" = "1" ] && echo "true" || echo "false"),
|
|
"token": "${token:-}",
|
|
"haproxy_router_enabled": $([ "$haproxy_router_enabled" = "1" ] && echo "true" || echo "false"),
|
|
"haproxy_listen_port": ${haproxy_listen_port:-8889},
|
|
"wan_protection_enabled": $([ "$wan_protection_enabled" = "1" ] && echo "true" || echo "false"),
|
|
"wan_interface": "${wan_interface:-wan}",
|
|
"crowdsec_feed": $([ "$crowdsec_feed" = "1" ] && echo "true" || echo "false"),
|
|
"block_bots": $([ "$block_bots" = "1" ] && echo "true" || echo "false"),
|
|
"autoban_enabled": $([ "$autoban_enabled" = "1" ] && echo "true" || echo "false"),
|
|
"autoban_sensitivity": "${autoban_sensitivity:-moderate}",
|
|
"autoban_duration": "${autoban_duration:-4h}",
|
|
"threats_today": ${threats_today:-0},
|
|
"autobans_today": ${autobans_today:-0},
|
|
"autobans_total": ${autobans_total:-0},
|
|
"autobans_pending": ${autobans_pending:-0}
|
|
}
|
|
EOFJ
|
|
}
|
|
|
|
get_settings() {
|
|
json_init
|
|
|
|
# Main settings
|
|
local enabled=$(uci_get main.enabled)
|
|
local mode=$(uci_get main.mode)
|
|
local proxy_port=$(uci_get main.proxy_port)
|
|
local web_port=$(uci_get main.web_port)
|
|
local web_host=$(uci_get main.web_host)
|
|
local data_path=$(uci_get main.data_path)
|
|
local memory_limit=$(uci_get main.memory_limit)
|
|
local upstream_proxy=$(uci_get main.upstream_proxy)
|
|
local reverse_target=$(uci_get main.reverse_target)
|
|
local ssl_insecure=$(uci_get main.ssl_insecure)
|
|
local anticache=$(uci_get main.anticache)
|
|
local anticomp=$(uci_get main.anticomp)
|
|
|
|
json_add_boolean "enabled" "${enabled:-0}"
|
|
json_add_string "mode" "${mode:-regular}"
|
|
json_add_int "proxy_port" "${proxy_port:-8888}"
|
|
json_add_int "web_port" "${web_port:-8081}"
|
|
json_add_string "web_host" "${web_host:-0.0.0.0}"
|
|
json_add_string "data_path" "${data_path:-/srv/mitmproxy}"
|
|
json_add_string "memory_limit" "${memory_limit:-256M}"
|
|
json_add_string "upstream_proxy" "${upstream_proxy:-}"
|
|
json_add_string "reverse_target" "${reverse_target:-}"
|
|
json_add_boolean "ssl_insecure" "${ssl_insecure:-0}"
|
|
json_add_boolean "anticache" "${anticache:-0}"
|
|
json_add_boolean "anticomp" "${anticomp:-0}"
|
|
|
|
# WAN Protection settings
|
|
local wan_protection_enabled=$(uci_get wan_protection.enabled)
|
|
local wan_interface=$(uci_get wan_protection.wan_interface)
|
|
local wan_http_port=$(uci_get wan_protection.wan_http_port)
|
|
local wan_https_port=$(uci_get wan_protection.wan_https_port)
|
|
local crowdsec_feed=$(uci_get wan_protection.crowdsec_feed)
|
|
local block_bots=$(uci_get wan_protection.block_bots)
|
|
local rate_limit=$(uci_get wan_protection.rate_limit)
|
|
|
|
json_add_boolean "wan_protection_enabled" "${wan_protection_enabled:-0}"
|
|
json_add_string "wan_interface" "${wan_interface:-wan}"
|
|
json_add_int "wan_http_port" "${wan_http_port:-80}"
|
|
json_add_int "wan_https_port" "${wan_https_port:-443}"
|
|
json_add_boolean "crowdsec_feed" "${crowdsec_feed:-1}"
|
|
json_add_boolean "block_bots" "${block_bots:-0}"
|
|
json_add_int "rate_limit" "${rate_limit:-0}"
|
|
|
|
# Transparent settings (LAN)
|
|
local transparent_enabled=$(uci_get transparent.enabled)
|
|
local transparent_iface=$(uci_get transparent.interface)
|
|
local redirect_http=$(uci_get transparent.redirect_http)
|
|
local redirect_https=$(uci_get transparent.redirect_https)
|
|
|
|
json_add_boolean "transparent_enabled" "${transparent_enabled:-0}"
|
|
json_add_string "transparent_interface" "${transparent_iface:-br-lan}"
|
|
json_add_boolean "redirect_http" "${redirect_http:-1}"
|
|
json_add_boolean "redirect_https" "${redirect_https:-1}"
|
|
|
|
# DPI Mirror settings
|
|
local dpi_mirror_enabled=$(uci_get dpi_mirror.enabled)
|
|
local dpi_interface=$(uci_get dpi_mirror.dpi_interface)
|
|
local mirror_wan=$(uci_get dpi_mirror.mirror_wan)
|
|
local mirror_lan=$(uci_get dpi_mirror.mirror_lan)
|
|
|
|
json_add_boolean "dpi_mirror_enabled" "${dpi_mirror_enabled:-0}"
|
|
json_add_string "dpi_interface" "${dpi_interface:-br-lan}"
|
|
json_add_boolean "mirror_wan" "${mirror_wan:-0}"
|
|
json_add_boolean "mirror_lan" "${mirror_lan:-0}"
|
|
|
|
# Filtering settings
|
|
local filtering_enabled=$(uci_get filtering.enabled)
|
|
local log_requests=$(uci_get filtering.log_requests)
|
|
local filter_cdn=$(uci_get filtering.filter_cdn)
|
|
local filter_media=$(uci_get filtering.filter_media)
|
|
local block_ads=$(uci_get filtering.block_ads)
|
|
|
|
json_add_boolean "filtering_enabled" "${filtering_enabled:-0}"
|
|
json_add_boolean "log_requests" "${log_requests:-1}"
|
|
json_add_boolean "filter_cdn" "${filter_cdn:-0}"
|
|
json_add_boolean "filter_media" "${filter_media:-0}"
|
|
json_add_boolean "block_ads" "${block_ads:-0}"
|
|
|
|
json_dump
|
|
}
|
|
|
|
save_settings() {
|
|
read input
|
|
json_load "$input"
|
|
|
|
# Get values from input
|
|
local mode enabled proxy_port web_port web_host data_path memory_limit
|
|
local upstream_proxy reverse_target ssl_insecure anticache anticomp
|
|
local wan_protection_enabled wan_interface wan_http_port wan_https_port
|
|
local crowdsec_feed block_bots rate_limit
|
|
local transparent_enabled transparent_interface redirect_http redirect_https
|
|
local dpi_mirror_enabled dpi_interface mirror_wan mirror_lan
|
|
local filtering_enabled log_requests filter_cdn filter_media block_ads
|
|
local apply_now
|
|
|
|
json_get_var mode mode
|
|
json_get_var enabled enabled
|
|
json_get_var proxy_port proxy_port
|
|
json_get_var web_port web_port
|
|
json_get_var web_host web_host
|
|
json_get_var data_path data_path
|
|
json_get_var memory_limit memory_limit
|
|
json_get_var upstream_proxy upstream_proxy
|
|
json_get_var reverse_target reverse_target
|
|
json_get_var ssl_insecure ssl_insecure
|
|
json_get_var anticache anticache
|
|
json_get_var anticomp anticomp
|
|
json_get_var wan_protection_enabled wan_protection_enabled
|
|
json_get_var wan_interface wan_interface
|
|
json_get_var wan_http_port wan_http_port
|
|
json_get_var wan_https_port wan_https_port
|
|
json_get_var crowdsec_feed crowdsec_feed
|
|
json_get_var block_bots block_bots
|
|
json_get_var rate_limit rate_limit
|
|
json_get_var transparent_enabled transparent_enabled
|
|
json_get_var transparent_interface transparent_interface
|
|
json_get_var redirect_http redirect_http
|
|
json_get_var redirect_https redirect_https
|
|
json_get_var dpi_mirror_enabled dpi_mirror_enabled
|
|
json_get_var dpi_interface dpi_interface
|
|
json_get_var mirror_wan mirror_wan
|
|
json_get_var mirror_lan mirror_lan
|
|
json_get_var filtering_enabled filtering_enabled
|
|
json_get_var log_requests log_requests
|
|
json_get_var filter_cdn filter_cdn
|
|
json_get_var filter_media filter_media
|
|
json_get_var block_ads block_ads
|
|
json_get_var apply_now apply_now
|
|
|
|
# Now initialize output JSON
|
|
json_init
|
|
|
|
# Ensure UCI sections exist
|
|
uci -q get mitmproxy.main >/dev/null 2>&1 || {
|
|
uci set mitmproxy.main=mitmproxy
|
|
uci set mitmproxy.main.enabled='0'
|
|
uci set mitmproxy.main.mode='regular'
|
|
}
|
|
uci -q get mitmproxy.wan_protection >/dev/null 2>&1 || {
|
|
uci set mitmproxy.wan_protection=wan_protection
|
|
uci set mitmproxy.wan_protection.enabled='0'
|
|
}
|
|
uci -q get mitmproxy.transparent >/dev/null 2>&1 || {
|
|
uci set mitmproxy.transparent=transparent
|
|
uci set mitmproxy.transparent.enabled='0'
|
|
}
|
|
uci -q get mitmproxy.dpi_mirror >/dev/null 2>&1 || {
|
|
uci set mitmproxy.dpi_mirror=dpi_mirror
|
|
uci set mitmproxy.dpi_mirror.enabled='0'
|
|
}
|
|
uci -q get mitmproxy.filtering >/dev/null 2>&1 || {
|
|
uci set mitmproxy.filtering=filtering
|
|
uci set mitmproxy.filtering.enabled='0'
|
|
}
|
|
|
|
# Apply main settings
|
|
[ -n "$mode" ] && uci_set main.mode "$mode"
|
|
[ -n "$enabled" ] && uci_set main.enabled "$enabled"
|
|
[ -n "$proxy_port" ] && uci_set main.proxy_port "$proxy_port"
|
|
[ -n "$web_port" ] && uci_set main.web_port "$web_port"
|
|
[ -n "$web_host" ] && uci_set main.web_host "$web_host"
|
|
[ -n "$data_path" ] && uci_set main.data_path "$data_path"
|
|
[ -n "$memory_limit" ] && uci_set main.memory_limit "$memory_limit"
|
|
[ -n "$upstream_proxy" ] && uci_set main.upstream_proxy "$upstream_proxy"
|
|
[ -n "$reverse_target" ] && uci_set main.reverse_target "$reverse_target"
|
|
[ -n "$ssl_insecure" ] && uci_set main.ssl_insecure "$ssl_insecure"
|
|
[ -n "$anticache" ] && uci_set main.anticache "$anticache"
|
|
[ -n "$anticomp" ] && uci_set main.anticomp "$anticomp"
|
|
|
|
# Apply WAN protection settings
|
|
[ -n "$wan_protection_enabled" ] && uci_set wan_protection.enabled "$wan_protection_enabled"
|
|
[ -n "$wan_interface" ] && uci_set wan_protection.wan_interface "$wan_interface"
|
|
[ -n "$wan_http_port" ] && uci_set wan_protection.wan_http_port "$wan_http_port"
|
|
[ -n "$wan_https_port" ] && uci_set wan_protection.wan_https_port "$wan_https_port"
|
|
[ -n "$crowdsec_feed" ] && uci_set wan_protection.crowdsec_feed "$crowdsec_feed"
|
|
[ -n "$block_bots" ] && uci_set wan_protection.block_bots "$block_bots"
|
|
[ -n "$rate_limit" ] && uci_set wan_protection.rate_limit "$rate_limit"
|
|
|
|
# Apply transparent settings (LAN)
|
|
[ -n "$transparent_enabled" ] && uci_set transparent.enabled "$transparent_enabled"
|
|
[ -n "$transparent_interface" ] && uci_set transparent.interface "$transparent_interface"
|
|
[ -n "$redirect_http" ] && uci_set transparent.redirect_http "$redirect_http"
|
|
[ -n "$redirect_https" ] && uci_set transparent.redirect_https "$redirect_https"
|
|
|
|
# Apply DPI mirror settings
|
|
[ -n "$dpi_mirror_enabled" ] && uci_set dpi_mirror.enabled "$dpi_mirror_enabled"
|
|
[ -n "$dpi_interface" ] && uci_set dpi_mirror.dpi_interface "$dpi_interface"
|
|
[ -n "$mirror_wan" ] && uci_set dpi_mirror.mirror_wan "$mirror_wan"
|
|
[ -n "$mirror_lan" ] && uci_set dpi_mirror.mirror_lan "$mirror_lan"
|
|
|
|
# Apply filtering settings
|
|
[ -n "$filtering_enabled" ] && uci_set filtering.enabled "$filtering_enabled"
|
|
[ -n "$log_requests" ] && uci_set filtering.log_requests "$log_requests"
|
|
[ -n "$filter_cdn" ] && uci_set filtering.filter_cdn "$filter_cdn"
|
|
[ -n "$filter_media" ] && uci_set filtering.filter_media "$filter_media"
|
|
[ -n "$block_ads" ] && uci_set filtering.block_ads "$block_ads"
|
|
|
|
uci commit mitmproxy
|
|
|
|
# Restart service to apply firewall rules if enabled and apply_now is set
|
|
local is_enabled=$(uci_get main.enabled)
|
|
local restarted=0
|
|
if [ "$is_enabled" = "1" ] && [ "$apply_now" = "1" ]; then
|
|
/etc/init.d/mitmproxy restart >/dev/null 2>&1 &
|
|
restarted=1
|
|
fi
|
|
|
|
json_add_boolean "success" 1
|
|
if [ "$restarted" = "1" ]; then
|
|
json_add_string "message" "Settings saved and applied"
|
|
json_add_boolean "restarted" 1
|
|
else
|
|
json_add_string "message" "Settings saved"
|
|
json_add_boolean "restarted" 0
|
|
fi
|
|
|
|
json_dump
|
|
}
|
|
|
|
set_mode() {
|
|
read input
|
|
json_load "$input"
|
|
|
|
local mode apply_now
|
|
json_get_var mode mode
|
|
json_get_var apply_now apply_now
|
|
|
|
json_init
|
|
|
|
if [ -z "$mode" ]; then
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Mode is required"
|
|
json_dump
|
|
return
|
|
fi
|
|
|
|
# Validate mode
|
|
case "$mode" in
|
|
regular|transparent|upstream|reverse) ;;
|
|
*)
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Invalid mode: $mode"
|
|
json_dump
|
|
return
|
|
;;
|
|
esac
|
|
|
|
# Ensure section exists
|
|
uci -q get mitmproxy.main >/dev/null 2>&1 || {
|
|
uci set mitmproxy.main=mitmproxy
|
|
uci set mitmproxy.main.enabled='0'
|
|
}
|
|
|
|
uci_set main.mode "$mode"
|
|
uci commit mitmproxy
|
|
|
|
# Restart to apply firewall rules if needed
|
|
local is_enabled=$(uci_get main.enabled)
|
|
local restarted=0
|
|
if [ "$is_enabled" = "1" ] && [ "$apply_now" = "1" ]; then
|
|
/etc/init.d/mitmproxy restart >/dev/null 2>&1 &
|
|
restarted=1
|
|
fi
|
|
|
|
json_add_boolean "success" 1
|
|
json_add_string "mode" "$mode"
|
|
if [ "$restarted" = "1" ]; then
|
|
json_add_string "message" "Mode set to $mode and applied"
|
|
json_add_boolean "restarted" 1
|
|
else
|
|
json_add_string "message" "Mode set to $mode"
|
|
json_add_boolean "restarted" 0
|
|
fi
|
|
|
|
json_dump
|
|
}
|
|
|
|
setup_firewall() {
|
|
json_init
|
|
|
|
if ! command -v mitmproxyctl >/dev/null 2>&1; then
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "mitmproxyctl not found"
|
|
json_dump
|
|
return
|
|
fi
|
|
|
|
mitmproxyctl firewall-setup >/tmp/mitmproxy-fw.log 2>&1
|
|
local result=$?
|
|
|
|
if [ $result -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Firewall rules applied"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Failed to setup firewall rules"
|
|
local log=$(cat /tmp/mitmproxy-fw.log 2>/dev/null)
|
|
[ -n "$log" ] && json_add_string "details" "$log"
|
|
fi
|
|
|
|
json_dump
|
|
}
|
|
|
|
clear_firewall() {
|
|
json_init
|
|
|
|
if ! command -v mitmproxyctl >/dev/null 2>&1; then
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "mitmproxyctl not found"
|
|
json_dump
|
|
return
|
|
fi
|
|
|
|
mitmproxyctl firewall-clear >/tmp/mitmproxy-fw.log 2>&1
|
|
local result=$?
|
|
|
|
if [ $result -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Firewall rules cleared"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Failed to clear firewall rules"
|
|
fi
|
|
|
|
json_dump
|
|
}
|
|
|
|
do_install() {
|
|
command -v mitmproxyctl >/dev/null 2>&1 && { mitmproxyctl install >/tmp/mitmproxy-install.log 2>&1 & echo '{"success":true,"message":"Installing"}'; } || echo '{"success":false,"error":"mitmproxyctl not found"}'
|
|
}
|
|
|
|
do_start() { [ -x /etc/init.d/mitmproxy ] && /etc/init.d/mitmproxy start >/dev/null 2>&1; echo '{"success":true}'; }
|
|
do_stop() { [ -x /etc/init.d/mitmproxy ] && /etc/init.d/mitmproxy stop >/dev/null 2>&1; echo '{"success":true}'; }
|
|
do_restart() { [ -x /etc/init.d/mitmproxy ] && /etc/init.d/mitmproxy restart >/dev/null 2>&1; echo '{"success":true}'; }
|
|
|
|
get_alerts() {
|
|
# Read alerts from host-visible JSONL log file
|
|
# The analytics addon writes to /data/threats.log inside container
|
|
# which is bind-mounted to /srv/mitmproxy/threats.log on host
|
|
local log_file="/srv/mitmproxy/threats.log"
|
|
local max_alerts=50
|
|
local alerts_json="[]"
|
|
|
|
# Read last N lines from the host-accessible log file
|
|
if [ -f "$log_file" ]; then
|
|
local lines=$(tail -n "$max_alerts" "$log_file" 2>/dev/null)
|
|
if [ -n "$lines" ]; then
|
|
# Convert JSONL to JSON array: join lines with commas, wrap in brackets
|
|
alerts_json=$(echo "$lines" | awk '
|
|
BEGIN { printf "[" }
|
|
NR > 1 { printf "," }
|
|
{ printf "%s", $0 }
|
|
END { printf "]" }
|
|
')
|
|
fi
|
|
fi
|
|
|
|
# Validate JSON - if invalid, return empty array
|
|
if ! echo "$alerts_json" | jsonfilter -e '@' >/dev/null 2>&1; then
|
|
alerts_json="[]"
|
|
fi
|
|
|
|
cat <<EOFJ
|
|
{
|
|
"success": true,
|
|
"alerts": $alerts_json,
|
|
"timestamp": "$(date -Iseconds)"
|
|
}
|
|
EOFJ
|
|
}
|
|
|
|
get_threat_stats() {
|
|
local stats_file="/tmp/secubox-mitm-stats.json"
|
|
local container_stats=""
|
|
|
|
# Try to get stats from LXC container
|
|
if command -v lxc-attach >/dev/null 2>&1; then
|
|
container_stats=$(lxc-attach -n "$LXC_NAME" -- cat /tmp/secubox-mitm-stats.json 2>/dev/null)
|
|
fi
|
|
|
|
# Fall back to host path
|
|
if [ -z "$container_stats" ]; then
|
|
[ -f "$stats_file" ] && container_stats=$(cat "$stats_file" 2>/dev/null)
|
|
fi
|
|
|
|
# Default stats
|
|
[ -z "$container_stats" ] && container_stats='{"total":{"requests":0,"threats":0,"bots":0}}'
|
|
|
|
cat <<EOFJ
|
|
{
|
|
"success": true,
|
|
"stats": $container_stats,
|
|
"timestamp": "$(date -Iseconds)"
|
|
}
|
|
EOFJ
|
|
}
|
|
|
|
clear_alerts() {
|
|
# Clear the host-visible threats log file
|
|
local log_file="/srv/mitmproxy/threats.log"
|
|
> "$log_file" 2>/dev/null
|
|
|
|
# Also clear the legacy alerts file
|
|
echo "[]" > /tmp/secubox-mitm-alerts.json 2>/dev/null
|
|
|
|
echo '{"success":true,"message":"Alerts cleared"}'
|
|
}
|
|
|
|
haproxy_enable() {
|
|
json_init
|
|
|
|
if ! command -v mitmproxyctl >/dev/null 2>&1; then
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "mitmproxyctl not found"
|
|
json_dump
|
|
return
|
|
fi
|
|
|
|
mitmproxyctl haproxy-enable >/tmp/haproxy-enable.log 2>&1
|
|
local result=$?
|
|
|
|
if [ $result -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "HAProxy backend inspection enabled"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Failed to enable HAProxy inspection"
|
|
local log=$(cat /tmp/haproxy-enable.log 2>/dev/null)
|
|
[ -n "$log" ] && json_add_string "details" "$log"
|
|
fi
|
|
|
|
json_dump
|
|
}
|
|
|
|
haproxy_disable() {
|
|
json_init
|
|
|
|
if ! command -v mitmproxyctl >/dev/null 2>&1; then
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "mitmproxyctl not found"
|
|
json_dump
|
|
return
|
|
fi
|
|
|
|
mitmproxyctl haproxy-disable >/tmp/haproxy-disable.log 2>&1
|
|
local result=$?
|
|
|
|
if [ $result -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "HAProxy backend inspection disabled"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Failed to disable HAProxy inspection"
|
|
fi
|
|
|
|
json_dump
|
|
}
|
|
|
|
sync_routes() {
|
|
json_init
|
|
|
|
if ! command -v mitmproxyctl >/dev/null 2>&1; then
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "mitmproxyctl not found"
|
|
json_dump
|
|
return
|
|
fi
|
|
|
|
mitmproxyctl sync-routes >/tmp/sync-routes.log 2>&1
|
|
local result=$?
|
|
|
|
if [ $result -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "Routes synced from HAProxy"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Failed to sync routes"
|
|
fi
|
|
|
|
json_dump
|
|
}
|
|
|
|
wan_setup() {
|
|
json_init
|
|
|
|
if ! command -v mitmproxyctl >/dev/null 2>&1; then
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "mitmproxyctl not found"
|
|
json_dump
|
|
return
|
|
fi
|
|
|
|
mitmproxyctl wan-setup >/tmp/wan-setup.log 2>&1
|
|
local result=$?
|
|
|
|
if [ $result -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "WAN protection rules applied"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Failed to setup WAN protection rules"
|
|
local log=$(cat /tmp/wan-setup.log 2>/dev/null)
|
|
[ -n "$log" ] && json_add_string "details" "$log"
|
|
fi
|
|
|
|
json_dump
|
|
}
|
|
|
|
wan_clear() {
|
|
json_init
|
|
|
|
if ! command -v mitmproxyctl >/dev/null 2>&1; then
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "mitmproxyctl not found"
|
|
json_dump
|
|
return
|
|
fi
|
|
|
|
mitmproxyctl wan-clear >/tmp/wan-clear.log 2>&1
|
|
local result=$?
|
|
|
|
if [ $result -eq 0 ]; then
|
|
json_add_boolean "success" 1
|
|
json_add_string "message" "WAN protection rules cleared"
|
|
else
|
|
json_add_boolean "success" 0
|
|
json_add_string "error" "Failed to clear WAN protection rules"
|
|
fi
|
|
|
|
json_dump
|
|
}
|
|
|
|
list_methods() { cat <<'EOFM'
|
|
{"status":{},"settings":{},"save_settings":{"mode":"str","enabled":"bool","proxy_port":"int","web_port":"int","apply_now":"bool","wan_protection_enabled":"bool","wan_interface":"str"},"set_mode":{"mode":"str","apply_now":"bool"},"setup_firewall":{},"clear_firewall":{},"wan_setup":{},"wan_clear":{},"install":{},"start":{},"stop":{},"restart":{},"alerts":{},"threat_stats":{},"clear_alerts":{},"haproxy_enable":{},"haproxy_disable":{},"sync_routes":{}}
|
|
EOFM
|
|
}
|
|
|
|
case "$1" in
|
|
list) list_methods ;;
|
|
call)
|
|
case "$2" in
|
|
status) get_status ;;
|
|
settings) get_settings ;;
|
|
save_settings) save_settings ;;
|
|
set_mode) set_mode ;;
|
|
setup_firewall) setup_firewall ;;
|
|
clear_firewall) clear_firewall ;;
|
|
wan_setup) wan_setup ;;
|
|
wan_clear) wan_clear ;;
|
|
install) do_install ;;
|
|
start) do_start ;;
|
|
stop) do_stop ;;
|
|
restart) do_restart ;;
|
|
alerts) get_alerts ;;
|
|
threat_stats) get_threat_stats ;;
|
|
clear_alerts) clear_alerts ;;
|
|
haproxy_enable) haproxy_enable ;;
|
|
haproxy_disable) haproxy_disable ;;
|
|
sync_routes) sync_routes ;;
|
|
*) echo '{"error":"Unknown method"}' ;;
|
|
esac
|
|
;;
|
|
*) echo '{"error":"Unknown command"}' ;;
|
|
esac
|