##// END OF EJS Templates
ssh tunneling utils into IPython.external.ssh
MinRK -
Show More
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
@@ -29,21 +29,11 b' connection to a destination reachable from the SSH server machine.'
29
29
30 from __future__ import print_function
30 from __future__ import print_function
31
31
32 import getpass
32 import logging
33 import os
34 import socket
35 import select
33 import select
36 import SocketServer
34 import SocketServer
37 import sys
38 from optparse import OptionParser
39
40 import paramiko
41
42 SSH_PORT = 22
43 DEFAULT_PORT = 4000
44
45 g_verbose = False
46
35
36 logger = logging.getLogger('ssh')
47
37
48 class ForwardServer (SocketServer.ThreadingTCPServer):
38 class ForwardServer (SocketServer.ThreadingTCPServer):
49 daemon_threads = True
39 daemon_threads = True
@@ -58,16 +48,16 b' class Handler (SocketServer.BaseRequestHandler):'
58 (self.chain_host, self.chain_port),
48 (self.chain_host, self.chain_port),
59 self.request.getpeername())
49 self.request.getpeername())
60 except Exception, e:
50 except Exception, e:
61 verbose('Incoming request to %s:%d failed: %s' % (self.chain_host,
51 logger.debug('Incoming request to %s:%d failed: %s' % (self.chain_host,
62 self.chain_port,
52 self.chain_port,
63 repr(e)))
53 repr(e)))
64 return
54 return
65 if chan is None:
55 if chan is None:
66 verbose('Incoming request to %s:%d was rejected by the SSH server.' %
56 logger.debug('Incoming request to %s:%d was rejected by the SSH server.' %
67 (self.chain_host, self.chain_port))
57 (self.chain_host, self.chain_port))
68 return
58 return
69
59
70 verbose('Connected! Tunnel open %r -> %r -> %r' % (self.request.getpeername(),
60 logger.debug('Connected! Tunnel open %r -> %r -> %r' % (self.request.getpeername(),
71 chan.getpeername(), (self.chain_host, self.chain_port)))
61 chan.getpeername(), (self.chain_host, self.chain_port)))
72 while True:
62 while True:
73 r, w, x = select.select([self.request, chan], [], [])
63 r, w, x = select.select([self.request, chan], [], [])
@@ -83,7 +73,7 b' class Handler (SocketServer.BaseRequestHandler):'
83 self.request.send(data)
73 self.request.send(data)
84 chan.close()
74 chan.close()
85 self.request.close()
75 self.request.close()
86 verbose('Tunnel closed ')
76 logger.debug('Tunnel closed ')
87
77
88
78
89 def forward_tunnel(local_port, remote_host, remote_port, transport):
79 def forward_tunnel(local_port, remote_host, remote_port, transport):
@@ -97,87 +87,4 b' def forward_tunnel(local_port, remote_host, remote_port, transport):'
97 ForwardServer(('127.0.0.1', local_port), SubHander).serve_forever()
87 ForwardServer(('127.0.0.1', local_port), SubHander).serve_forever()
98
88
99
89
100 def verbose(s):
90 __all__ = ['forward_tunnel'] No newline at end of file
101 if g_verbose:
102 print (s)
103
104
105 HELP = """\
106 Set up a forward tunnel across an SSH server, using paramiko. A local port
107 (given with -p) is forwarded across an SSH session to an address:port from
108 the SSH server. This is similar to the openssh -L option.
109 """
110
111
112 def get_host_port(spec, default_port):
113 "parse 'hostname:22' into a host and port, with the port optional"
114 args = (spec.split(':', 1) + [default_port])[:2]
115 args[1] = int(args[1])
116 return args[0], args[1]
117
118
119 def parse_options():
120 global g_verbose
121
122 parser = OptionParser(usage='usage: %prog [options] <ssh-server>[:<server-port>]',
123 version='%prog 1.0', description=HELP)
124 parser.add_option('-q', '--quiet', action='store_false', dest='verbose', default=True,
125 help='squelch all informational output')
126 parser.add_option('-p', '--local-port', action='store', type='int', dest='port',
127 default=DEFAULT_PORT,
128 help='local port to forward (default: %d)' % DEFAULT_PORT)
129 parser.add_option('-u', '--user', action='store', type='string', dest='user',
130 default=getpass.getuser(),
131 help='username for SSH authentication (default: %s)' % getpass.getuser())
132 parser.add_option('-K', '--key', action='store', type='string', dest='keyfile',
133 default=None,
134 help='private key file to use for SSH authentication')
135 parser.add_option('', '--no-key', action='store_false', dest='look_for_keys', default=True,
136 help='don\'t look for or use a private key file')
137 parser.add_option('-P', '--password', action='store_true', dest='readpass', default=False,
138 help='read password (for key or password auth) from stdin')
139 parser.add_option('-r', '--remote', action='store', type='string', dest='remote', default=None, metavar='host:port',
140 help='remote host and port to forward to')
141 options, args = parser.parse_args()
142
143 if len(args) != 1:
144 parser.error('Incorrect number of arguments.')
145 if options.remote is None:
146 parser.error('Remote address required (-r).')
147
148 g_verbose = options.verbose
149 server_host, server_port = get_host_port(args[0], SSH_PORT)
150 remote_host, remote_port = get_host_port(options.remote, SSH_PORT)
151 return options, (server_host, server_port), (remote_host, remote_port)
152
153
154 def main():
155 options, server, remote = parse_options()
156
157 password = None
158 if options.readpass:
159 password = getpass.getpass('Enter SSH password: ')
160
161 client = paramiko.SSHClient()
162 client.load_system_host_keys()
163 client.set_missing_host_key_policy(paramiko.WarningPolicy())
164
165 verbose('Connecting to ssh host %s:%d ...' % (server[0], server[1]))
166 try:
167 client.connect(server[0], server[1], username=options.user, key_filename=options.keyfile,
168 look_for_keys=options.look_for_keys, password=password)
169 except Exception as e:
170 print ('*** Failed to connect to %s:%d: %r' % (server[0], server[1], e))
171 sys.exit(1)
172
173 verbose('Now forwarding port %d to %s:%d ...' % (options.port, remote[0], remote[1]))
174
175 try:
176 forward_tunnel(options.port, remote[0], remote[1], client.get_transport())
177 except KeyboardInterrupt:
178 print ('C-c: Port forwarding stopped.')
179 sys.exit(0)
180
181
182 if __name__ == '__main__':
183 main()
1 NO CONTENT: file renamed from IPython/zmq/tunnel.py to IPython/external/ssh/tunnel.py
NO CONTENT: file renamed from IPython/zmq/tunnel.py to IPython/external/ssh/tunnel.py
@@ -23,7 +23,7 b' from zmq.eventloop import ioloop, zmqstream'
23
23
24 from IPython.utils.path import get_ipython_dir
24 from IPython.utils.path import get_ipython_dir
25 from IPython.external.decorator import decorator
25 from IPython.external.decorator import decorator
26 from IPython.zmq import tunnel
26 from IPython.external.ssh import tunnel
27
27
28 import streamsession as ss
28 import streamsession as ss
29 from clusterdir import ClusterDir, ClusterDirError
29 from clusterdir import ClusterDir, ClusterDirError
@@ -152,9 +152,10 b' class Client(object):'
152 Parameters
152 Parameters
153 ----------
153 ----------
154
154
155 addr : bytes; zmq url, e.g. 'tcp://127.0.0.1:10101'
155 url_or_file : bytes; zmq url or path to ipcontroller-client.json
156 The address of the controller's registration socket.
156 Connection information for the Hub's registration. If a json connector
157 [Default: 'tcp://127.0.0.1:10101']
157 file is given, then likely no further configuration is necessary.
158 [Default: None]
158 context : zmq.Context
159 context : zmq.Context
159 Pass an existing zmq.Context instance, otherwise the client will create its own
160 Pass an existing zmq.Context instance, otherwise the client will create its own
160 username : bytes
161 username : bytes
@@ -178,15 +179,18 b' class Client(object):'
178 sshkey : str; path to public ssh key file
179 sshkey : str; path to public ssh key file
179 This specifies a key to be used in ssh login, default None.
180 This specifies a key to be used in ssh login, default None.
180 Regular default ssh keys will be used without specifying this argument.
181 Regular default ssh keys will be used without specifying this argument.
181 password : str;
182 password : str
182 Your ssh password to sshserver. Note that if this is left None,
183 Your ssh password to sshserver. Note that if this is left None,
183 you will be prompted for it if passwordless key based login is unavailable.
184 you will be prompted for it if passwordless key based login is unavailable.
185 paramiko : bool
186 flag for whether to use paramiko instead of shell ssh for tunneling.
187 [default: True on win32, False else]
184
188
185 #------- exec authentication args -------
189 #------- exec authentication args -------
186 # If even localhost is untrusted, you can have some protection against
190 # If even localhost is untrusted, you can have some protection against
187 # unauthorized execution by using a key. Messages are still sent
191 # unauthorized execution by using a key. Messages are still sent
188 # as cleartext, so if someone can snoop your loopback traffic this will
192 # as cleartext, so if someone can snoop your loopback traffic this will
189 # not help anything.
193 # not help against malicious attacks.
190
194
191 exec_key : str
195 exec_key : str
192 an authentication key or file containing a key
196 an authentication key or file containing a key
General Comments 0
You need to be logged in to leave comments. Login now