DaemonForums  

Go Back   DaemonForums > Miscellaneous > Programming

Programming C, bash, Python, Perl, PHP, Java, you name it.

Reply
 
Thread Tools Display Modes
  #1   (View Single Post)  
Old 15th September 2015
gso gso is offline
Port Guard
 
Join Date: Nov 2014
Posts: 35
Default rc script to start and stop a local ssh socks connection

rc script to start & stop a local ssh SOCKS server, following on from a thread discussing how to obtain the PID of a ssh process.

[Edit 16/09/2015] Re-uploaded, somewhat longer version, but should behave more reliably as a rc script.

[Edit 16/09/2015] My own conclusion at this point at least I think is assuming the control socket can be closed after the connection has been made, it might be preferable to obtain the PID with a control socket rather than, e.g., 'pgrep -P $$ -x ssh'. The parent process can still be double checked, e.g., 'ps -o ppid= -p PID', likewise a process timestamp cached ('ps -o lstart= -p PID ').

[Edit 16/09/2015] The freshly uploaded version of the script implements the latter (i.e., control socket approach), however with the caveat that there is an issue requesting "the master to stop accepting further multiplexing requests" (i.e., the control socket itself is not closed after making the connection and reading the PID; take a look at the commented code in the 'sshsocks_start' function if anyone thinks they may be able to sort the problem out). Tested on a FreeBSD 10.2 install.

Code:
cat >/usr/local/rc.conf.d/sshsocks <<EOT
sshsocks_user=...  
sshsocks_server=...
sshsocks_fwd_addr=...  # default localhost
sshsocks_fwd_port=...  # default 1080
EOT
Code:
#!/bin/sh
#
# PROVIDE: sshsocks socksproxy
# REQUIRE: NETWORK_UP_PLACEHOLDER
# KEYWORD: nostart

name="sshsocks"
. /etc/rc.subr

#set -x

# ssh control socket
test -d "${HOME}"/.ssh || { echo "Script requires a configured ~/.ssh directory to run."; exit 1; }  #todo check perms
control_path="${HOME}"/.ssh/controlmasters
test -d "${control_path}" || mkdir "${control_path}"
# status command PID file
test -d "/var/run/${name}" || mkdir "/var/run/${name}"
pidfile="/var/run/${name}/${name}.pid"

restart_cmd="${name}_restart"
start_cmd="${name}_start"
stop_cmd="${name}_stop"
extra_commands="check status"
check_cmd="${name}_check"
status_cmd="${name}_status"

sshsocks_start()
{
	echo "Starting ssh SOCKS proxy..." >/dev/stderr
	sshsocks_check_running
	if [ $? -eq 0 ]
	then
		echo "Unable to start ssh, process already running" >/dev/stderr
		exit 1
	else
		# Connect to server
		ssh -CN -f -o "ExitOnForwardFailure=yes" -o "ControlMaster=yes" -o "ControlPath=${control_path}/%r@%h:%p" "${sshsocks_user}@${sshsocks_server}"
		# Read process PID
		ssh -O check -S "${control_path}/${sshsocks_user}@%h:%p" "$sshsocks_server" >"$pidfile".check.out 2>&1
		if [ $? -ne 0 ]
		then 
			echo "Error starting the ssh process" >/dev/stderr
			cat "$pidfile".check.out  # any error messages will be here
			sshsocks_cleanup
			#todo check if ssh process has been left running?
			exit 1
		else
			cat "$pidfile".check.out | sed -n '1s/^.*(pid=\([0-9]*\)).*$/\1/p' >"$pidfile"
			#todo check a valid PID is actually returned
			rm "$pidfile".check.out
			ps -p "$(cat "$pidfile")" -o lstart='' >"$pidfile".timestamp
		fi
		# Start forwarding
		ssh -O forward -D "${sshsocks_fwd_addr}:${sshsocks_fwd_port}" -S "${control_path}/${sshsocks_user}@%h:%p" "$sshsocks_server"
		if [ $? -ne 0 ]
		then
			echo "Error starting ssh forwarding" >/dev/stderr
			sshsocks_stop  # close the connection with kill
			exit 1
		fi
		# Close control socket
		#ssh -O stop -S "${control_path}/${sshsocks_user}@%h:%p" "$sshsocks_server" #>/dev/null 2>&1
		#if [ $? -ne 0 ]
		#then
		#	echo "Error closing the control socket" >/dev/stderr
		#	sshsocks_stop  # close the connection with kill if open
		#	exit 1
		#fi
	fi
}

sshsocks_restart()
{
	sshsocks_stop
	sshsocks_start
}

sshsocks_stop()
{
	echo "Stopping ssh SOCKS proxy..." >/dev/stderr
	sshsocks_check_running
	if [ $? -ne 0 ]
	then 
		echo "Unable to stop ssh, process is not running" >/dev/stderr
		exit 1
	else
		kill "$(cat "$pidfile")"
		if [ $? -ne 0 ]
		then
			echo "Error attempting to kill ssh process" >/dev/stderr
			exit 1
		fi
		rm "$pidfile"
		rm "$pidfile".timestamp
	fi
}

sshsocks_status()
{
	sshsocks_check_running
	if [ $? -eq 0 ]
	then 
		cat "$pidfile"
	fi
}

sshsocks_check()
{
	sshsocks_check_running
	if [ $? -ne 0 ]
	then 
		exit 1
	else
		exit 0
	fi
}

sshsocks_check_running()
{
	if [ ! -f "$pidfile" -a ! -f "${pidfile}.timestamp" ]
	then
		return 1  ## SOCKS server not yet started
	elif [ ! -f "$pidfile" -o ! -f "${pidfile}.timestamp" ]
	then
		sshsocks_cleanup
		return 1  ## system crash of some sort
	else
		ps -p "$(cat "$pidfile")" >/dev/null 2>&1
		if [ $? -ne 0 ]
		then
			sshsocks_cleanup
			return 1  ## PID no longer exists
		fi
		ps -o lstart= -p "$(cat "$pidfile")" >"$pidfile".timestamp.cmp
		cmp "$pidfile".timestamp "$pidfile".timestamp.cmp
		if [ $? -ne 0 ]
		then
			sshsocks_cleanup
			return 1  ## a process with the same PID but not ours
		else
			return 0  ## our ssh process is still up and running
		fi
	fi
}

sshsocks_cleanup()
{
	echo "Cleaning up after system failure..."
	test ! -f "$pidfile" || rm "$pidfile"
	test ! -f "$pidfile".check.out || rm "$pidfile".check.out
	test ! -f "${pidfile}.timestamp" || rm "$pidfile".timestamp
	test ! -f "${pidfile}.timestamp.cmp" || rm "$pidfile".timestamp.cmp
}

load_rc_config $name
test -n "$sshsocks_user" || { echo "ssh user not configured"; exit 1; }
test -n "$sshsocks_server" || { echo "ssh server not configured"; exit 1; }
: ${sshsocks_port:=22}
: ${sshsocks_fwd_addr:=localhost}
: ${sshsocks_fwd_port:=1080}

run_rc_command "$1"

exit 0

Last edited by gso; 10th October 2015 at 04:25 PM. Reason: minor bug fix
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Issues with rc.local file (and getting CUPS to start at boot time) Biased OpenBSD General 7 13th January 2014 01:50 PM
Cannot start program in rc.local guitarscn OpenBSD General 2 8th November 2010 01:10 PM
start and stop KDE from shell ccc FreeBSD General 8 8th July 2010 10:12 PM
shell script-start another process bsdnewbie999 Programming 2 23rd April 2009 07:48 PM
start stop services ? smooth187 OpenBSD General 4 31st August 2008 01:00 AM


All times are GMT. The time now is 01:13 PM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2016, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick