fix(tor-shield): Fix json_init bug and permission issues
RPCD backend: - Fix critical json_init bug: variables must be extracted BEFORE json_init() which wipes the loaded JSON. Affected functions: save_settings, do_enable, set_bridges, add/remove_hidden_service - Fix process detection: use pgrep instead of pid file - Fix uptime calculation: get PID from pgrep, not pid file - Fix RPC expect unwrapping in getDashboardData for presets Init script: - Remove PidFile directive (procd manages the process) - Clean up stale files before starting to avoid permission issues - Set proper ownership on torrc after generation - Fix iptables chain creation to handle "already exists" gracefully - Remove from OUTPUT chain before attempting chain deletion Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
5400e34e1f
commit
787fe3864e
@ -188,9 +188,13 @@ return baseclass.extend({
|
|||||||
callPresets(),
|
callPresets(),
|
||||||
callBandwidth()
|
callBandwidth()
|
||||||
]).then(function(results) {
|
]).then(function(results) {
|
||||||
|
// Handle RPC expect unwrapping - results may be array or object
|
||||||
|
var presetsData = results[1] || [];
|
||||||
|
var presets = Array.isArray(presetsData) ? presetsData : (presetsData.presets || []);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: results[0] || {},
|
status: results[0] || {},
|
||||||
presets: (results[1] || {}).presets || [],
|
presets: presets,
|
||||||
bandwidth: results[2] || {}
|
bandwidth: results[2] || {}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@ -32,15 +32,10 @@ tor_control() {
|
|||||||
} | socat - UNIX-CONNECT:"$TOR_CONTROL" 2>/dev/null
|
} | socat - UNIX-CONNECT:"$TOR_CONTROL" 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if Tor is running (via tor-shield, not just any tor process)
|
# Check if Tor is running
|
||||||
is_running() {
|
is_running() {
|
||||||
# Check for tor-shield's pid file first
|
# Check for tor process (procd manages the process, no pid file)
|
||||||
if [ -f "$TOR_RUN/tor.pid" ]; then
|
pgrep -f "/usr/sbin/tor" >/dev/null 2>&1
|
||||||
local pid=$(cat "$TOR_RUN/tor.pid" 2>/dev/null)
|
|
||||||
[ -n "$pid" ] && [ -d "/proc/$pid" ] && return 0
|
|
||||||
fi
|
|
||||||
# Fallback to checking any tor process
|
|
||||||
pgrep tor >/dev/null 2>&1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if tor-shield control socket is available
|
# Check if tor-shield control socket is available
|
||||||
@ -113,15 +108,12 @@ get_status() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Uptime from pid file
|
# Uptime from process start time
|
||||||
local pidfile="$TOR_RUN/tor.pid"
|
local pid=$(pgrep -f "/usr/sbin/tor" | head -1)
|
||||||
if [ -f "$pidfile" ]; then
|
if [ -n "$pid" ] && [ -d "/proc/$pid" ]; then
|
||||||
local pid=$(cat "$pidfile")
|
local start_time=$(stat -c %Y "/proc/$pid" 2>/dev/null)
|
||||||
if [ -d "/proc/$pid" ]; then
|
local now=$(date +%s)
|
||||||
local start_time=$(stat -c %Y "/proc/$pid" 2>/dev/null)
|
json_add_int "uptime" "$((now - start_time))"
|
||||||
local now=$(date +%s)
|
|
||||||
json_add_int "uptime" "$((now - start_time))"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
json_add_boolean "running" 0
|
json_add_boolean "running" 0
|
||||||
@ -149,12 +141,15 @@ get_status() {
|
|||||||
do_enable() {
|
do_enable() {
|
||||||
read input
|
read input
|
||||||
json_load "$input"
|
json_load "$input"
|
||||||
|
|
||||||
|
# Get values from input BEFORE json_init
|
||||||
|
local preset
|
||||||
json_get_var preset preset
|
json_get_var preset preset
|
||||||
|
|
||||||
json_init
|
|
||||||
|
|
||||||
[ -z "$preset" ] && preset="anonymous"
|
[ -z "$preset" ] && preset="anonymous"
|
||||||
|
|
||||||
|
# Now initialize output JSON
|
||||||
|
json_init
|
||||||
|
|
||||||
# Load preset configuration
|
# Load preset configuration
|
||||||
config_load "$CONFIG"
|
config_load "$CONFIG"
|
||||||
|
|
||||||
@ -383,10 +378,14 @@ add_hidden_service_json() {
|
|||||||
add_hidden_service() {
|
add_hidden_service() {
|
||||||
read input
|
read input
|
||||||
json_load "$input"
|
json_load "$input"
|
||||||
|
|
||||||
|
# Get values from input BEFORE json_init
|
||||||
|
local name local_port virtual_port
|
||||||
json_get_var name name
|
json_get_var name name
|
||||||
json_get_var local_port local_port
|
json_get_var local_port local_port
|
||||||
json_get_var virtual_port virtual_port
|
json_get_var virtual_port virtual_port
|
||||||
|
|
||||||
|
# Now initialize output JSON
|
||||||
json_init
|
json_init
|
||||||
|
|
||||||
if [ -z "$name" ]; then
|
if [ -z "$name" ]; then
|
||||||
@ -420,8 +419,12 @@ add_hidden_service() {
|
|||||||
remove_hidden_service() {
|
remove_hidden_service() {
|
||||||
read input
|
read input
|
||||||
json_load "$input"
|
json_load "$input"
|
||||||
|
|
||||||
|
# Get values from input BEFORE json_init
|
||||||
|
local name
|
||||||
json_get_var name name
|
json_get_var name name
|
||||||
|
|
||||||
|
# Now initialize output JSON
|
||||||
json_init
|
json_init
|
||||||
|
|
||||||
if [ -z "$name" ]; then
|
if [ -z "$name" ]; then
|
||||||
@ -587,9 +590,13 @@ add_bridge_json() {
|
|||||||
set_bridges() {
|
set_bridges() {
|
||||||
read input
|
read input
|
||||||
json_load "$input"
|
json_load "$input"
|
||||||
|
|
||||||
|
# Get values from input BEFORE json_init
|
||||||
|
local enabled type
|
||||||
json_get_var enabled enabled
|
json_get_var enabled enabled
|
||||||
json_get_var type type
|
json_get_var type type
|
||||||
|
|
||||||
|
# Now initialize output JSON
|
||||||
json_init
|
json_init
|
||||||
|
|
||||||
[ -n "$enabled" ] && uci set tor-shield.bridges.enabled="$enabled"
|
[ -n "$enabled" ] && uci set tor-shield.bridges.enabled="$enabled"
|
||||||
@ -664,9 +671,9 @@ save_settings() {
|
|||||||
read input
|
read input
|
||||||
json_load "$input"
|
json_load "$input"
|
||||||
|
|
||||||
json_init
|
# Get values from input BEFORE json_init (which wipes loaded JSON)
|
||||||
|
local mode dns_over_tor kill_switch socks_port trans_port dns_port
|
||||||
# Get values from input
|
local exit_nodes exclude_exit strict_nodes
|
||||||
json_get_var mode mode
|
json_get_var mode mode
|
||||||
json_get_var dns_over_tor dns_over_tor
|
json_get_var dns_over_tor dns_over_tor
|
||||||
json_get_var kill_switch kill_switch
|
json_get_var kill_switch kill_switch
|
||||||
@ -677,6 +684,9 @@ save_settings() {
|
|||||||
json_get_var exclude_exit exclude_exit_nodes
|
json_get_var exclude_exit exclude_exit_nodes
|
||||||
json_get_var strict_nodes strict_nodes
|
json_get_var strict_nodes strict_nodes
|
||||||
|
|
||||||
|
# Now initialize output JSON
|
||||||
|
json_init
|
||||||
|
|
||||||
# Apply settings
|
# Apply settings
|
||||||
[ -n "$mode" ] && uci set tor-shield.main.mode="$mode"
|
[ -n "$mode" ] && uci set tor-shield.main.mode="$mode"
|
||||||
[ -n "$dns_over_tor" ] && uci set tor-shield.main.dns_over_tor="$dns_over_tor"
|
[ -n "$dns_over_tor" ] && uci set tor-shield.main.dns_over_tor="$dns_over_tor"
|
||||||
|
|||||||
@ -37,6 +37,11 @@ generate_torrc() {
|
|||||||
config_get strict_nodes security strict_nodes '0'
|
config_get strict_nodes security strict_nodes '0'
|
||||||
|
|
||||||
mkdir -p "$TOR_RUN" "$TOR_DATA"
|
mkdir -p "$TOR_RUN" "$TOR_DATA"
|
||||||
|
|
||||||
|
# Clean up stale files that may have wrong ownership
|
||||||
|
rm -f "$TOR_RUN/tor.pid" "$TOR_RUN/control" "$TOR_RUN/control_auth_cookie" 2>/dev/null
|
||||||
|
rm -f "$TOR_DATA/lock" 2>/dev/null
|
||||||
|
|
||||||
chown tor:tor "$TOR_RUN" "$TOR_DATA"
|
chown tor:tor "$TOR_RUN" "$TOR_DATA"
|
||||||
chmod 700 "$TOR_RUN" "$TOR_DATA"
|
chmod 700 "$TOR_RUN" "$TOR_DATA"
|
||||||
|
|
||||||
@ -46,7 +51,6 @@ generate_torrc() {
|
|||||||
|
|
||||||
User tor
|
User tor
|
||||||
DataDirectory $TOR_DATA
|
DataDirectory $TOR_DATA
|
||||||
PidFile $TOR_RUN/tor.pid
|
|
||||||
Log notice syslog
|
Log notice syslog
|
||||||
ControlSocket $TOR_RUN/control
|
ControlSocket $TOR_RUN/control
|
||||||
ControlSocketsGroupWritable 1
|
ControlSocketsGroupWritable 1
|
||||||
@ -123,6 +127,9 @@ EOF
|
|||||||
if [ -f /usr/share/tor/geoip6 ]; then
|
if [ -f /usr/share/tor/geoip6 ]; then
|
||||||
echo "GeoIPv6File /usr/share/tor/geoip6" >> "$TORRC"
|
echo "GeoIPv6File /usr/share/tor/geoip6" >> "$TORRC"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Ensure torrc is readable by tor user
|
||||||
|
chown tor:tor "$TORRC"
|
||||||
}
|
}
|
||||||
|
|
||||||
add_bridge_line() {
|
add_bridge_line() {
|
||||||
@ -166,6 +173,10 @@ setup_iptables() {
|
|||||||
# Get Tor user ID
|
# Get Tor user ID
|
||||||
local tor_uid=$(id -u tor 2>/dev/null || echo "tor")
|
local tor_uid=$(id -u tor 2>/dev/null || echo "tor")
|
||||||
|
|
||||||
|
# Remove from OUTPUT chain first (to allow chain deletion)
|
||||||
|
iptables -t nat -D OUTPUT -j TOR_SHIELD 2>/dev/null
|
||||||
|
iptables -t filter -D OUTPUT -j TOR_SHIELD 2>/dev/null
|
||||||
|
|
||||||
# Clear existing Tor rules
|
# Clear existing Tor rules
|
||||||
iptables -t nat -F TOR_SHIELD 2>/dev/null
|
iptables -t nat -F TOR_SHIELD 2>/dev/null
|
||||||
iptables -t nat -X TOR_SHIELD 2>/dev/null
|
iptables -t nat -X TOR_SHIELD 2>/dev/null
|
||||||
@ -174,9 +185,9 @@ setup_iptables() {
|
|||||||
|
|
||||||
[ "$mode" = "transparent" ] || return 0
|
[ "$mode" = "transparent" ] || return 0
|
||||||
|
|
||||||
# Create chains
|
# Create chains (ignore "already exists" errors)
|
||||||
iptables -t nat -N TOR_SHIELD
|
iptables -t nat -N TOR_SHIELD 2>/dev/null || true
|
||||||
iptables -t filter -N TOR_SHIELD
|
iptables -t filter -N TOR_SHIELD 2>/dev/null || true
|
||||||
|
|
||||||
# Exclude Tor traffic
|
# Exclude Tor traffic
|
||||||
iptables -t nat -A TOR_SHIELD -m owner --uid-owner $tor_uid -j RETURN
|
iptables -t nat -A TOR_SHIELD -m owner --uid-owner $tor_uid -j RETURN
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user