chinda_fall_desu’s diary

竹内豊の日記

ヒューマンコンピューターインターフェースをもっと知りたいなー

pythonとParamikoでsshの通信を行う(sshサーバ作成)

paramikoモジュールを使ってpythonsshサーバを立ててみる。


(1)sshサーバを立てる (適宜分割して示す)

import socket
import threading
import paramiko

host_key = paramiko.RSAKey(filename='test_rsa.key')

簡単のため配布されているデモファイル 'test_rsa.key' を使う。
paramiko/test_rsa.key at master · paramiko/paramiko · GitHub

bind_host="0.0.0.0"
bind_port=50000
pw="password is 12345\n"

今回はpwの文字列を送ることにする。ポート番号50000を開く。

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

    def check_channel_request(self, kind, chanid):
        if kind == 'session':
            return paramiko.OPEN_SUCCEEDED
        return paramiko.OPEN_FAILED_ADMINISTRATIVELY_PROHIBITED
    def check_auth_password(self, username, password):
        if(username=='user') and (password=='pass'):
            return paramiko.AUTH_SUCCESSFUL
        return paramiko.AUTH_FAILED
    # def check_auth_publickey(self, username, key):
    #     if (username=="user") and (key ==(鍵)):
    #         return paramiko.AUTH_SUCCESSFUL
    #     return paramiko.AUTH_FAILED

これでサーバの動作を定義する。
パスワードを使って接続を確立する場合はcheck_auth_password()を使い、鍵を使う場合はcheck_auth_publickey()を使う。

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((bind_host, bind_port))
sock.listen(5)
client, addr = sock.accept()

ソケットを使って通信を確立する。

t = paramiko.Transport(client)
t.add_server_key(host_key)
server = Server()
t.start_server(server=server)

sshトランスポートをソケット通信にアタッチし、セッションを開始し、チャネルを生成する。

chan=t.accept(30)
chan.send("Hello\n".encode('utf-8'))
chan.send(pw.encode('utf-8'))

クライアントによって開かれた次のチャネルを使って文字列を送信する。

t.close()

セッションを終了し、すべてのチャネルを閉じる。


(2)接続を試す

> ssh -p 50000 user@---------
The authenticity of host '[-------]:50000 ([--------]:50000)' can't be established.
RSA key fingerprint is ---------
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[-------]:50000' (RSA) to the list of known hosts.     
user@-------'s password: (パスワードを入力)
Hello
     password is 12345
                      Connection reset by ------- port 50000


下記のデモファイルを参考にした。
paramiko/demos at master · paramiko/paramiko · GitHub



(間違い等あればコメントよろしくお願いいたします。)