3

Mac OS X 10.6のコマンドラインからPHPを使用して、リモートサーバーへのインタラクティブなSSH接続を確立しようとしています。現在、PHPのproc_open関数を使用して次のコマンドを実行しています。

ssh -t -t -p 22 user@server.com

これはほとんど機能します。-t -tオプションは、ほとんどの場合、疑似端末を強制することになっています。SSHパスワードを入力して、Enterキーを押すことができます。ただし、Enterキーを押した後、端末は単にハングしているように見えます。出力も何もありません-SSHセッションが失敗したかのようです。コマンドなどを実行できず、Ctrl+Cを使用してすべてを強制終了する必要があります。ssh -t -t -p 22 user@server.com "ls -la"のようなコマンドを実行して正しい出力を取得できるため、ログインが成功したことはわかっています。

この問題は、proc_open呼び出しで標準パイプを使用していたことに関連していると考えたため、それらをptyに置き換えました。次のエラーが発生します:「このシステムではpty疑似端末がサポートされていません...」

Mac OS Xは単にptyまたは疑似端末をサポートしていませんか?(私はこのすべてのシェル用語を使用するのはかなり新しいです)。

PHPコードは次のとおりです。

$descriptorspec = array(0 => array("pty"), 1 => array("pty"), 2 => array("pty"));  
$cwd = getcwd();  
$process = proc_open('ssh -t -t -p 22 user@server.com', $descriptorspec, $pipes, $cwd);  
if (is_resource($process))  
{  
    while (true)  
    {  
        echo(stream_get_contents($pipes[1]));  
        $status = proc_get_status($process);  
        if (! $status["running"])  
            break;  
    }  
} 

(申し訳ありませんが、SOのフォーマット手順を理解することはできません...)

私は何が間違っているのですか?なぜptyを使用できないのですか?これはMacOSXでは不可能ですか?ご協力いただきありがとうございます!

4

6 に答える 6

5

プログラムで対話型パスワード認証をバイパスするのではなく、公開鍵認証を使用する必要があります。

パスワードプロンプトはttyから使用されることになっていますが、それ以外の方法で意図的に使用することは困難になっていると思います。また、-t -t引数は、リモートホストに接続した場合にのみ有効になります。proc_open()そして、PHP関数が仮想端末内でコマンドを実行できるとは思いません。

公開鍵認証を設定するには:

# Generate keypair
ssh-keygen -t rsa

# Copy public key to server
scp ~/.ssh/id_rsa.pub example.com:.ssh/authorized_keys

# Now you shouldn't be prompted for a password when connecting to example.com
# from this host and user account.
ssh example.com

# Since the web server (and thus PHP) probably has its own user account...
# Copy the ~/.ssh/id_rsa file somewhere else
cp ~/.ssh/id_rsa /some_path/id_rsa

# Change ownership of the file to the web server account
chown www-data:www-data /some_path/id_rsa

# Fix the file permissions (ssh ignore the keyfile if it is world readable)
chown 600 /some_path/id_rsa

# Try connecting to the server through the web server account
su -c "ssh -i /some_path/id_rsa -o UserKnownHostsFile=/some_path/known_hosts example.com" www-data

# Add the host to the known hosts file when prompted


plinkまたは、コマンドラインでパスワードを取得できるため、OpenSSHの代わりに(PuTTY for Linuxの一部)を 使用することもできますplink -pw password example.com。ただし、サーバー上で実行するすべてのユーザーがプロセスリストでパスワードを確認できるため、これを行うとセキュリティリスクが発生します。ps aux

sshpass環境変数またはコマンド引数からパスワードを取得してに渡すプログラムもありますssh

于 2010-11-05T08:07:38.467 に答える
4

この問題は、PHPのpassthru()関数を使用して解決するのが最適なようです。さらに多くの(かなり苦痛な)調査の後、この関数を介してコマンドを発行し、sshとsvn exportを手動で実行したかのようにターミナルを介してリモートサーバーと対話できました(どちらもパスワードが必要なため、良いテストでした) 。私がしなければならないことは、コマンドの(潜在的に非常に長い)文字列を区切り&&、sshコマンドの最後に添付することです。ssh -t -t -p 22 hostname command1 && command2 ... コマンドがリモートサーバーで実行されている場合でも、出力はMacOSXの端末に送信されます。これは私がずっと探していた解決策のように見えます-本当に簡単です!これを手伝ってくれたすべての人に感謝します。アレクサンドルに「緑色のチェックマーク」を付けたのは、彼だけが応答を続け、問題の最終的な答えを推測するのに非常に役立ったからです。アレクサンドルありがとう!

于 2010-11-06T23:10:25.777 に答える
3

これは古いですが、そこにいるすべてのgooglerにとって、proc_openを使用した実際の解決策は次のとおりです。

Pty記述子はPHPで使用できますが、コンパイル時に構成する必要があります(この10年前のバグレポートhttps://bugs.php.net/bug.php?id=33147を参照)

しかし、Pythonではその問題はありません。したがって、sshコマンドを直接実行する代わりに、次のPythonスクリプトを実行します。

import sys
import pty

args = " ".join(sys.argv[1:])
pty.spawn(['/usr/bin/ssh', args])

Pythonドキュメントのpty.spawnについて:

プロセスを生成し、その制御端末を現在のプロセスの標準ioに接続します。これは、制御端末からの読み取りを要求するプログラムを妨害するためによく使用されます。

于 2015-08-06T07:23:34.153 に答える
1

PHP SSH2拡張機能を試しましたか?

于 2010-11-05T09:26:05.713 に答える
1

純粋なPHPSSH実装であるphpseclibを試しましたか?:

<?php
include('Net/SSH2.php');

$ssh = new Net_SSH2('www.domain.tld');
if (!$ssh->login('username', 'password')) {
    exit('Login Failed');
}

echo $ssh->read('username@username:~$');
$ssh->write("ls -la\n");
echo $ssh->read('username@username:~$');
?>
于 2012-10-18T19:13:55.903 に答える
0

phpでssh2拡張子の付いたsshクライアントを作成しました。githubページhttps://github.com/roke22/PHP-SSH2-Web-Clientでソースコードを確認できます。

フィードバックを送ってください。

于 2018-07-20T19:49:45.280 に答える