运行 shell 脚本时,如何防止其覆盖或截断文件?

发布于 2024-08-24 02:49:42 字数 596 浏览 9 评论 0原文

如果应用程序运行时它使用的共享库之一被写入或截断,则应用程序将崩溃。移动文件或使用“rm”批量删除它不会导致崩溃,因为操作系统(在本例中为 Solaris,但我认为在 Linux 和其他 *nix 上也是如此)足够聪明,不会删除与当任何进程打开该文件时。

我有一个执行共享库安装的 shell 脚本。有时,它可用于重新安装已安装的共享库的版本,而无需先卸载。由于应用程序可能正在使用已安装的共享库,因此脚本足够智能以 rm 文件或将它们移开(例如,当我们知道没有应用程序时 cron 可能会清空的“已删除”文件夹),这一点很重要将运行),然后再安装新的,这样它们就不会被覆盖或截断。

不幸的是,最近有一个应用程序在安装后就崩溃了。巧合?很难说。这里真正的解决方案是切换到比旧的巨大 shell 脚本更强大的安装方法,但在切换之前最好有一些额外的保护。有没有什么方法可以包装 shell 脚本以防止其覆盖或截断文件(理想情况下会大声失败),但仍允许移动或 rm'd?

标准 UNIX 文件权限不起作用,因为您无法区分移动/删除与覆盖/截断。别名可以工作,但我不确定哪些命令需要别名。我想象类似 truss/strace 的东西,除了在每个操作之前它会检查过滤器是否真正执行它。我不需要一个即使针对故意恶意脚本也能工作的完美解决方案。

If while an application is running one of the shared libraries it uses is written to or truncated, then the application will crash. Moving the file or removing it wholesale with 'rm' will not cause a crash, because the OS (Solaris in this case but I assume this is true on Linux and other *nix as well) is smart enough to not delete the inode associated with the file while any process has it open.

I have a shell script that performs installation of shared libraries. Sometimes, it may be used to reinstall versions of shared libraries that were already installed, without an uninstall first. Because applications may be using the already installed shared libraries, it's important the the script is smart enough to rm the files or move them out of the way (e.g. to a 'deleted' folder that cron could empty at a time when we know no applications will be running) before installing the new ones so that they're not overwritten or truncated.

Unfortunately, recently an application crashed just after an install. Coincidence? It's difficult to tell. The real solution here is to switch over to a more robust installation method than an old gigantic shell script, but it'd be nice to have some extra protection until the switch is made. Is there any way to wrap a shell script to protect it from overwriting or truncating files (and ideally failing loudly), but still allowing them to be moved or rm'd?

Standard UNIX file permissions won't do the trick because you can't distinguish moving/removing from overwriting/truncating. Aliases could work but I'm not sure what entirety of commands need to be aliased. I imagine something like truss/strace except before each action it checks against a filter whether to actually do it. I don't need a perfect solution that would work even against an intentionally malicious script.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

等风也等你 2024-08-31 02:49:42

您可以通过 I/O 重定向来防止脚本被覆盖,方法是

set noclobber

通过 cp 防止覆盖等更难。我的倾向是重置脚本的 PATH 以便使用仅包含一个条目的 PATH 运行,这是一个“有福的”目录,您可以在其中放置您知道安全的命令。例如,这可能意味着您的 cp 版本始终使用 --remove-destination 选项(可能是 GNU 主义)。无论如何,您都可以安排脚本仅执行受祝福的目录中的命令。然后,您可以单独审查每个此类命令。

如果您可以阻止脚本通过绝对路径名执行命令,那就太好了,但我不知道该怎么做。如果您在常规目录中进行安装,chroot 监狱可能没有帮助,除非您进行大量环回安装以使这些目录可见。如果您要安装的目录包含危险命令,我不知道如何才能完全保护自己免受它们的侵害。

顺便说一句,我尝试了解 install(1) 是否在安装前删除了目标,但没有成功。学习起来会很有趣。

You can prevent a script from overwriting through I/O redirection by

set noclobber

Preventing overwriting by cp and the like is harder. My inclination would be to reset the PATH for the script to run with PATH containing just a single entry, a "blessed" directory where you place commands that you know are safe. This might mean, for example, that your version of cp is arranged always to use the --remove-destination option (probably a GNU-ism). In any case, you arrange for the script to execute only commands from the blessed directory. You can then vet each such command individually.

It would be good if you could prevent a script from executing a command by absolute pathname, but I don't know how to do that. If you are doing installations in your regular directories, a chroot jail probably does not help unless you do a lot of loopback mounting to make those directories visible. And if the directories into which you're installing contain dangerous commands, I don't see how you can protect yourself against them completely.

Incidentally, I tried and failed to learn if install(1) removes the desitination before installing. It would be interseting to learn.

朱染 2024-08-31 02:49:42

我猜是 Bash 脚本?剧本很长吗?如果没有,您可以手动执行此操作:

if [ ! -f /tmp/foo.txt ] #If file does not exist
then
    ...code
fi

但我认为您正在寻求一种方法来将其包装在脚本中。您当然可以使用 strace 监视文件写入,但据我所知,它没有中断它们的功能,除非您使用规则等设置某种入侵检测系统。

但说实话,除非它是一个巨大的脚本,否则可能会更多麻烦大于其价值

Bash script I presume? Is the script very long? If not, you can do this manually:

if [ ! -f /tmp/foo.txt ] #If file does not exist
then
    ...code
fi

But I think you're asking for a way to wrap this around the script. You can certainly monitor the file writes with strace but AFAIK it doesn't have the functionality to interrupt them, unless you set up some sort of Intrusion Detection System with rules etc.

But to be honest, unless it's a huge script, that's probably more trouble than it's worth

把时间冻结 2024-08-31 02:49:42

编写您自己的 safe_install() 函数并确保它们是唯一使用的方法。如果您确实需要确定,请运行两个进程。一个将有权进行更改,而另一个将提前放弃所有权限并告诉另一个脚本执行实际的磁盘工作。

Write your own safe_install() functions and make sure they're the only methods used. If you really need to be sure, run two processes. One would have permissions to make changes and the other would drop all privileges early and tell the other script to do the actual disk work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文