Skip to content

Instantly share code, notes, and snippets.

@pingswept
Created October 15, 2012 23:04
Show Gist options
  • Save pingswept/3896222 to your computer and use it in GitHub Desktop.
Save pingswept/3896222 to your computer and use it in GitHub Desktop.
Init script for the Rascal's autossh daemon
# command looks like:
# ssh -R *:8080:localhost:8080 [email protected] -N &
#
[autossh_tunnel]
enabled = 1
ssh_keys = /home/root/.ssh/id_rsa
remote_host = rascalmicro.com
remote_username = root
port = 8000
#!/usr/bin/env python
"""rascal-autossh.py - starts and stops the autossh tunnel according to parameters in /etc/rascal-autossh.conf
Usage:
rascal-autossh.py [start|stop|restart]
"""
import os
import sys
import getopt
import subprocess
import ConfigParser
RASCAL_AUTOSSH_CONFIG_FILE_PATH = '/etc/rascal-autossh.conf'
def ssh_keypair_exists(keypair_file_path):
priv_key_path = keypair_file_path
pub_key_path = keypair_file_path + '.pub'
return os.path.exists(priv_key_path) and os.path.exists(pub_key_path)
def generate_ssh_keypair(keypair_file_path):
priv_key_path = keypair_file_path
pub_key_path = keypair_file_path + '.pub'
# force full regeneration by deleting any old remnant files
for filename in [priv_key_path,pub_key_path]:
try:
os.unlink(filename)
except:
pass
# generate a new key pair
p = subprocess.Popen([ '/usr/bin/ssh-keygen', '-b', '768', '-N', '', '-f', priv_key_path ],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(stdoutdata, stderrdata) = p.communicate()
rc = p.returncode
if not (rc==0):
print stdoutdata
print stderrdata
print "%s error: ssh-keygen failed with code %i"%(sys.argv[0],rc)
raise
# pub_key_path = keypair_file_path + '.pub'
# f = open(pub_key_path, 'r')
# pub_key = f.read()
# f.close()
def read_config_file(config_file_path):
ret = {}
config = ConfigParser.ConfigParser()
config.read([ config_file_path ])
if config.has_section('autossh_tunnel'):
#tunnel_params = config.options('autossh_tunnel')
required_params = ['ssh_keys','remote_host','remote_username','port','enabled']
for param_name in required_params:
if config.has_option('autossh_tunnel',param_name):
ret[param_name] = config.get('autossh_tunnel',param_name)
else:
return None
else:
return None
return ret
def start_autossh():
print "Rascal autossh tunnel: ",
tunnel_params = read_config_file(RASCAL_AUTOSSH_CONFIG_FILE_PATH)
if (tunnel_params == None) or (not tunnel_params['enabled'] == '1'):
print 'no tunnel enabled in %s' % RASCAL_AUTOSSH_CONFIG_FILE_PATH
else:
# generate RSA key files if they don't exist yet
if not ssh_keypair_exists(tunnel_params['ssh_keys']):
print "\nGenerating SSH key pair in '%s'" % tunnel_params['ssh_keys']
generate_ssh_keypair(tunnel_params['ssh_keys'])
# start autossh
p = subprocess.Popen([
'/usr/local/bin/autossh',
'-M', '20000',
'-f',
'-i', tunnel_params['ssh_keys'],
'-R', '*:%s:localhost:80'%(tunnel_params['port']),
'-R', '*:2200:localhost:22',
'%s@%s'%(tunnel_params['remote_username'],tunnel_params['remote_host']),
'-N',
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
(stdoutdata, stderrdata) = p.communicate()
rc = p.returncode
if rc == 0:
print "started"
else:
print "failed to start (return code %i)" % rc
def stop_autossh():
print 'Rascal autossh tunnel: ',
p = subprocess.Popen( ['killall', '-SIGINT', 'autossh'], stdout=subprocess.PIPE, stderr=subprocess.PIPE )
(stdoutdata, stderrdata) = p.communicate()
rc = p.returncode
if rc == 0:
print "stopped"
else:
print "failed to kill autossh (was it running?), return code %i" % rc
def main(argv=None):
# parse command line options
if argv is None:
argv = sys.argv
try:
opts, args = getopt.getopt(argv[1:], "h", ["help"])
except getopt.error, msg:
print msg
print "for help use --help"
return 2
# process options
for o, a in opts:
if o in ("-h", "--help"):
print __doc__
return 0
# expecting 1 argument ('start', 'stop' or 'restart')
if not len(args) == 1:
print "%s error: wrong number of arguments; -h for help" % argv[0]
return 2
command = args[0]
if command == 'start':
start_autossh()
elif command == 'stop':
stop_autossh()
elif command == 'restart':
stop_autossh()
start_autossh()
else:
print "%s error: '%s' is not a valid command; -h for help" % (argv[0], command)
return 2
return 0
if __name__ == "__main__":
sys.exit(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment