我有一个中央系统(web应用程序),它应该一个接一个地连接到一组节点(客户端),以从通过mysql视图公开的数据库中获取记录集。
我正在为这个场景寻找尽可能好的实现方式。目前,我的脑海中有这样的流动。
1.第一种方法
伪代码
$dataFetched=array();
$clients= getListOfClients();
//
foreach($clients as $client){
// client={details:{id,name,etc....},
// ssh:{pem:'client.pem',localMysqlPort:3307 ,remoteMyqlPort:3306,
// sshUser:'demo@clientHost.com'},
// mysql:{user:'tunnelUser',password:'password'}
// }
//connect ssh connection
$ssh_connection=new Ssh_connect($client->ssh)
if($ssh_connection->status){
$dataFetched[$client->id]=array("status"=>'OK','data'=>fetchMysqlData($client->mysql))
}else{
$dataFetched[$client->id]=array("status"=>'NO_OK','data'=>array())
}
$ssh_connection->destroyTunnel();
unset($ssh_connection);
}
此方法的一些关注点/问题
有没有ssh lib/扩展可以为我提供这种功能?
为每个客户端存储"pem"文件的最佳安全方式是什么?
另一种方法?
2.第二种方法
编写bash脚本来实现上面的伪代码
设置cron作业以更新数据库
Web应用程序不了解外部客户端。它将使用更新的表通过cron作业来呈现数据。
某些点:
数据大小很轻
消费者和提供者都是网络应用程序
除了SSH之外,应用程序互不了解
添加新的客户端节点应该是灵活的(我不知道在第二种方法中我将如何做到这一点)
从安全角度来看,反向隧道和正向隧道
非常感谢您的建议
有一个用于PHP的SSH库。它被称为ssh2,它在PECL上可用。
它依赖于libssh2,但在基于Linux的机器上启动和运行应该不会太难。
存储pem文件的最佳方式是在您的web目录之外,权限有限,仅足以让您的web应用程序读取文件。或者,您可以设置ssh代理守护进程作为web应用程序运行。
(我希望你的PHP应用程序不会都在同一个用户下运行。对于Apache,有一个鲜为人知的mod_ruid2模块,它允许你更改用户并记录PHP web应用程序,而无需设置fastcgi或suExec)。
遗憾的是,ssh2_ttunnel只创建了一个新的PHP资源,它不是可以用来创建新的mysql连接的东西(好吧,至少不使用mysqli_connect&friends)。
您可以在本地服务器上执行SQL命令,将数据库密码存储在~/.my.cnf 中
~/.my.cnf:
[client]
password = lolcats1234
然后用PHP&ssh2连接后可以运行以下代码:
stream_set_blocking($stream, true);
$stream = ssh2_exec($connection, 'mysql -u db -p db -e "select * from table"');
$first = true;
while($line = fgets($stream)) {
if ($first) {
$first = false;
continue;
}
// process one line of results...
echo $line."<br />";
}
或者,如果您只使用反向隧道,您可以使用本地脚本mysql_connect,而不需要担心做任何SSH工作。