OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 |
| 3 '''This starts an SSH tunnel to a given host. If the SSH process ever dies then |
| 4 this script will detect that and restart it. I use this under Cygwin to keep |
| 5 open encrypted tunnels to port 25 (SMTP), port 143 (IMAP4), and port 110 |
| 6 (POP3). I set my mail client to talk to localhost and I keep this script |
| 7 running in the background. |
| 8 |
| 9 Note that this is a rather stupid script at the moment because it just looks to |
| 10 see if any ssh process is running. It should really make sure that our specific |
| 11 ssh process is running. The problem is that ssh is missing a very useful |
| 12 feature. It has no way to report the process id of the background daemon that |
| 13 it creates with the -f command. This would be a really useful script if I could |
| 14 figure a way around this problem. |
| 15 |
| 16 PEXPECT LICENSE |
| 17 |
| 18 This license is approved by the OSI and FSF as GPL-compatible. |
| 19 http://opensource.org/licenses/isc-license.txt |
| 20 |
| 21 Copyright (c) 2012, Noah Spurrier <noah@noah.org> |
| 22 PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY |
| 23 PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE |
| 24 COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. |
| 25 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 26 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 27 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
| 28 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 29 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
| 30 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
| 31 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
| 32 |
| 33 ''' |
| 34 |
| 35 from __future__ import print_function |
| 36 |
| 37 from __future__ import absolute_import |
| 38 |
| 39 import pexpect |
| 40 import getpass |
| 41 import time |
| 42 |
| 43 |
| 44 try: |
| 45 raw_input |
| 46 except NameError: |
| 47 raw_input = input |
| 48 |
| 49 |
| 50 # SMTP:25 IMAP4:143 POP3:110 |
| 51 tunnel_command = 'ssh -C -N -f -L 25:127.0.0.1:25 -L 143:127.0.0.1:143 -L 110:12
7.0.0.1:110 %(user)@%(host)' |
| 52 host = raw_input('Hostname: ') |
| 53 user = raw_input('Username: ') |
| 54 X = getpass.getpass('Password: ') |
| 55 |
| 56 def get_process_info (): |
| 57 |
| 58 # This seems to work on both Linux and BSD, but should otherwise be consider
ed highly UNportable. |
| 59 |
| 60 ps = pexpect.run ('ps ax -O ppid') |
| 61 pass |
| 62 |
| 63 def start_tunnel (): |
| 64 |
| 65 try: |
| 66 ssh_tunnel = pexpect.spawn (tunnel_command % globals()) |
| 67 ssh_tunnel.expect ('password:') |
| 68 time.sleep (0.1) |
| 69 ssh_tunnel.sendline (X) |
| 70 time.sleep (60) # Cygwin is slow to update process status. |
| 71 ssh_tunnel.expect (pexpect.EOF) |
| 72 |
| 73 except Exception as e: |
| 74 print(str(e)) |
| 75 |
| 76 def main (): |
| 77 |
| 78 while True: |
| 79 ps = pexpect.spawn ('ps') |
| 80 time.sleep (1) |
| 81 index = ps.expect (['/usr/bin/ssh', pexpect.EOF, pexpect.TIMEOUT]) |
| 82 if index == 2: |
| 83 print('TIMEOUT in ps command...') |
| 84 print(str(ps)) |
| 85 time.sleep (13) |
| 86 if index == 1: |
| 87 print(time.asctime(), end=' ') |
| 88 print('restarting tunnel') |
| 89 start_tunnel () |
| 90 time.sleep (11) |
| 91 print('tunnel OK') |
| 92 else: |
| 93 # print 'tunnel OK' |
| 94 time.sleep (7) |
| 95 |
| 96 if __name__ == '__main__': |
| 97 |
| 98 main () |
| 99 |
| 100 # This was for older SSH versions that didn't have -f option |
| 101 #tunnel_command = 'ssh -C -n -L 25:%(host)s:25 -L 110:%(host)s:110 %(user)s@%(ho
st)s -f nothing.sh' |
| 102 #nothing_script = '''#!/bin/sh |
| 103 #while true; do sleep 53; done |
| 104 #''' |
| 105 |
OLD | NEW |