Example #1
0
    def _tunnel_to_kernel(self, connection_info, sshserver, sshkey=None):
        """Tunnel connections to a kernel over SSH
        This will open five SSH tunnels from localhost on this machine to the
        ports associated with the kernel.
        See jupyter_client/connect.py for original implementation.
        """
        cf = connection_info

        lports = tunnel.select_random_ports(5)

        rports = cf['shell_port'], cf['iopub_port'], cf['stdin_port'], cf[
            'hb_port'], cf['control_port']

        port_names = "SHELL", "IOPUB", "STDIN", "HB", "CONTROL"

        remote_ip = cf['ip']

        if not tunnel.try_passwordless_ssh(sshserver, sshkey):
            raise RuntimeError(
                "Must use passwordless scheme by setting up the SSH public key on the cluster nodes"
            )

        for lp, rp, pn in zip(lports, rports, port_names):
            self._create_ssh_tunnel(pn, lp, rp, remote_ip, sshserver, sshkey)

        return tuple(lports)
Example #2
0
    def _set_comm_port(self, port):
        """Set comm port."""
        if port is None or port == self.remote_comm_port:
            return
        self.remote_comm_port = port

        client = self.kernel_client

        if hasattr(client, 'ssh_parameters'):
            # Need to tunnel port
            hostname, sshkey, password = client.ssh_parameters
            local_port = zmqtunnel.select_random_ports(1)[0]
            remote_port = port
            remote_ip = client.ip
            self.ssh_tunnel(local_port,
                            remote_port,
                            hostname,
                            remote_ip,
                            sshkey,
                            password,
                            timeout=10)
            port = local_port

        if not (hasattr(client, 'comm_port') and client.comm_port == port):
            client.comm_port = port
            identity = client.session.bsession
            socket = client._create_connected_socket('comm', identity=identity)
            client.comm_channel = client.shell_channel_class(
                socket, client.session, client.ioloop)
            # We emit in case we are waiting on this
            self._sig_comm_port_changed.emit()
Example #3
0
    def _tunnel_to_kernel(self,
                          connection_info,
                          server,
                          port=ssh_port,
                          key=None):
        """Tunnel connections to a kernel over SSH
        This will open five SSH tunnels from localhost on this machine to the
        ports associated with the kernel.
        See jupyter_client/connect.py for original implementation.
        """
        cf = connection_info

        lports = tunnel.select_random_ports(5)

        rports = cf['shell_port'], cf['iopub_port'], cf['stdin_port'], cf[
            'hb_port'], cf['control_port']

        channels = KernelChannel.SHELL, KernelChannel.IOPUB, KernelChannel.STDIN, \
            KernelChannel.HEARTBEAT, KernelChannel.CONTROL

        remote_ip = cf['ip']

        if not tunnel.try_passwordless_ssh(server + ":" + str(port), key):
            raise RuntimeError(
                "Must use password-less scheme by setting up the SSH public key on the cluster nodes"
            )

        for lp, rp, kc in zip(lports, rports, channels):
            self._create_ssh_tunnel(kc, lp, rp, remote_ip, server, port, key)

        return tuple(lports)
Example #4
0
 def _tunnel_to_port(self,
                     port_name,
                     remote_ip,
                     remote_port,
                     sshserver,
                     sshkey=None):
     """Analogous to _tunnel_to_kernel, but deals with a single port.  This will typically called for
     any one-off ports that require tunnelling. Note - this method assumes that passwordless ssh is
     in use and has been previously validated.
     """
     local_port = tunnel.select_random_ports(1)[0]
     self._create_ssh_tunnel(port_name, local_port, remote_port, remote_ip,
                             sshserver, sshkey)
     return local_port
Example #5
0
def tunnel_to_kernel(connection_info, sshserver, sshkey=None):
    """tunnel connections to a kernel via ssh

    This will open four SSH tunnels from localhost on this machine to the
    ports associated with the kernel.  They can be either direct
    localhost-localhost tunnels, or if an intermediate server is necessary,
    the kernel must be listening on a public IP.

    Parameters
    ----------
    connection_info : dict or str (path)
        Either a connection dict, or the path to a JSON connection file
    sshserver : str
        The ssh sever to use to tunnel to the kernel. Can be a full
        `user@server:port` string. ssh config aliases are respected.
    sshkey : str [optional]
        Path to file containing ssh key to use for authentication.
        Only necessary if your ssh config does not already associate
        a keyfile with the host.

    Returns
    -------

    (shell, iopub, stdin, hb) : ints
        The four ports on localhost that have been forwarded to the kernel.
    """
    from zmq.ssh import tunnel
    if isinstance(connection_info, string_types):
        # it's a path, unpack it
        with open(connection_info) as f:
            connection_info = json.loads(f.read())

    cf = connection_info

    lports = tunnel.select_random_ports(4)
    rports = cf['shell_port'], cf['iopub_port'], cf['stdin_port'], cf[
        'hb_port']

    remote_ip = cf['ip']

    if tunnel.try_passwordless_ssh(sshserver, sshkey):
        password = False
    else:
        password = getpass("SSH Password for %s: " % cast_bytes_py2(sshserver))

    for lp, rp in zip(lports, rports):
        tunnel.ssh_tunnel(lp, rp, sshserver, remote_ip, sshkey, password)

    return tuple(lports)
Example #6
0
def tunnel_to_kernel(connection_info, sshserver, sshkey=None):
    """tunnel connections to a kernel via ssh

    This will open four SSH tunnels from localhost on this machine to the
    ports associated with the kernel.  They can be either direct
    localhost-localhost tunnels, or if an intermediate server is necessary,
    the kernel must be listening on a public IP.

    Parameters
    ----------
    connection_info : dict or str (path)
        Either a connection dict, or the path to a JSON connection file
    sshserver : str
        The ssh sever to use to tunnel to the kernel. Can be a full
        `user@server:port` string. ssh config aliases are respected.
    sshkey : str [optional]
        Path to file containing ssh key to use for authentication.
        Only necessary if your ssh config does not already associate
        a keyfile with the host.

    Returns
    -------

    (shell, iopub, stdin, hb) : ints
        The four ports on localhost that have been forwarded to the kernel.
    """
    from zmq.ssh import tunnel
    if isinstance(connection_info, string_types):
        # it's a path, unpack it
        with open(connection_info) as f:
            connection_info = json.loads(f.read())

    cf = connection_info

    lports = tunnel.select_random_ports(4)
    rports = cf['shell_port'], cf['iopub_port'], cf[
        'stdin_port'], cf['hb_port']

    remote_ip = cf['ip']

    if tunnel.try_passwordless_ssh(sshserver, sshkey):
        password = False
    else:
        password = getpass("SSH Password for %s: " % cast_bytes_py2(sshserver))

    for lp, rp in zip(lports, rports):
        tunnel.ssh_tunnel(lp, rp, sshserver, remote_ip, sshkey, password)

    return tuple(lports)
Example #7
0
def test_random_ports():
    for i in range(4096):
        ports = select_random_ports(10)
        assert len(ports) == 10
        for p in ports:
            assert ports.count(p) == 1
Example #8
0
def open_ssh_tunnel(log,
                    config,
                    server,
                    ssh_port=622,
                    timeout=5,
                    ipc_wait_file=5):
    """Try to create ssh tunnels from localhost to server

    Try to create a a) passwordless ssh tunnel from localhost to server or b) munge rsh to server
    and create a passwordless reverse ssh tunnel from server to localhost.
    The transport protocol on localhost and server may differ if needed.
    """

    user = config["user"]

    # server must be visable for now
    try:
        server_info = socket.gethostbyaddr(server)
    except socket.herror:
        raise TunnelError("host %s is inaccessible" % server)
    except socket.gaierror as e:
        raise TunnelError(str(e))

    # make sure the kernel isn't on localhost
    if server_info[0] == "localhost":
        log("kernel on localhost - nothing to do")
        return

    # no gui password prompt
    env = os.environ.copy()
    env.pop("SSH_ASKPASS", None)

    if try_ssh(log, server, ssh_port, env):
        mode = "ssh"
    elif try_mrsh(log, server, ssh_port, env):
        mode = "mrsh"
    else:
        raise TunnelError("Unable to connect, tried ssh and mrsh")

    protocol = config["protocol"]

    # remote (r) ports are the ports for the machine hosting the kernel
    if protocol == "ipc":
        rport = config["uds"]
        lport = "%s-%s" % (rport, localhost)
        config["uds"] = lport
    elif protocol == "tcp":
        rport = config["port"]
        lport = select_random_ports(1)[0]
        config["port"] = lport
    else:
        raise TunnelError("Unsupported protocol %s" % protocol)

    log("attempting to create tunnels from %s@%s to %s@%s" %
        (protocol, localhost, protocol, server))

    ssh_tunnel(log,
               mode,
               ltransport=protocol,
               lport=lport,
               rtransport=protocol,
               rport=rport,
               server=server,
               user=user,
               ssh_port=ssh_port)

    if protocol == "ipc":
        while not os.path.exists(lport) and ipc_wait_file > 0:
            log("waiting for local ipc socket - %d" % ipc_wait_file)
            time.sleep(1)
            ipc_wait_file -= 1
        if not os.path.exists(lport):
            raise TunnelError("local ipc socket doesn't exist: %s" % lport)
    elif protocol == "tcp":
        time.sleep(2)
Example #9
0
def test_random_ports():
    for i in range(4096):
        ports = select_random_ports(10)
        assert len(ports) == 10
        for p in ports:
            assert ports.count(p) == 1