因此我有以下设置:
- 服务器 A(网络服务器)
- 服务器 B(Xen Dom0 - 带有逻辑卷)
- 服务器C(备份服务器)
我想自动且安全地在各个B
服务器之间创建备份。我可以在服务器上创建一个 PHP 文件,该文件在访问时会创建备份。但是,这需要在服务器上运行 PHP。C
B
现在我也可以使用ssh2_connect
PHP,我可以用它在服务器上仅运行 PHPB
并执行命令,但这些命令需要 root 访问权限。因此,任何入侵网络服务器或以其他方式访问文件的人都会立即获得 root 访问权限。
我的 Web 服务器上有一个数据库,里面有要执行的“命令”。例如备份 VM 服务器 1,然后恢复 VM 服务器 8 等。这就是我需要从服务器A
向服务器发送“命令”的原因B
。我的问题是,安全地执行此操作的最佳解决方案是什么?我显然不希望除了我之外的任何人访问服务器B
。
答案1
而不是拥有服务器 A远程运行命令服务器 B,为什么不服务器 B只需询问服务器 A运行哪些命令?
安排一个 cron 作业,类似这样的事情:
10 01 * * * /usr/local/bin/do_backups
看起来do_backups
像这样:
#!/usr/bin/env php
<?php
$conn = pg_connect('host=servera dbname=backup');
pg_prepare($conn, 'get_commands', 'SELECT command FROM backup_commands');
$result = pg_execute($conn, 'get_commands', array());
$commands = pg_fetch_result($result);
foreach($commands as $cmd) {
system(escapeshellcmd($cmd));
}
?>
显然,这是一种伪代码,因为我不知道你的数据库是什么样子的,所以如果你不清楚它在做什么,请告诉我。只要记住,如果你的命令需要的参数可能不受信任,就将其转义。另外,我已经有一段时间没有用 PHP 编写代码了,所以我的代码中可能存在错误 ;)
答案2
您要做的是在服务器 B 上创建一个 cron 作业,定期为您进行备份。如果您已php_cli
在服务器上安装,这甚至可以是一个 PHP 脚本(如果您对此非常了解)。
以你喜欢的任何形式创建备份脚本,然后以 root 身份将其添加到 crontab 中crontab -e
。例如:
0 1 * * * /root/mybackupscript.sh
mybackupscript.sh
将在每天晚上 01:00 点运行 root 主文件夹中的脚本。
欲了解更多信息,请参阅man cron
和man crontab
。
根据您的编辑,还有一些其他建议:
- 让您的备份脚本轮询 Web 服务器以获取作业信息。它仍可以以 root 身份运行。Web 服务器上的简单脚本可以为此轮询生成作业命令。
- 使用 SSH 连接到服务器 B 并以此方式运行作业。很难以安全的方式非交互地运行。
- 允许服务器 B 上的用户(可能是 Web 服务器的用户)无需密码即可使用 sudo 执行您的备份脚本。确保只有 root 可以修改此脚本,并且不会被恶意参数欺骗。
答案3
WRT Devator 的答案,你可以使用phpseclib,一个纯 PHP SSH 实现,以交互方式执行 SSH。以下是来自 phpseclib 文档的有关 sudo 的示例,它通常会提供输入密码的交互式提示:
<?php
include('Net/SSH2.php');
$sftp = new Net_SSH2('www.domain.tld');
$sftp->login('username', 'password');
echo $sftp->read('username@username:~$');
$sftp->write("sudo ls -la\n");
$output = $sftp->read('#Password:|username@username:~\$#', NET_SSH2_READ_REGEX);
echo $output;
if (preg_match('#Password:#', $lines)) {
$ssh->write("password\n");
echo $sftp->read('username@username:~$');
}
?>
您还可以使用 $ssh->setTimeout(xx) 来适应即使使用正则表达式匹配也不会返回您所查找内容的命令。