Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/ns-don/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ define Package/ns-don/description
Connect to a remote Windmill installation
endef

define Package/ns-don/prerm
#!/bin/sh
sed -i '\|/usr/sbin/don expire|d' /etc/crontabs/root
endef

# this is required, otherwise compile will fail
define Build/Compile
endef
Expand All @@ -40,6 +45,7 @@ define Package/ns-don/install
$(INSTALL_DIR) $(1)/usr/share/nftables.d/chain-pre/input
$(INSTALL_BIN) ./files/don $(1)/usr/sbin
$(INSTALL_CONF) ./files/20_ns_don $(1)/etc/uci-defaults
$(INSTALL_BIN) ./files/30_don-expire $(1)/etc/uci-defaults
$(INSTALL_CONF) ./files/nethesis.pub $(1)/etc/don
$(INSTALL_CONF) ./files/nethesis.pem $(1)/etc/don
$(INSTALL_DATA) ./files/20-don.nft $(1)/usr/share/nftables.d/chain-pre/input
Expand Down
4 changes: 4 additions & 0 deletions packages/ns-don/files/30_don-expire
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh

grep -q '/usr/sbin/don expire' /etc/crontabs/root 2>/dev/null && exit 0
echo "0 * * * * sleep $(( RANDOM % 60 )); /usr/sbin/don expire" >> /etc/crontabs/root
167 changes: 149 additions & 18 deletions packages/ns-don/files/don
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ rsa_key="$base_dir/rsa_key"
ecdsa_key="$base_dir/ecdsa_key"
socket="$base_dir/management"
credentials="$base_dir/credentials"
session_start="$base_dir/session_start"
session_extended="$base_dir/session_extended"
user="nethsupport"
password=""
ca=$(uci -q get don.config.ca)
Expand All @@ -27,6 +29,18 @@ if [ "$2" == "-j" ]; then
json_output=1
fi

function log_message
{
# Log to /var/log/messages using logger (syslog)
logger -t "don" -p daemon.info "$1"
}

function log_error
{
# Log errors to syslog
logger -t "don" -p daemon.err "$1"
}

function cleanup
{
# stop demons
Expand All @@ -40,19 +54,57 @@ function cleanup
# destroy ubus sessions
session=$(ubus call session list | jq -r '.ubus_rpc_session as $parent | .data.username | select(. == "nethsupport") | $parent')
if [ "$session" != "" ]; then
ubus call session destroy '{"ubus_rpc_session": "'$session'"}'
ubus call session destroy '{"ubus_rpc_session": "'"$session"'"}'
fi
log_message "Remote support session stopped"
}

function show_credentials
function get_session_info
{
# Both session_start and credentials must be present for a valid session
if [ ! -f "$session_start" ] || [ ! -f "$credentials" ]; then
if [ "$json_output" == 1 ]; then
echo "null"
fi
return 1
fi

# Read credentials file into array
mapfile -t creds < "$credentials"
local server_id="${creds[0]}"
local session_id="${creds[1]}"

local session_start_time
session_start_time=$(cat "$session_start")
local session_expiry

# Use extended expiry if available, otherwise use start + 24 hours
if [ -f "$session_extended" ]; then
session_expiry=$(cat "$session_extended")
else
session_expiry=$((session_start_time + 86400))
fi

local current_time
current_time=$(date +%s)
local time_remaining=$((session_expiry - current_time))
local hours_remaining=$((time_remaining / 3600))
local minutes_remaining=$(( (time_remaining % 3600) / 60 ))

if [ "$json_output" == 1 ]; then
echo "{\"server_id\": \"$(sed -n '1{p;q}' $credentials)\", \"session_id\": \"$(sed -n '2{p;q}' $credentials)\"}"
if [ "$time_remaining" -gt 0 ]; then
echo "{\"server_id\": \"$server_id\", \"session_id\": \"$session_id\", \"expires_in_seconds\": $time_remaining, \"expires_in\": \"${hours_remaining}h ${minutes_remaining}m\"}"
else
echo "{\"server_id\": \"$server_id\", \"session_id\": \"$session_id\", \"status\": \"expired\"}"
fi
else
echo -n "Server ID:"
echo -e "\t"$(sed -n '1{p;q}' $credentials)
echo -n "Session ID:"
echo -e "\t"$(sed -n '2{p;q}' $credentials)
echo "Server ID:$(printf '\t')$server_id"
echo "Session ID:$(printf '\t')$session_id"
if [ "$time_remaining" -gt 0 ]; then
echo "Session expires in: ${hours_remaining}h ${minutes_remaining}m"
else
echo "Session EXPIRED"
fi
fi
}

Expand All @@ -67,11 +119,13 @@ start)
system_id=$(uci -q get ns-plug.config.system_id)
fi
if [ -z "$system_id" ]; then
log_error "Remote support session failed: system_id not configured"
exit 2
fi

cn=$(openssl x509 -noout -subject -in $ca | cut -d= -f 2- | sed 's/ = /=/g')
cn=$(openssl x509 -noout -subject -in "$ca" | cut -d= -f 2- | sed 's/ = /=/g')
if [ -z "$cn" ]; then
log_error "Remote support session failed: invalid CA certificate"
exit 3
fi

Expand Down Expand Up @@ -162,38 +216,115 @@ AuthorizedKeysFile $auth_keys
StrictModes no
EOF

mkdir -m 0700 -p /var/empty
/usr/sbin/sshd -f $sshd_conf
cat $(uci -q get don.config.ssh_key) > $auth_keys
mkdir -p /var/empty
chmod 700 /var/empty
/usr/sbin/sshd -f "$sshd_conf"
cat "$(uci -q get don.config.ssh_key)" > "$auth_keys"

# Enable UI access
uci set rpcd.ns_don=login
uci set rpcd.ns_don.username=$user
uci set rpcd.ns_don.password=$(echo $password | mkpasswd)
uci set rpcd.ns_don.password="$(echo "$password" | mkpasswd)"
uci add_list rpcd.ns_don.read='*'
uci add_list rpcd.ns_don.write='*'
# commit rpcd changes
uci commit rpcd

show_credentials
# Save session start time
date +%s > "$session_start"
# Mark as not extended initially
rm -f "$session_extended"
log_message "Remote support session started"

get_session_info
;;
stop)
cleanup
;;
status)
if [ -f $credentials ]; then
show_credentials
exit 0
if [ -f "$credentials" ]; then
get_session_info
exit 0
else
if [ "$json_output" == 1 ]; then
echo null
else
echo "don is not running"
fi
exit 1
exit 1
fi
;;
expire)
# Check if session has expired - requires both files to be present
if [ ! -f "$session_start" ] || [ ! -f "$credentials" ]; then
if [ "$json_output" == 1 ]; then
echo "{\"status\": \"no_session\"}"
else
echo "No session running"
fi
exit 0
fi

session_start_time=$(cat "$session_start")
# Use extended expiry if available, otherwise use start + 24 hours
if [ -f "$session_extended" ]; then
session_expiry=$(cat "$session_extended")
else
session_expiry=$((session_start_time + 86400))
fi

current_time=$(date +%s)
time_remaining=$((session_expiry - current_time))

if [ "$time_remaining" -le 0 ]; then
# Session has expired - STOP IT NOW
if [ "$json_output" == 1 ]; then
echo "{\"status\": \"expired\", \"action\": \"stopping\"}"
else
echo "Session expired - stopping don service"
fi
log_error "Remote support session expired - auto-disabling"
/usr/sbin/don stop
exit 0
fi
;;
extend)
# Extend session by 7 days
if [ ! -f "$session_start" ] || [ ! -f "$credentials" ]; then
echo "No session running"
exit 1
fi

# Validate that the session has not already expired before allowing extension
session_start_time=$(cat "$session_start")
if [ -f "$session_extended" ]; then
session_expiry=$(cat "$session_extended")
else
session_expiry=$((session_start_time + 86400))
fi
current_time=$(date +%s)
time_remaining=$((session_expiry - current_time))

# Do not extend an already-expired session; the user must start a new one
if [ "$time_remaining" -le 0 ]; then
if [ "$json_output" == 1 ]; then
echo "{\"status\": \"error\", \"message\": \"session already expired\"}"
else
echo "Cannot extend: session already expired"
fi
exit 1
fi

# Set expiry to 7 days from now
new_expiry=$((current_time + 604800))
echo "$new_expiry" > "$session_extended"

# Log the extension
log_message "Remote support session extended by 7 days"

get_session_info
;;
*)
echo "Usage: $0 {start|stop|status} [-j]"
echo "Usage: $0 {start|stop|status|expire|extend} [-j]"
exit 2
esac