Advertisement
Guest User

Untitled

a guest
May 25th, 2015
218
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.49 KB | None | 0 0
  1. # SSH tunnel script
  2. #
  3. # Set the following environment variables:
  4. #
  5. # SSH_TUNNEL_TARGET=user@hostname:port
  6. # SSH_TUNNEL_KEY=RSA:{base64 private key}
  7. # SSH_TUNNEL_FORWARDS=localaddr:localport:remoteaddr:remoteport,[...]
  8. #
  9. # Notes:
  10. #
  11. # SSH_TUNNEL_KEY is the key type (e.g. "RSA"), a colon character, and then
  12. # the ssh private key in base64 without the headers/footers or newlines.
  13. # Yes, you're setting an entire giant ssh key as an environment variable,
  14. # but it works. :)
  15. #
  16. # SSH_TUNNEL_FORWARDS is a comma-separated list of args that would normally
  17. # each be preceded by -L in an ssh command.
  18. #
  19. # In your Procfile, simply run the tunnel before any workers that need it.
  20. #
  21. # web: python tunnel.py && ....
  22. #
  23. # It's safe to run the script multiple times concurrently. Only one tunnel will
  24. # be made and the other invocations will fail successfully. This way multiple
  25. # workers can depend on the tunnel, and you can still use foreman locally.
  26. #
  27. import os
  28. import sys
  29. from tempfile import NamedTemporaryFile
  30. import subprocess
  31.  
  32. def check_already_running(forwards):
  33. try:
  34. lines = subprocess.check_output(['pgrep', '-x', '-a', 'ssh']).split('\n')
  35. except subprocess.CalledProcessError:
  36. lines = list()
  37.  
  38. for line in lines:
  39. if not line:
  40. continue
  41. pid, cmd = line.split(' ', 1)
  42. pid = int(pid)
  43. found = False
  44. for f in forwards:
  45. if f in cmd:
  46. found = True
  47. break
  48. if found:
  49. print 'SSH tunnel already running. PID=%d' % pid
  50. return True
  51. return False
  52.  
  53. target = os.environ['SSH_TUNNEL_TARGET']
  54. at = target.find(':')
  55. if at != -1:
  56. port = int(target[at + 1:])
  57. target = target[:at]
  58. else:
  59. port = None
  60.  
  61. key = os.environ['SSH_TUNNEL_KEY']
  62.  
  63. forwards = os.environ['SSH_TUNNEL_FORWARDS'].split(',')
  64.  
  65. type, blob = key.split(':', 1)
  66.  
  67. out = '-----BEGIN %s PRIVATE KEY-----\n' % type
  68. for n in range(0, ((len(blob) - 1) / 64) + 1):
  69. out += blob[n*64:(n*64)+64] + '\n'
  70. out += '-----END %s PRIVATE KEY-----\n' % type
  71.  
  72. f = NamedTemporaryFile(delete=False)
  73. key_file = f.name
  74.  
  75. try:
  76. f.write(out)
  77. f.close()
  78.  
  79. args = [
  80. 'ssh',
  81. '-f',
  82. '-N',
  83. '-i', key_file,
  84. '-o', 'StrictHostKeyChecking=no',
  85. '-o', 'ExitOnForwardFailure=yes'
  86. ]
  87.  
  88. for f in forwards:
  89. args.extend(['-L', f])
  90.  
  91. if port is not None:
  92. args.extend(['-p', str(port)])
  93.  
  94. args.append(target)
  95.  
  96. cmd = ' '.join(args)
  97.  
  98. if check_already_running(forwards):
  99. sys.exit(0)
  100.  
  101. print 'Starting SSH tunnel: %s' % cmd
  102.  
  103. try:
  104. subprocess.check_call(args)
  105. except subprocess.CalledProcessError:
  106. if not check_already_running(forwards):
  107. raise
  108. finally:
  109. os.remove(key_file)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement