#!/bin/sh # # RPCD backend for mitmproxy LuCI interface # Copyright (C) 2025 CyberMind.fr (SecuBox) # . /lib/functions.sh CONF_DIR=/etc/mitmproxy DATA_DIR=/tmp/mitmproxy LOG_FILE=/tmp/mitmproxy/requests.log FLOW_FILE=/tmp/mitmproxy/flows.bin # JSON helpers json_init() { echo "{"; } json_close() { echo "}"; } json_add_string() { printf '"%s":"%s"' "$1" "$2"; } json_add_int() { printf '"%s":%d' "$1" "${2:-0}"; } json_add_bool() { [ "$2" = "1" ] && printf '"%s":true' "$1" || printf '"%s":false' "$1"; } # Get service status get_status() { local running=0 local pid="" local mode="unknown" local web_url="" if pgrep mitmweb >/dev/null 2>&1; then running=1 pid=$(pgrep mitmweb | head -1) mode="mitmweb" elif pgrep mitmdump >/dev/null 2>&1; then running=1 pid=$(pgrep mitmdump | head -1) mode="mitmdump" fi local enabled=$(uci -q get mitmproxy.main.enabled || echo "0") local listen_port=$(uci -q get mitmproxy.main.listen_port || echo "8080") local web_port=$(uci -q get mitmproxy.main.web_port || echo "8081") local proxy_mode=$(uci -q get mitmproxy.main.mode || echo "transparent") local router_ip=$(uci -q get network.lan.ipaddr || echo "192.168.1.1") [ "$running" = "1" ] && [ "$mode" = "mitmweb" ] && web_url="http://${router_ip}:${web_port}" cat </dev/null || echo "0") if command -v jq >/dev/null 2>&1; then unique_hosts=$(jq -r '.request.host // .host // empty' "$LOG_FILE" 2>/dev/null | sort -u | wc -l) fi fi if [ -f "$FLOW_FILE" ]; then flow_size=$(ls -l "$FLOW_FILE" 2>/dev/null | awk '{print $5}' || echo "0") fi cat </dev/null 2>&1; then echo '{"requests":' tail -"$limit" "$LOG_FILE" 2>/dev/null | jq -s '.' 2>/dev/null || echo '[]' echo '}' else echo '{"requests":[]}' fi } # Get top hosts get_top_hosts() { local limit="${1:-20}" if [ ! -f "$LOG_FILE" ] || ! command -v jq >/dev/null 2>&1; then echo '{"hosts":[]}' return fi echo '{"hosts":[' jq -r '.request.host // .host // "unknown"' "$LOG_FILE" 2>/dev/null | \ sort | uniq -c | sort -rn | head -"$limit" | \ awk 'BEGIN{first=1} { if(!first) printf ","; first=0; gsub(/"/, "\\\"", $2); printf "{\"host\":\"%s\",\"count\":%d}", $2, $1 }' echo ']}' } # Service control service_start() { /etc/init.d/mitmproxy start >/dev/null 2>&1 sleep 2 get_status } service_stop() { /etc/init.d/mitmproxy stop >/dev/null 2>&1 sleep 1 get_status } service_restart() { /etc/init.d/mitmproxy restart >/dev/null 2>&1 sleep 2 get_status } # Set configuration set_config() { local key="$1" local value="$2" local section="main" case "$key" in save_flows|capture_*) section="capture" ;; esac uci set "mitmproxy.$section.$key=$value" uci commit mitmproxy echo '{"success":true}' } # Clear captured data clear_data() { rm -f "$DATA_DIR"/*.log "$DATA_DIR"/*.bin 2>/dev/null echo '{"success":true,"message":"Captured data cleared"}' } # Get CA certificate info get_ca_info() { local cert="$CONF_DIR/mitmproxy-ca-cert.pem" local router_ip=$(uci -q get network.lan.ipaddr || echo "192.168.1.1") local web_port=$(uci -q get mitmproxy.main.web_port || echo "8081") if [ -f "$cert" ]; then local subject=$(openssl x509 -in "$cert" -noout -subject 2>/dev/null | sed 's/subject=//') local expires=$(openssl x509 -in "$cert" -noout -enddate 2>/dev/null | sed 's/notAfter=//') cat </dev/null || echo "50") get_requests "$limit" ;; get_top_hosts) read -r input limit=$(echo "$input" | jsonfilter -e '@.limit' 2>/dev/null || echo "20") get_top_hosts "$limit" ;; get_ca_info) get_ca_info ;; service_start) service_start ;; service_stop) service_stop ;; service_restart) service_restart ;; set_config) read -r input key=$(echo "$input" | jsonfilter -e '@.key' 2>/dev/null) value=$(echo "$input" | jsonfilter -e '@.value' 2>/dev/null) set_config "$key" "$value" ;; clear_data) clear_data ;; *) echo '{"error":"Unknown method"}' ;; esac ;; *) echo '{"error":"Unknown command"}' ;; esac