我正在创建一个应用程序来将我的本地 mysql 数据库同步到远程 mysql 数据库,所以我正在生成一个转储文件,通过 sFTP 发送它,然后在服务器上执行它。
但是,我知道还有其他可用的方法,例如 cURL。我喜欢将数据发送到远程服务器并在服务器上执行它,当它被接受时(TRUE),但我对在这方面使用 cURL 相关的安全问题知之甚少。任何人都可以就 cURL 解决方案提出建议,否则建议任何替代方法?
首先,您应该使用 等从文件中读取数据,而不是生成转储file_get_contents()
文件fread()
。
将此结果存储在一个变量中,然后通过管道发送原始数据(如果您愿意,可以通过 cURL),并让服务器端的代码生成转储文件。
使用 cURL,您可以指定一个私有证书文件进行身份验证 - 因此其安全性与使用 ssh 证书相同 - 这不是您需要担心的事情。
您可以使用以下 cURL 选项示例设置 pem 文件:
curl_setopt($ch, CURLOPT_SSLCERT, $pemfile);
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLKEY, $keyfile);
网上都有以上教程。使用私钥身份验证,您的安全问题得到排序。只要确保你没有设置CURLOPT_SSL_VERIFYPEER
(false
你现在不想要任何 MiTM(中间人)攻击,是吗)。
我使用 Curl 来执行此操作。
我有一个生成 json 或 xml 的导出脚本(取决于我的心情最重要)然后我将此文件发布到远程服务器和远程服务器使用ignore_user_abort
,以便即使父内部系统脚本也可以继续处理超时/完成任何事情。
就像在本地 Web 服务器和远程 Web 服务器之间同步更改到 2.6gb 表的魅力一样。
我使用 phpseclib,一个纯 PHP SFTP 实现,来做这样的事情。例如。
<?php
include('Net/SFTP.php');
$sftp = new Net_SFTP('www.domain.tld');
if (!$sftp->login('username', 'password')) {
exit('Login Failed');
}
$sftp->put('filename.remote', 'filename.local', NET_SFTP_LOCAL_FILE);
?>
与 libssh2 相比,它具有许多优势,包括速度和可移植性:
这是使用 ssh2 / libssh 的基本解决方案。
这段代码假定您已经有了创建数据库转储的方法,并且只是在当前服务器上读取它,目的是在远程服务器上加载它。
它通过 SSH 连接到远程主机,将您的 sql_dump 写入远程服务器上的文件,然后执行命令将其加载到数据库中。
我不建议存储用于连接的用户名/密码,这只是测试代码的一种快速方法。您最好使用 ssh2_auth_pubkey_file 进行身份验证: http ://php.net/manual/en/function.ssh2-auth-pubkey-file.php
// remote host authentication details. hostname/ip, user, pass
$host = 'REMOTE_HOST';
$user = 'REMOTE_USER';
$pass = 'REMOTE_PASS';
// check if we have ssh2 installed first
if (function_exists("ssh2_connect")) {
//connect to remote host
$connection = ssh2_connect($host, 22);
// if connection successful, proceed
if ($connection) {
// authenticate on remote connection
$auth = ssh2_auth_password($connection, $user, $pass);
// if we have authenticated, proceed with remote commands
if ($auth) {
// load our dump file to a string
$sql_str = file_get_contents('dump_file.sql');
// bash command to cat our dump string to a file
$write_remote_file_command = "cat <<'EOF' > /home/tmp_file.sql \n$sql_str \nEOF";
// call our execute ssh function to execute above command
executeSSHCommand($connection, $write_remote_file_command);
// command to load our temp dump file into the database
// - you may need to add additional commands to drop the existing db, etc
$remote_load_command = "mysql -Uroot -p -h localhost database_name < /home/tmp_file.sql";
// remotely execute load commands
executeSSHCommand($connection, $remote_load_command);
}
}
}
// basic function to execute remote shell commands via our authenticated $connection
function executeSSHCommand($connection, $command) {
$output = array();
$ssh_data = "";
$stream = ssh2_exec($connection, $command);
if ($stream) {
stream_set_blocking($stream, true);
while ($buffer = fread($stream, 65536)) {
$ssh_data .= $buffer;
}
fclose($stream);
$output = explode(PHP_EOL, $ssh_data);
}
return $output;
}