Restic: MacOS Mojave:错误:打开:...不允许操作

创建于 2018-10-17  ·  56评论  ·  资料来源: restic/restic

MacOS Mojave 的隐私功能似乎限制了对文件的静态访问(至少似乎正在发生的事情),我得到了升级之前没有得到的权限错误。

macOS 10.14

使用 sudo 运行:

can not obtain extended attribute com.apple.rootless for /Library/Application Support/com.apple.TCC
error: Open: open /Library/Application Support/com.apple.TCC: operation not permitted
error: open /Library/Preferences/com.apple.TimeMachine.plist: operation not permitted

...许多其他文件。

restic version的输出

0.9.2(最新的自制软件)

你是怎么跑restic的?

在升级到 Mojave 之前,我已经使用了几个月的相同 bash 脚本,以 root 权限运行。

RESTIC_PASSWORD_FILE="/path/to/file.txt" \
HOME="/path/to/homedir" \
/usr/local/bin/restic \
    --repo sftp:myserver.local:my/repo/path \
    --option='sftp.command=ssh -p REDACTEDPORT -i REDACTEDKEYFILE -o identitiesonly=yes -l restic myserver.local -s sftp' \
    --exclude-file="${DIR}/global-exclude.txt" \
    --exclude-if-present='.norestic' \
    backup \
    --cleanup-cache \
    / \
    &>> /path/to/file.log

您使用什么后端/服务器/服务来存储存储库?

sftp,如上所述。 与以前相同的回购。

预期行为

希望在以 root 身份运行时读取并备份所有文件(意识到这可能不是一个静态问题,但似乎它肯定是备份的问题)。

实际行为

如上

重现行为的步骤

sudo bash restic-backup.sh (上面的脚本)

您知道是什么原因造成的吗?

我猜:

你知道如何解决这个问题吗?

不,到目前为止我已经尝试过:

  • MacOS 上没有 libcap,所以不能使用setcap
  • 尝试在新的“系统偏好设置”->“安全和隐私”窗格中将 restic 添加到“全盘访问”,但没有成功。

restic 有没有以任何方式帮助你或让你快乐?

经过多年努力寻找一个好的、可靠的、可编写脚本的、开源的备份解决方案,它是唯一符合要求的解决方案。 非常感谢!

backup documentation wanted darwin discussion

最有用的评论

我最近开始使用 Restic 并一直试图让它作为一个从根 crontab sudo crontab -e调用的 cron 作业来工作,这样我可以感觉更安全一点,将我的备份脚本放在一个只能通过 sudo 权限访问的文件中. 我遇到了与@n8henrie完全相同的错误,但现在我有一个可行的解决方案,并且想知道这是否适用于这里的其他人。

首先是我的设置的一些背景:

我在/Users/myuser/bin中有一个名为restic-backup.sh的备份脚本,其权限700 (仅限 root/sudo 读/写/执行)。 我用我的根 crontab sudo crontab -e执行这个文件。 我使用 iTerm 作为我的默认终端。 我已经用 Homebrew 安装resticzsh

macOS 版本 10.14.5

restic-backup.sh:

我的备份脚本文件中包含以下内容。

#!/usr/local/bin/zsh
restic_path="/usr/local/bin"
logFile="/Users/myuser/Documents/Backups/configurations/Mac/backup_logs/$(date +%F_%H%M)_restic.log"
unset HISTFILE
export RESTIC_REPOSITORY="..."
export AWS_ACCESS_KEY_I'd="..."
export AWS_SECRET_ACCESS_KEY="..."
export RESTIC_PASSWORD="..."
$restic_path/restic --verbose backup /Users/myuser  &> $logFile

然后在我的根 crontab 文件中: sudo crontab -e我有:

0 */2 * * * /Users/myuser/bin/restic-backup.sh

在全盘访问中:

cron ==> /usr/sbin/cron
iTerm.app ==> /Applications/iTerm.app

@n8henrie一样,我认为实际访问像restic这样的文件的程序将是需要 FDA 的程序,但似乎发出初始sudo请求的程序需要 FDA: cron自动情况下为 $ iTerm.app

所有56条评论

是的,显然你必须做全盘访问的事情: https ://www.backblaze.com/blog/mojave-permissions/

你确定你添加了正确的静态二进制文件吗? 在系统偏好设置中将文件添加到全盘访问后,您是否移动了文件或更改了其任何属性(所有权等)?

(我有一台 Mac,但我还没有 Mojave,抱歉。)

我使用自制软件,所以首先我将/usr/local/bin/restic添加到全盘访问,开始工作,注意到相同的错误,所以我删除了它并添加了实际二进制文件的路径(注意这很遗憾必须是每次restic更新时重做): /usr/local/Cellar/restic/0.9.2/bin/restic ,不幸的是我看到了同样的错误。

没有更改,将二进制文件添加到全盘访问,切换回终端并运行sudo myscript.sh ,这对大多数文件都有效,但在其他文件上出现权限错误。

旁注,我正在尝试解决另一个(可能与 Mojave 相关的)问题,我的 sftp pubkey 身份验证在从 launchctl(以 root 身份)运行时停止工作,但在以 root 身份手动运行时工作,但我会如果我能够确定它不是特定于我的设置,请提交一个新问题。

有趣的。 如果你直接运行restic会发生什么? 和/或将您的脚本添加到 FDA。 老实说,只是在黑暗中拍摄。 如果我有 Mojave,我会尝试一下。

好主意。

我的脚本本身是不可执行的(实际上没有充分的理由),如前所述,我使用sudo bash myscript.sh (实际上是/usr/local/bin/bash )运行它; 它无法添加到 FDA,因为它不可执行。

我尝试将/usr/local/bin/bash添加到 FDA 并且没有骰子。

编辑:我显然错了,即使在chmod +x之后,我的backup.sh仍然不能直接添加到 FDA(而bashrestic二进制文件能够)。 奇怪的。

EDIT2:为了彻底起见,我将bashrestic二进制文件都添加到了 FDA,我看到了同样的错误。

可能是比 restic 更大的问题——我什至尝试将/bin/ls添加到 FDA 列表中,但仍然出现错误。

$ sudo /bin/ls /Users/me/Library/Suggestions
ls: Suggestions: Operation not permitted

编辑:丑陋的解决方法:将Terminal.app添加到 FDA 权限,权限错误就会消失。

相关线程: https ://forums.developer.apple.com/thread/107546

尝试codesign将 restic 二进制文件和我的backup.sh脚本添加到 FDA 中,但没有运气。

(在阅读了一些帖子之后)我的天哪。 这太烦人了。 感谢您调查它! 升级后我也会继续调查...

哇,非常感谢您提供的信息以及您在这个问题上花费的所有时间! 我根本没有mac,所以如果你们俩都能弄清楚,我很高兴我们可以为其他用户记录这个问题! 再次感谢你!

@mholt如果您愿意,您可以安装 VMware Fusion 的 30 天试用版并在其中安装 Mojave(除非 Apple 削弱了临时安装它的能力)。 该试用版不会造成任何污染,如果您以后不想要它,可以将其卸载。

在上面提到将Terminal.app添加到System Preferences -> Security & Privacy -> Full Disk Access列表是一种解决方法,因为当我手动运行我的脚本时( sudo /usr/local/bin/bash mybackup.sh ) 它似乎在没有权限错误的情况下工作。

出于某种原因,当我今天早上从自动夜间静态运行中检查我的日志时(基于 $ /Library/LaunchDaemons/com.n8henrie.restic.plistlaunchd脚本,它每晚以 root 权限运行),权限错误仍然存​​在。

不幸的是,我现在无法让解决方法起作用——即使在 FDA 中使用Terminal.app ,当我运行sudo launchctl start com.n8henrie.resticsudo /usr/local/bin/bash mybackup.sh时,我仍然会遇到权限错误。

所以解决方法似乎不起作用,或者发生了一些变化。

编辑:Gah,刚刚将所有 3 个添加到 FDA - Terminal.app/usr/local/bin/bash/usr/local/Cellar/restic/0.9.2/bin/restic - 现在它运行没有错误。 🤷‍♂️

FWIW,这是我的日志输出,其中包含出现错误的文件列表。 正如你所看到的,有一些大问题,比如我的照片库。

@n8henrie从您之前链接到的 Mac 支持线程,似乎 FDA 要求批准的应用程序是 Applications 文件夹中的注册 .app 包,这可能是 Terminal.app 成功的原因......但您必须添加所有 3在你的情况下到 FDA ? 有趣的...

@mholt似乎正在发生其他事情。 我完全按照昨天的设置(在 FDA 中的所有 3 个,都没有产生权限错误),我的夜间运行仍然得到相同的旧权限错误。

这种情况现在已经发生了两次,经过一段时间的修补后,我运行时没有权限错误,然后再次出现。 restic 是否知道文件是否已更改而无需打开文件——某种缓存? 我想知道我是否被紧密在一起的运行所愚弄,并且文件没有临时更改,因此restic不会尝试打开它?

否则我很难解释这里发生了什么。

好问题。 我知道 restic 使用缓存,但我还没有研究在权限错误等情况下它对它的坚持程度。

SO的相关讨论: https ://apple.stackexchange.com/q/338213/27415

好问题。 我知道 restic 使用缓存,但我还没有研究在权限错误等情况下它对它的坚持程度。

一点也不。 缓存仅包含来自 repo 的文件,不包含有关文件系统(不在 repo 中)的信息。

好的 - 是的,我认为这不是 restic 中的错误。 这绝对是一个 macOS Mojave 问题,在这一点上,我很确定 restic 本身无法解决任何问题。

太棒了,感谢您的反馈,我现在关闭这个问题。 如果您发现问题,请添加更多评论。 谢谢!

看到这个问题已经结束,我有点惊讶——这似乎是一个
与主要平台严重不兼容,并在此时关闭它
可能会说它“眼不见,心不烦”。

我知道这主要不是一个静止的问题,但似乎
MacOS 用户可以采取一些合理的步骤。 照原样,
用户备份他们最重要的个人信息的能力
默认情况下,数据(例如照片)在当前版本的
苹果系统。 对于任何备份软件来说,这对我来说似乎很重要!

一些建议/可能性(我很乐意帮助工作):

  • 解决问题的可能性

    • 是否可以提供适当的 MacOS 包装应用程序

      可以添加到 FDA 列表中,其中包含 restic 二进制文件

    • 如果能够弄清楚如何执行上述操作,而不是提供

      应用程序,我们是否可以包含有关用户如何完成它的说明

      自己使用某种 Makefile 或 XCode?

  • 解决方法

    • 在文档中提供有关最安全/最小二进制文件的信息

      需要添加到 FDA

    • 提供有关禁用 SIP(​​及其风险)的信息的链接

  • 警告

    • 在文档中包含 Mojave 用户不会拥有的信息

      他们的数据默认完全备份

总体而言,这种情况似乎与没有 root 的完整备份没有太大的不同
在 Linux 上,完全禁用 SIP 就像运行
root,并确定并推荐一个合理安全的妥协方案
FDA 就像使用setcap一样。

不幸的是,我的 Macbook 这周在商店里,所以我不能
立即处理其中任何一项,但我很想听听想法
来自他人; 也许我离基地很远,或者可能对细节一无所知
用于管理问题的 restic 团队工作流程。

现在我的机器回来了,还有一些更新:

我无法复制上面从我的启动脚本获取完整系统备份的成功。

我尝试将以下所有内容添加到 FDA 列表中(同时),但仍然出现错误:

  • 休息的
  • 重击
  • 启动控制
  • 发射
  • 终端应用程序

只是为了实验,裸二进制文件在添加到 FDA 列表时似乎工作正常,并且似乎与代码设计无关。 比较 MacOS 和 Homebrew 提供的ls二进制文件:

$ codesign -d /bin/ls
Executable=/bin/ls
$ codesign -d /usr/local/opt/coreutils/libexec/gnubin/ls
/usr/local/opt/coreutils/libexec/gnubin/ls: code object is not signed at all

在和添加到 FDA 列表之前:

$ /bin/ls ~/Library/Mail
ls: Mail: Operation not permitted
$ /usr/local/opt/coreutils/libexec/gnubin/ls ~/Library/Mail
ls: cannot open directory '/Users/n8henrie/Library/Mail': Operation not permitted
$ # Added to FDA
$ /bin/ls ~/Library/Mail
PersistenceInfo.plist V6
$ /usr/local/opt/coreutils/libexec/gnubin/ls ~/Library/Mail
PersistenceInfo.plist  V6

此外,只要ls在 FDA 中,它们在放入 bash 脚本时工作正常(无需单独添加bash ),这让我认为我应该只需要添加restic

此外,为了比较,如果不在 FDA 中运行以下 Go 脚本错误,但只要二进制文件在 FDA 中,它本身以及从 launchd 调用时都可以正常工作(无需添加 launchd / launchctl / 其他任何内容)。

package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    matches, err := ioutil.ReadDir("/Users/n8henrie/Library/Mail")
    if err != nil {
        fmt.Println("Err:", err)
    } else {
        for _, match := range matches {
            fmt.Println(match.Name())
        }
    }
}

输出:

$ ./gotest
Err: open /Users/n8henrie/Library/Mail: operation not permitted
$ # Add to FDA
$ ./gotest
.DS_Store
PersistenceInfo.plist
V6

接下来,我将对 Restic 进行一些试验,看看我是否可以弄清楚为什么即使添加到 FDA 也会出现权限错误(尽管其他二进制文件一旦添加似乎就可以工作)。

好的,谢谢反馈! 我将重新打开这个问题,也许我们可以弄清楚发生了什么,然后在手册中添加一些文档。

~在新的回购中仍然出现Open错误, restic已添加到 FDA 列表中。~

请参阅下面的编辑。

$ restic -r /tmp/restic backup ~/Library/Mail -vvv
open repository
enter password for repository:
repository 9ccb5357 opened successfully, password is correct
created new cache in /Users/me/Library/Caches/restic
lock repository
load index files
start scan on [/Users/me/Library/Mail]
start backup on [/Users/me/Library/Mail]
scan: Open: open /Users/me/Library/Mail: operation not permitted
scan finished in 1.849s: 0 files, 0 B
can not obtain extended attribute com.apple.quarantine for /Users/me/Library/Mail:
error: Open: open /Users/me/Library/Mail: operation not permitted
new       /Users/me/Library/, saved in 0.012s (0 B added, 13 B metadata)
new       /Users/me/, saved in 0.012s (0 B added, 381 B metadata)
new       /Users/, saved in 0.013s (0 B added, 379 B metadata)

Files:           0 new,     0 changed,     0 unmodified
Dirs:            3 new,     0 changed,     0 unmodified
Data Blobs:      0 new
Tree Blobs:      4 new
Added to the repo: 1.119 KiB

processed 0 files, 0 B in 0:01
snapshot 4a658c73 saved
$ restic -r /tmp/restic ls latest
enter password for repository:
repository 9ccb5357 opened successfully, password is correct
snapshot 4a658c73 of [/Users/me/Library/Mail] filtered by [] at 2018-11-04 11:30:05.334024 -0700 MST):
/Users
/Users/me
/Users/me/Library

screenshot 2018-11-04 at 11 32 18 am

编辑:忽略这条评论——我仍然受到间歇性错误的困扰,这些错误会混淆任何进展,可能与昨天更新到 MacOS 10.14.1 有关。 今天,昨天的相同 Go 代码一直与 FDA 一起工作,但没有它就失败了(我多次打开和关闭它以确保)即使在 FDA 也不再工作。 与ls相同。

如果将Terminal.app添加到 FDA(作为唯一条目),它确实有效,这在昨天是不必要的。

🤷‍♂️

如果我能在 Apple 论坛上找到任何关于此的内容,我会进行报告。

EDIT2:妻子的 Macbook 仍在 10.14 上,并且/bin/ls ~/Library/Mail不适用于添加到 FDA 的/bin/ls ,所以看起来它在 10.14.1 中可能不是新东西。 😕

仍在为此努力。

它仍然非常痛苦,但我终于有了一个我认为可以满足我的目的的解决方法。

我已经详细说明了这里的过程,但底线是:

您可以使用Script Editor.app将 AppleScript 制作成应用程序包。 AppleScript 可以运行你的 restic 备份脚本(在我的例子中/path/to/restic-backup.sh ,其中restic-backup.sh是一个 bash 脚本,它使用我想要的设置运行 restic),你可以将生成的应用程序包添加到 FDA为了访问受保护的文件。

但是,这使得在系统级别上自动运行备份变得困难。 内置的open命令有效,但在您的用户下运行应用程序 - 因此,当备份上述受 FDA 保护的文件时,您将在任何只有 root 可读的文件(例如 root -拥有0600东西)。

此时我的解决方法是让 AppleScript 使用sudo调用备份脚本,并授予我的用户权限以在没有密码的情况下以 root 权限运行该脚本( sudo visudoNOPASSWD: , 等等。)。

它不漂亮,但它似乎正在工作。

我想留下这个开放的意见来自具有更多专业知识的 MacOS 用户的任何建议。 如果没有更令人满意的结果,我可以将此信息添加到文档中(尽管这个解决方案老实说似乎不太令人满意)。

令人难以置信的是,这似乎有效,而且清洁、更简单。

// Runrestic provides a binary to run my restic backup script in MacOS Mojave with Full Disk Access
package main

import (
    "log"
    "os"
    "os/exec"
    "path/filepath"
)

func main() {
    ex, err := os.Executable()
    if err != nil {
        log.Fatal(err)
    }
    dir := filepath.Dir(ex)
    script := filepath.Join(dir, "restic-backup.sh")
    cmd := exec.Command("/usr/local/bin/bash", script)
    if err := cmd.Run(); err != nil {
        log.Fatal(err)
    }
}

生成的二进制文件可以是chown rootchmod 0700 ,然后添加到全盘访问,它似乎可以工作。 然后可以将其添加到/Library/LaunchDaemons plist 以自动运行。

到目前为止,前 2 次运行正在运行,我希望这不会像上面的几个错误开始那样结束。

我昨晚的自动运行成功了。 我今天将这个策略部署到我妻子的 Macbook Air 上,如果它看起来也可以在那里工作,我会认为这是一个合理的修复,并在https://github.com/restic/restic 上做一个小 PR。净(如果这看起来合理的话)。

@n8henrie ,我在遇到这个确切的问题然后找到你的博客文章后来到这里。 感谢您进行所有这些研究。

上述解决方案(从简单的 Go 二进制文件调用 shell 脚本)对我不起作用。 您确定它已成功访问您的所有文件吗?

我特别注意到 stdout/stderr 被丢弃到 /dev/null。 例如,如果 restic 想要提示输入密码,它也无法读取标准输入。 (也有点好笑,为什么你的 bash 是/usr/local/bin/bash而不是/bin/bash ?只是好奇。)

无论如何,我进行了以下更改以查看错误输出:

    cmd := exec.Command("/bin/bash", script)
    cmd.Stdin = os.Stdin
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr

在看到您的博客文章之前,我的第一反应是将 restic 二进制文件本身添加到 FDA,这对我在 10.14.1 (18B75) 下不起作用。 我不确定为什么插入另一个程序(调用 shell 脚本的 Go 包装器,最终调用 restic)会改变任何东西。

这仍然对您有用吗?

@n8henrie感谢您及时通知我们! 如果你愿意的话,你也可以在 restic 博客上写一篇关于它的博客文章(除了手册中的一小部分)...... :)

@fd0我很荣幸!

@armhold是的,看起来就像一个魅力,见下文。 在我妻子的 MBA 课程中,我认为我需要在它开始工作之前重新启动(虽然不是我的)。 为她的 IIRC,我创建了二进制文件,然后重新启动,然后添加到 FDA,它工作了。

修复前:

Thu Nov 15 02:00:00 MST 2018 :: Starting restic-backup.sh
can not obtain extended attribute com.apple.rootless for /Library/Application Support/com.apple.TCC:
error: Open: open /Library/Application Support/com.apple.TCC: operation not permitted
error: open /Library/Preferences/com.apple.TimeMachine.plist: operation not permitted
error: Open: open /Users/me/Library/Application Support/AddressBook: operation not permitted
error: Open: open /Users/me/Library/Application Support/CallHistoryDB: operation not permitted
error: Open: open /Users/me/Library/Application Support/CallHistoryTransactions: operation not permitted
error: Open: open /Users/me/Library/Application Support/MobileSync: operation not permitted
error: Open: open /Users/me/Library/Application Support/com.apple.TCC: operation not permitted
error: Open: open /Users/me/Library/Calendars: operation not permitted
error: Open: open /Users/me/Library/Containers/com.apple.Home: operation not permitted
error: Open: open /Users/me/Library/Containers/com.apple.Safari: operation not permitted
error: Open: open /Users/me/Library/Containers/com.apple.VoiceMemos: operation not permitted
error: Open: open /Users/me/Library/Containers/com.apple.iChat: operation not permitted
error: Open: open /Users/me/Library/Containers/com.apple.mail: operation not permitted
error: Open: open /Users/me/Library/Containers/com.apple.news: operation not permitted
error: Open: open /Users/me/Library/Containers/com.apple.stocks: operation not permitted
can not obtain extended attribute com.apple.quarantine for /Users/me/Library/Cookies:
error: Open: open /Users/me/Library/Cookies: operation not permitted
error: Open: open /Users/me/Library/HomeKit: operation not permitted
error: Open: open /Users/me/Library/IdentityServices: operation not permitted
can not obtain extended attribute com.apple.quarantine for /Users/me/Library/Mail:
error: Open: open /Users/me/Library/Mail: operation not permitted
error: Open: open /Users/me/Library/Messages: operation not permitted
error: Open: open /Users/me/Library/Metadata/CoreSpotlight: operation not permitted
error: Open: open /Users/me/Library/Metadata/com.apple.IntelligentSuggestions: operation not permitted
can not obtain extended attribute com.apple.metadata:com_apple_backup_excludeItem for /Users/me/Library/PersonalizationPortrait:
error: Open: open /Users/me/Library/PersonalizationPortrait: operation not permitted
error: open /Users/me/Library/Preferences/com.apple.AddressBook.plist: operation not permitted
error: open /Users/me/Library/Preferences/com.apple.AddressBook.plist.KaSTvBv: operation not permitted
error: open /Users/me/Library/Preferences/com.apple.AddressBook.plist.M410OmB: operation not permitted
error: open /Users/me/Library/Preferences/com.apple.AddressBook.plist.Sjhd5Xh: operation not permitted
error: open /Users/me/Library/Preferences/com.apple.AddressBook.plist.ceAM0im: operation not permitted
error: open /Users/me/Library/Preferences/com.apple.homed.notbackedup.plist: operation not permitted
error: open /Users/me/Library/Preferences/com.apple.homed.plist: operation not permitted
error: open /Users/me/Library/Preferences/com.apple.mail-shared.plist: operation not permitted
error: Open: open /Users/me/Library/Safari: operation not permitted
can not obtain extended attribute com.apple.metadata:com_apple_backup_excludeItem for /Users/me/Library/Suggestions:
error: Open: open /Users/me/Library/Suggestions: operation not permitted
can not obtain extended attribute com.apple.FinderInfo for /Users/me/Pictures/Photos Library.photoslibrary:
can not obtain extended attribute com.apple.quarantine for /Users/me/Pictures/Photos Library.photoslibrary:
error: Open: open /Users/me/Pictures/Photos Library.photoslibrary: operation not permitted

Files:         179 new,   261 changed, 857338 unmodified
Dirs:            0 new,     0 changed,     0 unmodified
Added to the repo: 266.392 MiB

processed 857778 files, 186.192 GiB in 12:57
snapshot 46831f24 saved
Thu Nov 15 02:12:58 MST 2018 :: restic-backup.sh finished.
Duration: 778 seconds

修复后:

Tue Nov 27 02:00:00 MST 2018 :: Starting restic-backup.sh

Files:         389 new,  2367 changed, 1055845 unmodified
Dirs:            0 new,     0 changed,     0 unmodified
Added to the repo: 430.279 MiB

processed 1058601 files, 295.471 GiB in 18:16
snapshot e58d8f1c saved
Tue Nov 27 02:18:17 MST 2018 :: restic-backup.sh finished.
Duration: 1097 seconds

同样的修复也在我妻子的 Macbook Air 上工作,两者都在遥控器上使用restic find '/Users/*/Library/Mail' --snapshot latest --host=$(hostname)进行了验证(其中~/Library/Mail是通常受保护的目录之一,如上面的错误日志中所示) .

我特别注意到 stdout/stderr 被丢弃到 /dev/null。 例如,如果 restic 想要提示输入密码,它也无法读取标准输入。

这将完全取决于您的脚本。 正如您在我的原始帖子中看到的那样,由于我的设置是完全自动化的,它被设置为从(root 拥有的 0600)文件中读取密码,但也可以从 envvar 或任何常用方法中读取。 你是对的,我认为这不适用于交互式的东西。 它还将所有内容记录到一个文件中: &>> /path/to/file.log

(也有点好笑,为什么你的 bash 是 /usr/local/bin/bash 而不是 /bin/bash?只是好奇。)

我使用Homebrew来获取更新版本的 bash

$ /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin18)
Copyright (C) 2007 Free Software Foundation, Inc.
$ /usr/local/bin/bash --version
GNU bash, version 4.4.23(1)-release (x86_64-apple-darwin17.5.0)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

这为我提供了更多现代功能,例如&>file.log运算符(与2>&1 >file.log相比,它节省了一些击键。

在看到您的博客文章之前,我的第一反应是将 restic 二进制文件本身添加到 FDA,这对我在 10.14.1 (18B75) 下不起作用。 我不确定为什么插入另一个程序(调用 shell 脚本的 Go 包装器,最终调用 restic)会改变任何东西。

我也不完全确定这一点。 对于我的用例,我在我的 bash 脚本中进行了很多其他设置(有点复杂的 sftp 命令,其中目标、备份路径和几个选项都基于主机名)所以调用 restic 二进制文件本身不是一个选项。 我可以尝试一下。

好的,谢谢解释。 我刚刚尝试重建、重新启动 + 添加 FDA,但我仍然得到operation not permitted 。 还尝试将二进制包装器和 shell 脚本都移动到 /Applications 中,但没有运气。 我会继续挖掘。

嗯。 对我来说绝对不需要在 /Applications 中。

你在 10.14 还是 10.14.1 上? 我是后者。

您可以尝试使用我引用的 tccutil 命令预先清除所有条目。

我在 10.14.1 (18B75)。 我也尝试了 tccutil 命令,没有运气。 我理解苹果为什么要这样做,但是对于在这里做什么没有明确的路径确实令人沮丧。

嗯。 这很奇怪。

奇怪的是,我试过了,但我无法让 restic 二进制文件直接工作。

不清楚为什么这不起作用,但我的解决方法是(对我来说)。

似乎是另一个间歇性错误——我认为我们应该推迟
正式文件/书面记录,直到我们能够得到别人的
使用同一系统的计算机。 我是 2 对 2,但我不明白为什么
这不适用于@armhold。

@armhold ,你能发布一份确切的 bash 脚本和你的 Go 代码吗?
使用以及如何运行它? 我会看看我是否可以在我的最后重现。

奇怪的是,我试过了,但我无法让 restic 二进制文件直接工作。

是的,这就是我不明白的。 我不明白为什么 Go 包装器会在 restic 二进制文件本身失败的情况下成功。 似乎有些不对劲。

你能发布一份你正在使用的确切的 bash 脚本和 Go 代码的副本以及你是如何运行它的吗?

当然,这里是: https://github.com/armhold/restic-fda。

  • shell 脚本和 go 包装器都安装在我的~/bin目录中。
  • 通过系统偏好将~/bin/restic-fda添加到 FDA
  • 我在终端的命令行上以交互方式从非 root 用户帐户运行restic-fda 。 我收到如下错误: error: Open: open /Users/armhold/Library/Application Support/AddressBook: operation not permitted
  • 以 root 身份运行(通过 sudo)同样失败

我没有尝试通过launchctl运行它。

防火墙 Little Snitch 做了类似的事情——对于传出连接,它会询问是否允许“通过 restic 的终端”进行连接(而不仅仅是 restic); 即 Terminal.app 是授予权限的主要应用程序。

我最终所做的是使用Platypus将我的 shell 脚本捆绑为一个应用程序,并将 FDA 授予该生成的应用程序。 然后通过 Finder 启动备份。 工作至今。

launchctl 将是下一步。

仅供参考,这仍然对我有用(包括在最近的 MacOS 之后
更新)。 @armhold 有什么消息吗?

仍然对我不起作用。 我放弃了,只是给了终端 FDA。

不幸的是,我又被难住了。

我在 10.14.2。 我的静态备份脚本仍在工作,其日志中没有权限错误。 但是,我现在无法让@armhold的脚本甚至我之前的测试脚本工作(除了打开受保护的目录~/Library/Mail之外什么都不做)。

🤷‍♂️

您是否尝试过在新的存储库上运行您的(工作)包装器? 我的意思是,你确定它没有跳过旧文件,因此已经存在于 repo 中吗? 我想你仍然会在尝试进入受保护的文件夹时遇到错误,因为 restic 会遍历树。

@mholt这个和 relica 的状态是什么 - 你有没有以某种方式解决它,如果是的话,你能与我们分享你采取了哪些步骤吗?

在升级了几个客户端之后,我也看到了这种行为,非常烦人并且很难在不包装东西和搞乱的情况下处理。

@rawtaz

这个和遗物的状态是什么——你有没有以某种方式解决它,如果有,你能和我们分享你采取了哪些步骤吗?

我自己上周才升级到 Mojave。 但是我安装了 Relica 并且在尝试备份 ~/Library/Mail 时能够重现“不允许操作”错误。

然后我将Relica.app添加到 FDA 屏幕并重新运行 Relica 备份。

screen shot 2018-12-27 at 1 54 49 pm

这次备份成功,没有错误(而Relica+restic做的第一个快照,因为权限错误,根本没有显示Mail文件夹):

screen shot 2018-12-27 at 1 51 31 pm

所以恐怕我没有任何答案可以为这个线程做出贡献。 :-/ 我不确定它是否会_keep_工作,但我当然希望它会。

我也决定将我的 restic 备份脚本包装在一个 .app 包中,以便能够给它 FDA。 不得不这样做很糟糕,但这似乎是唯一可行的前进方式。

起初我尝试只提供 restic 二进制 FDA,但这并没有使它起作用。
我还尝试将我的备份脚本(一个调用 restic 的 Bash 脚本)提供给 FDA,但这也不起作用。
我没有尝试@armhold的包装器。

我按照上面的建议使用了鸭嘴兽,效果很好。 它会生成一个 .app 包,然后我可以在 macOS 的系统设置中将其提供给 FDA,这就解决了这个问题。

我在使用过程中注意到的唯一缺点是,当 .app 启动时(对我来说,它是由 crontab 使用open -ga ~/Applications/Backup.app启动的,当前窗口失去焦点。这对我的用户来说可能是一个严重的烦恼,但它是它是什么。至少我们又有了工作备份。我认为-g开关会解决这个问题,但不幸的是它并没有改变任何东西。

我非常简短地尝试查看当您删除 .app 包(将其移至垃圾箱,清空垃圾箱)并将其替换为具有相同名称的新 .app 包时会发生什么。 我的观察是,当你删除旧的时,系统偏好中FDA中的条目消失了,但是当你将新的放回原处时,该条目又出现了,表明系统识别并会考虑新的.app有FDA。 但是,当我在那之后运行新应用程序时,我得到了原来的错误。 一旦我在系统偏好中删除了应用程序的 FDA 条目并为其添加了一个新的 FDA 条目,错误又消失了。 所以现在,我假设在替换 .app 包时,我也需要替换 FDA 条目,以使其正常工作。 很可能,如果只是替换 .app 包的一部分,它会继续工作。 这需要进一步调查AFAICT。

对于任何想要将 restic 捆绑到 .app 包中的人,这是我几个月前写的关于如何为任何 Go 程序执行此操作的通用教程,包括如果您只想更改一些设置并使用您的代码方式: https ://medium.com/@mattholt/packaging -a-go-application-for-macos-f7084b00f6b5

10.14.3 - 仅使用二进制运行仍然没有好消息。

$ /bin/ls ~/Library/Mail/
ls: : Operation not permitted

如果Terminal.app被添加到 FDA,则有效,但不仅仅是ls (或其他二进制文件)。

applescript/automator 可以工作,但在停靠栏中显示一个图标; 或者,使用 xcode/swift cli,将其编译为二进制文件并将其添加到 FDA(将/full/path/to替换为您的真实路径)

import Foundation
import os

let task = Process()

task.launchPath = "/full/path/to/bash"
task.arguments = ["/full/path/to/backup_script.sh"]

do{
    try task.run()
}
catch{
    os_log("error")
}

task.waitUntilExit()

@daviehh这里没有运气。

import Foundation
import os

let task = Process()

task.launchPath = "/bin/ls"
task.arguments = ["/Users/me/Library/Mail"]

do{
    try task.run()
}
catch{
    os_log("error")
}

task.waitUntilExit()
$ swiftc foo.swift
$ ./foo
ls: Mail: Operation not permitted
$ # add to FDA
$ ./foo
ls: Mail: Operation not permitted
$ sudo ./foo
ls: Mail: Operation not permitted

我最近开始使用 Restic 并一直试图让它作为一个从根 crontab sudo crontab -e调用的 cron 作业来工作,这样我可以感觉更安全一点,将我的备份脚本放在一个只能通过 sudo 权限访问的文件中. 我遇到了与@n8henrie完全相同的错误,但现在我有一个可行的解决方案,并且想知道这是否适用于这里的其他人。

首先是我的设置的一些背景:

我在/Users/myuser/bin中有一个名为restic-backup.sh的备份脚本,其权限700 (仅限 root/sudo 读/写/执行)。 我用我的根 crontab sudo crontab -e执行这个文件。 我使用 iTerm 作为我的默认终端。 我已经用 Homebrew 安装resticzsh

macOS 版本 10.14.5

restic-backup.sh:

我的备份脚本文件中包含以下内容。

#!/usr/local/bin/zsh
restic_path="/usr/local/bin"
logFile="/Users/myuser/Documents/Backups/configurations/Mac/backup_logs/$(date +%F_%H%M)_restic.log"
unset HISTFILE
export RESTIC_REPOSITORY="..."
export AWS_ACCESS_KEY_I'd="..."
export AWS_SECRET_ACCESS_KEY="..."
export RESTIC_PASSWORD="..."
$restic_path/restic --verbose backup /Users/myuser  &> $logFile

然后在我的根 crontab 文件中: sudo crontab -e我有:

0 */2 * * * /Users/myuser/bin/restic-backup.sh

在全盘访问中:

cron ==> /usr/sbin/cron
iTerm.app ==> /Applications/iTerm.app

@n8henrie一样,我认为实际访问像restic这样的文件的程序将是需要 FDA 的程序,但似乎发出初始sudo请求的程序需要 FDA: cron自动情况下为 $ iTerm.app

我发现了一些有用的东西:当将应用列入白名单时,它适用于应用目录中的任何脚本或二进制文件。因此,您不必直接启动应用程序。事实上,应用程序本身是完全无关的——它只是充当白名单的容器。您可以将脚本复制到任意应用程序,将该应用程序列入白名单,然后运行您的脚本。唯一需要注意的是,每次更改其中的脚本或二进制文件时,您都必须删除该应用程序并将其重新添加到白名单中。

@atticusmatticus @russelldavis——我认为最近的 MacOS 更新之一可能再次改变了一些东西——我肯定尝试过这两种策略,但都没有运气。 但我也尝试了以下,它已经停止工作,但现在又开始工作了(有点):

package main

import (
    "fmt"
    "io/ioutil"
)

func main() {
    fmt.Println("Starting...")
    matches, err := ioutil.ReadDir("/Users/me/Library/Mail")
    if err != nil {
        fmt.Println("Err:", err)
    } else {
        for _, match := range matches {
            fmt.Println(match.Name())
        }
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.me.gotest</string>
        <key>ProgramArguments</key>
        <array>
            <string>/Users/me/go/src/github.com/me/gotest/gotest</string>
        </array>
        <key>StartInterval</key>
        <integer>15</integer>
        <key>StandardErrorPath</key>
        <string>/Users/me/go/src/github.com/me/gotest/stderr.txt</string>
        <key>StandardOutPath</key>
        <string>/Users/me/go/src/github.com/me/gotest/stdout.txt</string>
    </dict>
</plist>
  1. go build
  2. gotest二进制文件(仅此而已)添加到全盘访问
  3. 将 plist 复制到~/Library/LaunchAgents/
  4. 加载launchd守护进程: launchctl load -w ~/Library/LaunchAgents/com.me.gotest.plist

现在,奇怪的是,将gotest二进制文件,而不是launchd (或launchctl )添加到 FDA,我仍然无法直接运行:

$ ls -l gotest
-rwxr-xr-x 1 me staff 2142552 Jul  2 09:15 gotest
$ ./gotest
Starting...
Err: open /Users/me/Library/Mail: operation not permitted
$ sudo ./gotest
Password:
Starting...
Err: open /Users/me/Library/Mail: operation not permitted

但它从启动守护程序(每 15 秒配置一次)运行时没有错误,它不是以 root 身份运行( ~/Library/不是/Library/ ,并且launchctl load不是sudo launchctl load ):

$ cat stdout.txt | head
Starting...
.DS_Store
PersistenceInfo.plist
V6
Starting...
.DS_Store
PersistenceInfo.plist
V6
Starting...
.DS_Store

奇怪的是,我仍然看到,包括重新启动:

||在 FDA 中使用二进制文件|在 FDA 中使用二进制文件
---|:---:|:---:
不使用sudo |err|err 的二进制文件
使用sudo |err|err 进行二进制
启动运行 go binary|RUNS|err

与restic没有直接关系,但与FDA问题有关。
我想我知道它可能是如何工作的,我希望我不是明显的队长。 我还没有找到有用的讨论、文章或文档。

FDA 适用于列入白名单的应用程序(打开意味着它们由 launchd 启动)、这些应用程序的任何子进程(甚至未列入白名单的子进程)以及列入白名单的二进制文件(如果它们是由launchdlaunchd.plist )直接启动的) launchctl submit )。 如果在具有未列入白名单的父应用程序/二进制文件的进程树中启动列入白名单的二进制文件,则它不起作用。

从这里看起来是launchd负责将进程树列入白名单,具体取决于被列入白名单的应用程序/二进制文件。

从实验来看,二进制文件的路径应该是准确的,因此如果对于列入白名单的二进制文件,launchctl plist 指定了WorkingDirectory并且使用了相对路径./some-binary ,则不会触发白名单,它甚至不起作用对于/some/path/./some-binary/some/path/../path/some-binary ,只有/some/path/some-binary
即使直接通过launchd启动脚本,也无法将白名单应用程序用于 shebang,因此#!/some/path/some-binary将不起作用,只有/some/path/some-binary /path/to/script

我认为我们有足够的信息和数据点,至少可以在文档中提供一些指南(也许还有指向此问题的链接),如果可以的话,我想开始研究它。

这应该是示例下的一个新点,例如在 Linux 上不以 root 身份运行的备份部分吗?

我计划指出:

  • 需要全盘访问才能备份尽可能多的磁盘
  • 以 root 身份运行的 launchd 脚本可以调用在 FDA 下列入白名单的二进制文件,而无需将 launchd 添加到 FDA
  • 除非在 FDA 中列出 Terminal.app,否则从终端调用二进制文件时无法访问整个磁盘
  • 如果 Terminal.app 在 FDA 中列出,它可以在调用二进制文件时访问整个磁盘,无论该二进制文件是否在 FDA 中

这听起来是不是反映了大家的理解和经验?

虽然有些令人费解,但我对过去 1 年以上在 2 台 Macbook 上运行的设置感到满意,我可能会将其中的一部分作为示例。 我的设置是:

  • 我有一个 shell 脚本,它基于各种环境变量运行特定于机器的 restic 命令(相同的脚本也在 4 台 Linux 计算机上运行,​​它们直接调用这个脚本)。
  • 在我的 MacOS 计算机上,我构建了一个基本上只运行上面的 shell 脚本的 go 二进制文件。 我在这里使用 shell 脚本来轻松配置/更新/版本控制,尽管这也可以直接在 Go 中轻松完成。
  • 此二进制文件已添加到 FDA
  • 我运行一个系统范围的 launchd 守护程序(以 root 权限运行)来按计划启动这个 go 二进制文件

使用类似于https://github.com/restic/restic/issues/2051#issuecomment -442872479 的二进制文件对我有用。 我选择了 c,因为我现在还没有安装。 供其他人复制/粘贴:

  1. 备份.c
#include <stdlib.h>
int main(void) {
  int status = system("./backup.sh");
  int ret = WEXITSTATUS(status);
  return ret;
}
  1. 编译: gcc -Wall -o backup backup.c
  2. 将备份二进制文件列入白名单并随意使用

奇怪的是,我仍然看到,包括重新启动:

在 FDA 中使用二进制 在 FDA 中不使用二进制
去二进制没有sudo err err
sudo err err 去二进制
启动运行 go binary RUNS err

谢谢!

我的解决方案是使用 -p、--exclude-files、--files-from 选项创建直接调用 restic 的 .plist 文件并将所有参数放入或放入单独的文件中。 当然,还要给予静态二进制 FDA 权限:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>my.backup_agent</string>

    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/restic</string>
        <string>backup</string>

        <string>-r</string>
        <string>s3:https://MY.STORAGE.SERVER/....</string>

        <string>-p</string>
        <string>.config/backup/restic.pwd</string>

        <string>--files-from</string>
        <string>.config/backup/backup.lst</string>

        <string>--exclude-file</string>
        <string>.config/backup/exclude.lst</string>
    </array>

    <key>EnvironmentVariables</key>
    <dict>
        <key>AWS_ACCESS_KEY_ID</key>
        <string>XXX</string>

        <key>AWS_SECRET_ACCESS_KEY</key>
        <string>YYY</string>
    </dict>

    <key>WorkingDirectory</key>
    <string>/Users/ME</string>

    <key>StandardErrorPath</key>
    <string>/Users/ME/log/backup.log</string>

    <key>StandardOutPath</key>
    <string>/Users/ME/log/backup.log</string>

    <key>StartCalendarInterval</key>
    <dict>
        <key>Hour</key>
        <integer>13</integer>

        <key>Weekday</key>
        <array>
        <integer>1</integer>
        <integer>2</integer>
        <integer>3</integer>
        <integer>4</integer>
        <integer>5</integer>
        </array>
    </dict>
</dict>
</plist>

如何找到应该添加到 FDA 的应用程序? 简而言之,找到运行它的应用程序。

您可以保持进程运行,并遍历进程的父 pid,直到祖先 pid 为 1,通过ps ajxps ao pid,ppid,commandgrep启动。

简而言之:

  • 通过 crontab 运行, /usr/sbin/cron ,已被 launchd.plist 弃用
  • 通过 launchd.plist 运行, ProgramProgramArguments中的二进制文件
  • 在终端中运行,Terminal.app
  • 通过 ssh、 /usr/libexec/sshd-keygen-wrapper或类似方式运行
  • 通过其他应用程序运行,找到它。

因此,对于@n8henrie ,您需要找到实际的二进制文件。

如果您通过 launchd 运行,另一种解决此问题的方法: LaunchControl现在附带一个名为fdautil的帮助程序,您可以将其列入白名单,然后使用fdautil exec运行命令。 它只允许您通过 LaunchControl 或fdautil set列入白名单的命令。

https://www.soma-zone.com/LaunchControl/FAQ.html上有一些关于它的信息,在应用程序的帮助窗口中有更多详细信息。

此页面是否有帮助?
0 / 5 - 0 等级