PHPでリモートサーバー上のコマンドをsshで繋いで実行する

こんにちは、さるまりんです。

前回mac上でPHPのssh2を使えるようにしてみました。

今回はそれを使って、リモートサーバー上のコマンドをsshで繋いで実行するPHPプログラムです。

こちらが前提です。

まずは公開鍵と秘密鍵のペアを作り、公開鍵をリモートサーバー上に設置しておきます。

公開鍵はリモートサーバー上、/home/ec2-user/.ssh/authorized_keys

ssh-rsa AAAAB...略...eBw== ec2-user@amazon-linux2.localhost

のようにして設定しています。

ローカルの/Users/salumarine/.ssh/に公開鍵と秘密鍵のペアをとして置いています。

/Users/salumarine/.ssh/id_rsa.amazon-linux2.localhost
/Users/salumarine/.ssh/id_rsa.amazon-linux2.localhost.pub

※ローカルのOSはmacOS Big Sur、ユーザーはsalumarineです。なのでホームは/Users/salumarine/です。

実行するコマンドをリモートサーバー上へ用意します。今回はec2-userユーザーで接続するので、ec2-userhomeディレクトリにhello.shを置いてあります。その内容はこちらです。

/home/ec2-user/hello.sh

#!/bin/sh

echo "hello from amazon linux 2 instance"

こちらがsshで接続して接続先でコマンドを実行し、その結果を表示するPHPプログラムです。

run-some-cmd-via-ssh.php

// 接続先のホスト名です
$host = "amazon-linux2.localhost";
// 接続するユーザー名です
$user = "ec2-user";

// .sshのディレクトリパスです
$dot_ssh_dir = "/Users/salumarine/.ssh/";
// あらかじめ用意された鍵のファイルのパスです
// 公開鍵
$public_key = $dot_ssh_dir . "id_rsa.amazon-linux2.localhost.pub";
// 秘密鍵
$private_key = $dot_ssh_dir . "id_rsa.amazon-linux2.localhost";

// ssh2で接続します
$session = ssh2_connect($host);

// 公開鍵を使って認証します
$is_success = ssh2_auth_pubkey_file($session, $user, $public_key, $private_key);

// 接続に失敗したら
if ($is_success != true) {
    // 「接続失敗です」と表示して
    echo "接続失敗です";
    // プログラムを終了します
    exit;
}

// 接続先のコマンド./hello.shを実行します
$stream = ssh2_exec($session, "./hello.sh");

stream_set_blocking($stream, true);
$stream_out = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO);

// 結果を文字列に読み込みます
$result = stream_get_contents($stream_out);

// いろいろ閉じます
fclose($stream_out);
fclose($stream);
ssh2_disconnect($session);

// 結果を表示します
echo $result;

実行例です。

$ php run-some-cmd-via-ssh.php
hello from amazon linux 2 instance

プログラムのコメントに書いてありますが、簡単にやっているのはこんな流れです。

まず、ssh2_connect()で接続し、ssh2_auth_pubkey_file()で認証します。

続いて、ssh2_exec()でリモートサーバー上でコマンドを実行します。

ssh2_fetch_stream()で標準出力を受けられるようにして、stream_get_contents()でそこから結果を文字列で読み込み、最後に読み込んだ文字列をローカルで出力しています。

認証の時に鍵にパスフレーズが設定されている場合は、ssh2_auth_pubkey_file()にパスフレーズも渡します。

ssh2_auth_pubkey_file($session, $user, $public_key, $private_key, $passphrase);

鍵ではなく、パスワードを使った認証をする場合は、ssh2_auth_password()を使います。

ssh2_auth_password($session, $user, $password);

「リモートのコマンドを実行する」これをやりたい時って結構あると思います。

今回はPHPでsshでした。他にも色々チャレンジしたいと思います。

読んでくださってありがとうございました。

それではまた!