使用 php 脚本中的 rsync 同步本地和远程文件夹,无需输入密码

2024-03-12

如何在 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

并且没有文件从本地上传到远程服务器。

在网上搜索我发现这条线索 http://www.mombu.com/php/php/t-calling-rsync-from-php-script-3752852.html:

“您可以在这里使用 BASh 和 Expect shell 代码的组合,但这不是很安全,因为这会自动执行 root 登录。为以下内容生成密钥nobody or apache(无论以哪个用户身份执行 Apache)。或者,安装 phpSuExec、Suhosin 或 suPHP,以便脚本以调用它们的用户身份运行。”

好吧,我不知道如何为以“apache”运行的 PHP“自动 root 登录”。也许让脚本作为实际用户运行是一个更好的主意,我不知道......谢谢!

更新: - 因为这工作正常:

passthru('ssh [email protected] /cdn-cgi/l/email-protection | ls',$data);

返回主目录列表,我可以确定,自动登录没有问题。它必须是从 PHP 脚本运行 rsync 的东西。

  • 我还在本地和远程文件夹上设置了 chmod -R 0777 以防万一。但我还没明白。

UPDATE:

所有问题都与以下事实有关:“在命令行上运行时,ssh 使用 $HOME/.ssh/ 上的密钥文件,但在 PHP 下,它是使用 Apache 的用户运行的,因此它可能没有 $HOME;更不用说 $ HOME/.ssh/id_dsa。因此,要么您专门告诉它要使用哪个密钥文件,要么手动创建该目录及其内容。”

虽然我无法获得 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 给出了这个建议:“我不认为你想“将密钥复制到 apache 可以访问的地方”——这是一种安全违规。最好将脚本更改为以安全用户身份运行,然后设置 .ssh 密钥以在服务器之间进行无密码登录。

这是我必须投入更多时间的事情。如果有人知道如何做到这一点,拜托,这会有很大的帮助。


当我在我们的应用程序中设置同样的东西时,我也遇到了 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 的标准输出和标准错误流并返回两者。我还捕获并检查返回结果代码。

  • 我在调试模式下记录所有内容,包括运行 Apache 的用户、rsync 命令本身以及 rsync 命令的输出。这样,就像我上面提到的那样,只需快速复制和粘贴即可以同一用户身份运行相同的命令,这非常容易。

  • 如果您在使用 rsync 命令时遇到问题,可以在不受影响的情况下调整其详细程度并查看日志中的输出。

就我而言,我能够简单地指向适当的密钥文件,而不必过度担心安全性。也就是说,关于如何处理这个问题的一些想法:

  • 授予 Apache 访问该文件的权限并不意味着该文件必须位于 Web 目录中;而是意味着该文件必须位于 Web 目录中。您可以将该文件放在 Apache 用户可以访问的任何位置,甚至可以放在另一台网络计算机上。根据您的其他安全层,这可能是也可能不是可接受的妥协。

  • 根据您要复制的数据,您也许能够严格锁定另一台计算机上 ssh 用户的权限,这样,如果有人不道德地设法进入那里,他们造成损害的能力就会降到最低。

  • 您可以使用 suEXEC 以 Apache 用户以外的用户身份运行脚本,从而允许您将对密钥的访问锁定到其他用户。因此,损害 Apache 用户的人根本无法访问密钥。

我希望这有帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 php 脚本中的 rsync 同步本地和远程文件夹,无需输入密码 的相关文章

  • Doctrine2:入门教程“没有要处理的元数据类”

    我已经将本教程的第一部分运行了三遍 到目前为止 在这里或其他地方进行的大量搜索都无法帮助我使其发挥作用 我收到 没有要处理的元数据类 当我尝试时 php vendor bin doctrine orm schema tool update
  • 简单的颜色变化

    我正在创建一个用户界面 用户可以在其中更改页面的颜色值 我想要的是获取分配给其背景颜色的值并将其变亮一定程度 我只是想获得一条亮点线 而不必每次都制作新图像 示例 用户将背景颜色设置为 ECECEC 现在我希望某个元素边框变成 F4F4F4
  • 合并 csv 文件 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何在 PHP 或 joomla 中将多个 CSV 文件合并为一个 csv 文件 将文件夹中 csv 文件中的所有数据合并到文本文件中 通
  • 如何通过 PDO 使用密码哈希来使我的代码更安全? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我的代码实际上可以工作 但它一点也不安全 我不想使用 MD5 因为它不是那么安全 我一直在查找密码哈希 但我不确定如何将其合并到我的代
  • PHP 和 DOM 文档

    我有一个关于 DOMDocument 的使用和创建 XML 的问题 我有一个 PHP 程序 加载到 XML 文件中 处理XML的每个节点 行 将其发送到另一个进程 然后该进程返回一个 XML 元素 我获取节点的字符串表示形式 以便可以创建
  • Php mysql 30秒后执行任务

    如何让 mysql 查询命令在访问 php 站点 30 秒后执行 您可以对执行 mysql 查询的 php 脚本发出 AJAX 请求 在 js 中使用计时器
  • php 或 zend 中国际电话号码验证的正则表达式是什么?

    我有一个 zend 表单 其中有一个电话号码字段 并且必须检查验证器 我决定为此使用正则表达式 我搜索了谷歌 但我得到的结果不起作用 谁能给我提供正则表达式 这是我的代码 phone new Zend Form Element Text p
  • 从 json 数组获取值并执行 sql 插入

    这是我的数组 json 1 Device ID a9a3346be4375a92 Date 2012 05 31 Time 15 22 59 Latitude 51 4972912 Longitude 0 1108178 2 Device
  • 如何使用 PHP 动态插入 CSS 类?

    下面的代码有什么问题 我想在相应的情况下动态插入 当前 CSS 类 li 单击元素 谢谢 section section li
  • json_encode 创建格式错误的 JSON 数据?

    我有一个 codeigniter 应用程序将一些数据从数据库返回到视图 我正在尝试将其作为 json 数据发送回来 问题是返回的数据格式错误 它看起来像这样 2 5 Admin1 2 10 Admin2 当我在 jsonlint com 上
  • HTTP_REFERER 返回 NULL,$_SERVER 中不存在密钥

    使用以来第一次 SERVER HTTP REFERER 它给了我NULL因此 当我做var dump SERVER the HTTP REFERER密钥不存在 我还尝试使用不同的浏览器和不同的网站访问网站 但没有结果 该网站在基于 Linu
  • Laravel 5.6 - 注册表无法正常工作并且不显示任何错误

    在我最近的一个项目中 定制登记表不管用 当我单击注册按钮时 它会重新加载注册表单 不会打印任何错误 并且不会将数据插入数据库中 这是注册表的外观 这里是移民文件代码 public function up Schema create user
  • PHP,文本从数据库中回显,没有换行,全部一体

    我的数据库中有一个长文本 从 php mayadmin 来看它看起来很好 但是当我将它回显到页面时 它会丢失所有格式 即没有新行 全部都在一个块中 有任何想法吗 Thanks 可能是因为换行符是 n 并且 html 想要 br 所以使用nl
  • 计算轮班工作时间并检测

    我有个问题 我的英语很差 我需要用PHP做一个加班计算 已经有一个代码可以实现这一点 但当工作时间超过2天时 计算就会出错 工作开始 2018 09 09 13 43 工作结束 2018 09 11 07 13 结果 07 18 04 00
  • 从文本文件 PHP 读取数据

    我只是想知道如何在 php 中读取文本文件 我想让它显示文本文件中的最后 200 个条目 每个条目都在一个新行上 Like John White Jane Does John Does Someones Name 等等 Thanks Use
  • 使用 Flot、html、PHP 和 MySql 查询绘制多个图表

    我正在尝试使用 Flot html PHP 和 MySql 查询绘制多个图表 但我陷入了困境 因为我找不到在同一个 html 页面中绘制多个 flot 的方法 为简单起见 在数据库 test db3 映像中包含以下字段 表1 用户名 发送邮
  • 将价格格式设置为逗号分隔

    在我的数据库中 我有类似的值 256 23 200 33 89 33 133 45 我必须将这些值乘以千 然后将结果格式化为价格 逗号分隔 256 23 x 1000 256230 I want to show this as 256 23
  • 打印表数据mysql php

    我在尝试打印表格的一些数据时遇到问题 我是 php mysql 的新手 但我认为我的代码是正确的 这里是 h1 Lista de usu rios h1
  • 通过 SOAP 的 Gmt php 或 UTC C# 等效项

    is C DateTime UtcNow和 PHPdate c 是等价的 我怀疑 因为当我肥皂时 我得到了 C
  • 使用 PHP 创建图表并导出为 PDF

    我正在寻找有关使用 PHP 创建图表的建议 我还希望能够将这些图表导出到 PDF 文档 我目前正在使用谷歌图表 但我不喜欢将我的所有信息发送到谷歌的想法 我更喜欢自己的托管解决方案 我见过很多 Flash 解决方案 但我不知道有什么方法可以

随机推荐

  • 如何转换上传的视频并从此文件获取屏幕截图?

    我正在构建一个CMS 我希望用户能够上传视频 但我不熟悉视频上传和转换 有没有例子或者有人编写了这样的解决方案 我听说过 ffmpeg 但我不知道如何将它与 asp net 集成 作为简单的解决方案 我可以让我的客户上传 flv 文件 但我
  • 如何向 graphql 中的输入参数添加默认值

    我有这种输入类型 我想向其中一个字段添加默认值 我想将 0 添加到 ExampleInput 内的值字段 type ExampleType value Int another String type Mutation example inp
  • 在dispatch_async中正确引用self

    如何在快速关闭中正确引用 self dispatch async dispatch get main queue self popViewControllerAnimated true 我收到错误 Cannot convert the ex
  • django-admin 中的模型描述

    django admin中是否可以在某个模型的列表显示页面上放置模型描述或描述 我说的是当你点击 django admin 主页上的模型名称链接并进入该模型的列表显示页面时 表格顶部将写有说明 就像是 该模型用于记录将通过我们的抓取获取的所
  • SVG 容器在 Safari 桌面中呈现错误的大小(在 Chrome/iOS 中正常)

    我以为 Safari 已经解决了这个问题 但它似乎仍然是一个问题 除非我做了一些明显错误的事情 我在对象标签内放置了一个 SVG 它被包裹在一个灵活的包含 DIV 中 例如设置为宽度 50 在调整大小时 容器高度在 Firefox Chro
  • JPMS支持模块版本吗?

    我以为JPMS不支持模块版本 然而 当我这样做时java list modules我有以下输出 java activation 9 java base 9 java compiler 9 java corba 9 java datatran
  • 使用 jenkins 执行 wsl.exe 返回 exit -1073740791

    我在一台具有 WSL 适用于 Linux 的 Windows 子系统 的 Windows 10 计算机上设置了 jenkins 例如 当我从终端运行简单命令 C Windows System32 wsl exe help 时 它工作正常 使
  • 删除 Shapely 多边形外部的 numpy 网格点

    我有一个 10 x 10 网格 我想删除形状多边形之外的点 import numpy as np from shapely geometry import Polygon Point from descartes import Polygo
  • 如何为 powershell 函数的描述属性添加值?

    我想填充我在 PROFILE 中创建的 Powershell 函数的 Description 属性 我想向 描述 属性添加一个值 例如 在个人配置文件中创建 这可能吗 目前 如果我检查我的功能描述 我发现没有填充任何内容 例如 Get Co
  • 应该匹配 RSpec 期望语法

    正确的使用格式是什么应该匹配器 https github com thoughtbot shoulda matchers和 RSpec 的新期望语法 http myronmars to n dev blog 2012 06 rspecs n
  • 使用 Firebase android 时如何向用户添加用户名?

    我目前开始在我的 Android 应用程序中使用 Firebase 并使用其 GitHub 上的示例来创建登录和注册活动 https github com firebase quickstart android https github c
  • 在 onDragStop 事件中获取 Material UI Slider 值

    我想触发一个事件onDragStop而不是onChange使用材质 UISlider在我的 React 应用程序中 以便事件触发次数更少 但是 那文档 https mui com material ui react slider表明onDr
  • 尝试使用 ItemsControl.AlternationIndex 显示列表中的行索引

    我有以下 XAML 旨在将行号放在左列中 但所有输出都是0
  • 根据父 ID 值将数组从一维转换为多维

    我有一个代表多维数据的一维对象数组 array array id gt 45 parent id gt null array id gt 200 parent id gt 45 array id gt 345 parent id gt 45
  • 密码强度检查库[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 任何人都可以推荐一个 Java 库 其中包含适合在 Web 应用程序中执行服务器端密码强度检查的方法 理想情况下 检查器应该是 可配置 允
  • 如何在Python中子类化str

    我正在尝试对 str 对象进行子类化 并向其添加几个方法 我的主要目的是学习如何去做 我陷入困境的是 我是否应该在元类中对 string 进行子类化 并使用该元创建我的类 或者直接对 str 进行子类化 而且 我想我需要实施 new 不知何
  • 使用 NHibernate 和动态匿名对象在 GroupBy 查询中进行选择

    我的主要目标是创建一个动态组并在 NHibernate 中使用它 考虑这个非动态的例子works repository Collection
  • 使 React 组件作为 Widget 可用

    我有一个复杂的 React 应用程序 包括渲染某些组件的身份验证等 并且有一个特定的组件 一个日期选择器 我希望其他用户将其作为 Google 地图的小部件嵌入到他们的网站上 我已经成功地将其作为 iFrame 进行共享 但我想了解如何将其
  • 使用贪婪正则表达式忽略可选后缀

    我正在 NET 中对如下所示的字符串执行正则表达式匹配 1 Lists General Discussion Waffles Win 2 Lists General Discussion Waffles Win 2 000 3 Lists
  • 使用 php 脚本中的 rsync 同步本地和远程文件夹,无需输入密码

    如何在 php 脚本中使用 rsync 同步本地和远程文件夹而不提示输入密码 我已经设置了一个公钥来自动为我的用户登录远程服务器 所以从 cli 上运行没有任何问题 rsync r a v e ssh l user delete local