0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

paramikoを使ってPythonでSSH接続を行う

0
Posted at

Pythonのparamikoライブラリを使用して、リモートサーバーへSSH接続を行う方法について学びました。

その際に学習した内容について、自分用にアウトプットを行いたいと思います。

概要

今回は、「Pythonのparamikoライブラリを使ってSSH接続を行い、dirコマンドを実行して接続を切る」というシンプルな実装を通して、paramikoライブラリの使い方を学んだ形となっています。

また、以下のような前提のもとで行われています。

前提

  • 接続先のリモートサーバーは、Docker Composeで立ち上げたコンテナ(イメージはこちらを使用)である
  • 公開鍵認証でDE25519鍵を生成しており、それを使用して接続を行う
  • 秘密鍵ファイルはpathlibの相対パスで読み込み
  • ポート番号やSSHユーザーネームは.envファイルから読み込み(セキュリティの観点から)

ソースコード

connection_util.py
import paramiko
from pathlib import Path
import os
from dotenv import load_dotenv

def main():
    # 秘密鍵ファイルパス
    ROOT_DIR = Path(__file__).resolve().parent.parent
    key_path = Path(ROOT_DIR, "***", "***")
    
    # .envファイルの読み込み
    load_dotenv()
    # SSHユーザーネームとポート番号
    ssh_port = int(os.getenv("SSH_PORT", 22))
    ssh_user = os.getenv("SSH_USER")

    # 鍵を読み込む
    key = paramiko.Ed25519Key.from_private_key_file(key_path)
    
    # 接続の実行
    client = create_ssh_client("localhost", ssh_port, ssh_user, key)
    
    # コマンドの実行
    result = execute_command(client)
    
    print(result)
    
    # 終わったら閉じる
    client.close()

# SSHClientを使った接続
def create_ssh_client(hostname, port, username, key):
    client = paramiko.SSHClient()
    # 初回接続時にホストキーを自動追加する設定
    # 学習用に、自動的に信頼する`AutoAddPolicy`を使う
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
    # 接続実行
    client.connect(
        hostname=hostname,
        port=port,
        username=username,
        pkey=key
    )
    
    return client

def execute_command(client):
    # コマンドを実行
    # stdin:標準入力、stdout:標準出力、stderr:標準エラー出力
    stdin, stdout, stderr = client.exec_command("dir")
    
    # stdoutから中身を読み取って文字列にする
    result = stdout.read().decode('utf-8')
    return result

if __name__=="__main__":
    main()

ポイント

おさえておきたいポイントはいくつかあります。

接続に必要な秘密鍵の読み込み

connection_util.py
key = paramiko.Ed25519Key.from_private_key_file(key_path)

こちらの関数に、秘密鍵が書いてあるファイルのパスを渡すことによってparamikoに秘密鍵を読み込ませています。

接続の実行

connection_util.py
client = paramiko.SSHClient()
# 初回接続時にホストキーを自動追加する設定
# 学習用に、自動的に信頼する`AutoAddPolicy`を使う
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    
# 接続実行
client.connect(
        hostname=hostname,
        port=port,
        username=username,
        pkey=key
    )

paramiko.SSHClientインスタンスを作成し、connectでSSH接続が行われています。

なお、今回は学習用として、「初めて接続するサーバの情報を、確認なしで自動的に信頼して保存する」仕様であるAutoAddPolicyset_missing_host_key_policyメソッドに渡しています。

しかし、この運用は本番環境ではセキュリティの観点からは非推奨です。この辺りは別途本番用の仕様について学習する必要があるでしょう。

コマンドの実行

SSH接続したリモートサーバーでのコマンドの実行は、client.exec_commandメソッドによって行われました。

connection_util.py
# stdin:標準入力、stdout:標準出力、stderr:標準エラー出力
stdin, stdout, stderr = client.exec_command("dir")
    
# stdoutから中身を読み取って文字列にする
result = stdout.read().decode('utf-8')

このメソッドの出力であるstdinstdoutstderrは、それぞれ

  • stdin: 標準入力
  • stdout: 標準出力
  • stderr: 標準エラー
    を表しています。

今回は、result = stdout.read().decode('utf-8')として、標準出力をデコードして人間が読める形にして、result変数に代入しました。

接続を閉じる

connection_util.py
client.close()

接続を行った後は、必ずこのコードを実行することで閉じる処理を入れるべきでしょう。

その他

今回は、dirという単純なコマンドを実行するだけでしたが、もちろん、実践の場面ではもっと複雑な命令を与えることになるでしょう。

その場合は、linuxやMacのコマンドを記すことができる.shファイルに、命令文をまとめて書いておいて、それをparamikoに渡して実行することもできるようです。

まとめ

paramikoを使って、SSH接続を実現することができました。

この機能を、開発中のAPIに導入できるようにしていきたいです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?