- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
如何在 php 脚本中使用 rsync 同步本地和远程文件夹而不提示输入密码?
我已经设置了一个公钥来为我的用户自动登录远程服务器。
所以这从 cli 运行没有任何问题:
rsync -r -a -v -e "ssh -l user" --delete ~/local/file 111.111.11.111:~/remote/;
但是,当我尝试从 PHP 脚本(在我本地服务器的网页上)运行相同的脚本时:
$c='rsync -r -a -v -e "ssh -l user" --delete ~/local/file 111.111.11.111:~/remote/';
//exec($c,$data);
passthru($c,$data);
print_r($data);
这是我收到的:
255
并且没有文件从本地上传到远程服务器。
在网上搜索我找到了this clue :
“您可以在这里结合使用 BASh 和 Expect shell 代码,但它不会很安全,因为那样会自动进行 root 登录。为 nobody
或 apache 生成 key
(执行 Apache 的任何用户)。或者,安装 phpSuExec、Suhosin 或 suPHP,以便脚本以调用它们的用户身份运行。”
好吧,我不知道如何为作为“apache”运行的 PHP“自动执行 root 登录”。也许让脚本以实际用户身份运行是个更好的主意,我不知道……谢谢!
更新:- 因为这很好用:
passthru('ssh user@111.111.11.111 | ls',$data);
返回一个home foder列表,可以确定,自动登录没有问题。它可能与从 PHP 脚本运行的 rsync 相关。
更新:
所有问题都与“在命令行上运行时,ssh 使用 $HOME/.ssh/上的 key 文件,但在 PHP 下,它使用 Apache 的用户运行,因此它可能没有 $HOME;很多少一个 $HOME/.ssh/id_dsa。因此,您可以明确告诉它要使用哪个 key 文件,或者手动创建该目录及其内容。”
虽然我无法获得 rsync,但这是我将文件从本地传输到远程的方式:
if($con=ssh2_connect('111.111.11.111',22)) echo 'ok!';
if(ssh2_auth_password($con,'apache','xxxxxx')) echo ' ok!';
if(ssh2_scp_send($con,'localfile','/remotefolder',0755)) echo ' ok!';
本地文件需求:0644远程文件夹需要:0775
我想如果解决方案不是用相同的用户 bash 运行 php...
@Yzmir Ramirez 给出了这个建议:“我不认为你想“将 key 复制到 apache 可以访问它的地方”——这是一种安全违规行为。最好将脚本更改为以安全方式运行用户,然后设置 .ssh key 以在服务器之间进行无密码登录。
这是我必须投入更多时间的事情。如果有人知道如何做到这一点,那将会有很大的帮助。
最佳答案
当我在我们的应用程序中设置同样的东西时,我也遇到了 255 错误,并且发现它们可能意味着各种各样的事情;这不是一个特别有用的错误代码。事实上,即使是现在,在该解决方案顺利运行了一年多之后,我仍然偶尔会在日志中看到 255。
我还要说的是,让它发挥作用可能会有点麻烦,因为其中涉及多个变量。我发现非常有用的一件事是在变量中构造 rsync 命令,然后记录它。这样,我就可以获取正在使用的确切 rsync 命令并尝试手动运行它。您甚至可以 su 到 apache 用户并从与您的脚本相同的目录(或您的脚本设置为 cwd 的任何目录)运行它,这将使它的行为与以编程方式运行时相同;这使得调试 rsync 命令变得更加简单,因为您不必处理 Web 服务器。此外,当您手动运行它时,如果它由于某些未说明的原因而失败,请添加详细标志以增加错误输出。
以下是我们正在使用的代码,为了安全起见稍作编辑。请注意,我们的代码实际上支持本地和远程服务器的 rsync,因为目的地是完全可配置的,可以轻松进行测试安装。
try {
if ('' != $config['publishSsh']['to']['remote']):
//we're syncing with a remote server
$rsyncToRemote = escapeshellarg($config['publishSsh']['to']['remote']) . ':';
$rsyncTo = $rsyncToRemote . escapeshellarg($config['publishThemes']['to']['path']);
$keyFile = $config['publishSsh']['to']['keyfile'];
$rsyncSshCommand = "-e \"ssh -o 'BatchMode yes' -o 'StrictHostKeyChecking no' -q -i '$keyFile' -c arcfour\"";
else:
//we're syncing with the local machine
$rsyncTo = escapeshellarg($config['publishThemes']['to']['path']);
$rsyncSshCommand = '';
endif;
$log->Message("Apache running as user: " . trim(`whoami`), GLCLogger::level_debug);
$deployCommand = "
cd /my/themes/folder/; \
rsync \
--verbose \
--delete \
--recursive \
--exclude '.DS_Store' \
--exclude '.svn/' \
--log-format='Action: %o %n' \
--stats \
$rsyncSshCommand \
./ \
$rsyncTo \
2>&1
"; //deployCommand
$log->Message("Deploying with command: \n" . $deployCommand, GLCLogger::level_debug);
exec($deployCommand, $rsyncOutputLines, $returnValue);
$log->Message("rsync status code: $returnValue", GLCLogger::level_debug);
$log->Message("rsync output: \n" . implode("\n", $rsyncOutputLines), GLCLogger::level_debug);
if (0 != $returnValue):
$log->Message("Encountered error while publishing themes: <<<$returnValue>>>");
throw new Exception('rsync error');
endif;
/* ... process output ... */
} catch (Exception $e) {
/* ... handle errors ... */
}
关于代码需要注意的几件事:
我正在使用 exec() 以便我可以在变量中捕获输出。然后我对其进行解析,以便根据添加、修改和删除的文件数量记录和报告结果。
我正在组合 rsync 的标准输出和标准错误流并返回两者。我也在捕获并检查返回结果代码。
我在 Debug模式下记录所有内容,包括运行 Apache 的用户、rsync 命令本身以及 rsync 命令的输出。这样一来,就像我上面提到的那样,只需快速复制和粘贴,就可以非常容易地以同一用户的身份运行相同的命令。
如果您在使用 rsync 命令时遇到问题,可以在不影响的情况下调整其详细程度并查看日志中的输出。
就我而言,我能够简单地指向一个适当的 key 文件,而不必过分担心安全性。也就是说,关于如何处理这个问题的一些想法:
授予 Apache 访问文件的权限并不意味着它必须位于 Web 目录中;您可以将该文件放在 Apache 用户可以访问的任何位置,甚至可以放在另一台网络计算机上。根据您的其他安全层,这可能是也可能不是可接受的妥协。
根据您正在复制的数据,您可以严格锁定另一台机器上的 ssh 用户的权限,这样,如果有人不择手段地设法进入那里,他们的权限就会降到最低造成伤害的能力。
您可以使用 suEXEC 以 Apache 用户以外的用户身份运行脚本,从而将您的 key 的访问权锁定给其他用户。因此,攻击 Apache 用户的人根本无法访问 key 。
希望对您有所帮助。
关于php - 使用 php 脚本中的 rsync 同步本地和远程文件夹,无需输入密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4775220/
当我使用 --progress 标志运行 rsync 时,我得到有关传输的信息,如下所示。 path/to/file 16 100% 0.01kB/s 0:00:01
为了使用单个 rsync 命令将两个源目录(例如 ~/src1 和 ~/src2)同步到远程系统中的两个独立目标(例如/tgt 和/tgt/sub_tgt),我正在做: rsync ~/src1 ui
从 rsync 手册文档中,我看到通过使用选项 rsync-path,可以指定要在远程计算机上运行的程序以启动 rsync。特别是,该程序可以是一个包装脚本,它在中间调用实际的 rsync 命令,但它
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 6年前关闭。 Improve thi
我在远程主机上有一些文件(在目录中),我想在目录级别以原子方式执行 rsync 以在本地主机上提取文件(在分布式设置中)。我能想到的一种方法是一种非常简单的情况,我可以在本地主机上进行文件备份,然后用
我们有一个 130GB 大小的文件夹,其中包含数百万个微小 (5-20k) 图像文件,我们需要将它从旧服务器 (EC2) 移动到新服务器(德国 Hetzner)。 我们的 SQL 文件 SCP 很快就
我想知道是否有一种方法(命令)可以用来查找 rsync 地址的大小,而无需开始同步? 例如,我如何找到 rsync://mirrors.standaloneinstaller.com/vim/ 的大小
我想同步/Volumes/B/中的所有内容,除了我想全局排除的缓存目录。另外,我不想 rsync 任何其他/Volume/ 我有以下排除文件: + /Volumes/B/*** - Cache/ -
rsync -av --size-only --include="*/" --include="*.jpeg" --exclude="*" ~/alg/temperature/ ~/alg/tmp/
我正在使用 rsync 同步文件夹,如果现有文件已被修改,则对其进行备份。目前所有修改过的文件都备份到一个单独的目录中,以同步时间为后缀。这是使用以下命令: rsync --times --backu
我希望 rsync 排除所有包含具有特定名称的文件的目录,比如“.rsync-exclude”,独立于“.rsync-exclude”文件的内容。 如果文件“.rsync-exclude”只包含“*”
例子: rsync /tmp/fol1/fol2/fol3/foln user@addr:/tmp/fol1/fol2/fol3/foln 我的主要问题是文件夹/tmp/fol1 在远程机器上不存在。
以下命令按预期工作... cp -ur /home/abc/* /mnt/windowsabc/ rsync 相比它有什么优势吗?有没有更好的方法让备份文件夹每 24 小时保持同步? 最佳答案 Rsy
我想从本地计算机到服务器rsync。在不存在的目录上,我希望 rsync 首先在服务器上创建该目录。 我怎样才能做到这一点? 最佳答案 如果要创建的叶目录不止最后一个,您可以先运行单独的 ssh ..
我使用 rsync 来更新我的静态网站。我目前cd到本地网站目录,运行rsync命令,然后在下一行输入密码。我已将我的 rsync 调用保存到一个文本片段中(这样 _rs 就可以扩展到我的调用)。有没
我正在运行如下命令: rsync -vuan "/Volumes/Working/foldername/" "/Volumes/Archive/foldername/" 当文件夹名称包含“/”(如“1
我尝试使用以下命令从服务器进行 rsync,并收到以下错误消息: rsync -e ssh -avz name@home.com:/home/name/. . receiving file list
所以我有这个代码: rsync \ --archive \ --verbose \ --compress \ --delete \ --no-motd \ --ex
我使用 rsync 来更新我的静态网站。我目前cd到本地网站目录,运行rsync命令,然后在下一行输入密码。我已将我的 rsync 调用保存到一个文本片段中(这样 _rs 就可以扩展到我的调用)。有没
我正在运行如下命令: rsync -vuan "/Volumes/Working/foldername/" "/Volumes/Archive/foldername/" 当文件夹名称包含“/”(如“1
我是一名优秀的程序员,十分优秀!