Перенаправление порта сервера Paramiko с опцией openssh client -N

Я пытаюсь создать сервер Paramiko, который просто перенаправляет порты. Я адаптировал код из кода демонстрационного сервера

#!/usr/bin/env python
import base64
from binascii import hexlify
import os
import socket
import sys
import threading
import traceback
import paramiko
from paramiko.py3compat import b, u, decodebytes
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

host_key = paramiko.RSAKey(filename="test_rsa.key")
logger.info("Read key: " + u(hexlify(host_key.get_fingerprint())))


class Server(paramiko.ServerInterface):
    def __init__(self):
        self.event = threading.Event()

    def check_auth_publickey(self, username, key):
        logger.info("Auth attempt with key: " + u(hexlify(key.get_fingerprint())))
        try:
            with open("client_rsa.pub.stripped", "rb") as f:
                good_key = f.read()
            good_pub_key = paramiko.RSAKey(data=decodebytes(good_key))
        except:
            logger.exception("failed to read public key")
            return paramiko.AUTH_FAILED
        if (username == "robey") and (key == good_pub_key):
            return paramiko.AUTH_SUCCESSFUL
        return paramiko.AUTH_FAILED

    def get_allowed_auths(self, username):
        return "publickey"

    def check_channel_request(self, kind, chanid):
        logger.info("inside channel request")
        return paramiko.OPEN_SUCCEEDED

    def check_channel_direct_tcpip_request(self, chanid, origin, destination):
        return paramiko.OPEN_SUCCEEDED

    def check_channel_shell_request(self, channel):
        self.event.set()
        return True

if __name__ == "__main__":
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.bind(("", 2200))
    sock.listen(100)
    logger.info("Listening for connection ...")
    client, addr = sock.accept()
    logger.info("Got a connection!")

    with paramiko.Transport(client) as t:
        t.load_server_moduli()
        t.add_server_key(host_key)
        server = Server()
        t.start_server(server=server)

        # wait for auth
        chan = t.accept(20)
        if chan is None:
            logger.info("*** No channel.")
            sys.exit(1)
        logger.info("Authenticated!")

        # prompt for more information
        chan.send("Username: ")
        f = chan.makefile("rU")
        username = f.readline().strip("\r\n")
        logger.info("received username: " + username)
        chan.close()

И я использую эту команду для успешного подключения:

ssh -i client_rsa.key -p 2200 -L 9999:localhost:4000 -T robey@localhost

Однако, когда я пытаюсь использовать параметр -N для клиента ssh, то есть:

ssh -i client_rsa.key -p 2200 -L 9999:localhost:4000 -T -N robey@localhost

сервер Paramiko зависает после аутентификации клиента, так и не достигнув функции check_channel_request. Вот логи с пробега:

INFO:__main__:Read key: 689f8799e649f931b116b19227dbb2a3
INFO:__main__:Listening for connection ...
INFO:__main__:Got a connection!
INFO:paramiko.transport:Connected (version 2.0, client OpenSSH_7.2p2)
INFO:paramiko.transport:Auth rejected (none).
INFO:__main__:Auth attempt with key: cdbb2439816b22a59ee036be3a953e51
INFO:paramiko.transport:Auth rejected (publickey).
INFO:__main__:Auth attempt with key: 11c470c88233719a2499f03336589618
INFO:paramiko.transport:Auth granted (publickey).

Есть ли способ заставить сервер Paramiko справиться с этой ситуацией?


person buck    schedule 05.10.2017    source источник


Ответы (1)


Разобрался в этом. Причина, по которой ничего не происходит, заключается в том, что туннельное перенаправление не открывается, пока вы не попытаетесь его использовать. Оказывается, мой туннель не создавался даже без опции -N. Итак, ответ - убедитесь, что вы используете локальный порт после создания SSH-соединения.

person buck    schedule 07.10.2017