使用 Zend Framework 安全地运行 Cron 作业

发布于 2024-10-19 12:13:37 字数 1607 浏览 4 评论 0原文

我看过很多关于 cron 和 ZF 的帖子,但大多数解决方案都让工作可以由公众触发运行。

如果你想设置一个只能由 cron 运行的操作怎么办?不是由某个匿名用户也不是由必须登录的人?

我使用的解决方案涉及将一个文件放在我的 Web 根目录之外,让它引导足够的 ZF 来使用我需要的内容(例如,我不需要视图),然后从 cron 中点击该文件。 我的问题是,这是执行此操作的“最佳实践”方式吗?如果您需要使代码可以通过网络访问,但仍然需要防止随机用户找到并运行它,该怎么办?

为了说明,以下是我正在为从 php 运行的 cron 作业所做的(有效的)命令行,在同一台服务器上,如下所示:

* 10 * * * php /Apps/ZF/cronjobs/crontest.php

Webroot is: /Apps/ZF/someproject/

crontest.php:

<?php
ini_set('include_path', ini_get('include_path') . ':/Apps/ZF/someproject/library');

define('APPLICATION_PATH','/Apps/ZF/someproject/application');
define('APPLICATION_ENVIRONMENT','test');

//Include the loader (for loading ZF resources)
require_once 'Zend/Loader.php';

//Include the model (to access the Sites model in this case)
require_once(APPLICATION_PATH . '/models/Planets.php');

Zend_Loader::registerAutoload();

$configuration = new Zend_Config_Ini(
    APPLICATION_PATH . '/config/config.ini',
    APPLICATION_ENVIRONMENT
);

// DB adapter
$dbAdapter = Zend_Db::factory($configuration->database);

// DB table setup
Zend_Db_Table_Abstract::setDefaultAdapter($dbAdapter);

// Whatever code we want to run... 
$test = new Model_Planets();

$test->fetchEntries();

Zend_Debug::dump($test);
?>

所以,正如我所说,这有效,所以我不需要找人给我写一个解决方案......只是好奇如何“更好”地做到这一点。另外,如果我需要通过网络访问它,但仍然希望它只能由 cron 运行,该怎么办?让它更灵活怎么样(因为我在这里硬编码了一些我怀疑可以变得更加动态的路径)?

我假设我可以列出允许的服务器,然后使用 $_SERVER['REMOTE_ADDR'] 进行测试?

大家觉得怎么样?建议?我独自工作,所以我没有同事可以在这方面寻求帮助……在某种程度上,我的同事也是如此。

I've seen plenty of posts about cron and ZF but most of the solutions leave the job to be run available to triggering by the public.

What if you want to set up an action that can ONLY be run by cron? Not by some anonymous user and not by someone that has to log in?

The solution I am using involved putting a file outside of my web root, having it bootstrap enough of the ZF to use what I need (like, I don't need the view) and then hit that from cron. My questions are, is this a "best practice" way to do this? What if you needed to make the code accessible over the web but still need to prevent random users from finding and running it?

For illustration, here is what I am doing (that works) for a cron job run from the php command line, and on the same server, something like this:

* 10 * * * php /Apps/ZF/cronjobs/crontest.php

Webroot is: /Apps/ZF/someproject/

crontest.php:

<?php
ini_set('include_path', ini_get('include_path') . ':/Apps/ZF/someproject/library');

define('APPLICATION_PATH','/Apps/ZF/someproject/application');
define('APPLICATION_ENVIRONMENT','test');

//Include the loader (for loading ZF resources)
require_once 'Zend/Loader.php';

//Include the model (to access the Sites model in this case)
require_once(APPLICATION_PATH . '/models/Planets.php');

Zend_Loader::registerAutoload();

$configuration = new Zend_Config_Ini(
    APPLICATION_PATH . '/config/config.ini',
    APPLICATION_ENVIRONMENT
);

// DB adapter
$dbAdapter = Zend_Db::factory($configuration->database);

// DB table setup
Zend_Db_Table_Abstract::setDefaultAdapter($dbAdapter);

// Whatever code we want to run... 
$test = new Model_Planets();

$test->fetchEntries();

Zend_Debug::dump($test);
?>

So, as I said, this works so I'm not looking for someone to write me a solution... just curious about doing this "better". Also, what if I needed this to be accessible via the web but still want to keep it only runnable by cron? What about making it more flexible (because here I am hard coding a few paths that I suspect could be made more dynamic)?

I assume I could make a list of permitted servers, then test that with $_SERVER['REMOTE_ADDR']?

What do you all think? Suggestions? I work alone so I have no colleague to ask for help on this... SO is my colleague, in a way.

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

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

发布评论

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

评论(4

乙白 2024-10-26 12:13:37

一种方法是设置环境变量。

所以在你的 crontab

SCRIPT_RUN_ENV=cron
* * * * * foo.php // Whatever your line is

然后,在应用程序中,只需检查:

if (get_env('SCRIPT_RUN_ENV') != 'cron') {
    echo "Program cannot be run manually\n";
    exit(1);
}

现在,任何人都可以将其环境变量设置为该值并成功运行 cron,但它应该停止琐碎的运行(或意外)...

但还要注意,任何人可以在服务器上编辑环境变量的人已经可以执行它,因此没有真正的方法可以从这个角度保护它(至少没有自动化的方法)...还值得注意的是,您无法通过 HTTP 注入环境变量。

One way is to set an environmental variable.

So in your crontab

SCRIPT_RUN_ENV=cron
* * * * * foo.php // Whatever your line is

Then, in the application, just check that:

if (get_env('SCRIPT_RUN_ENV') != 'cron') {
    echo "Program cannot be run manually\n";
    exit(1);
}

Now, anyone can set their environmental variable to that value and successfully run the cron, but it should stop the trivial running (or accidental)...

But also note that anyone who can edit the environmental variable on the server can already execute it, so there's no real way to secure it from that angle (none that are automated at least)... It's also worth noting that you cannot inject an environmental variable through HTTP.

小嗷兮 2024-10-26 12:13:37

好吧,当 PHPSAPI 通过 cron 和 Web 服务器运行时,其值应该有所不同。

Well, the value of PHPSAPI should differ when it's run via cron and web-server.

故事灯 2024-10-26 12:13:37

确保 php cron 作业安全的最佳方法是将 php 文件放在 non-public_html 文件夹中。

例如:

您的页面位于 /home/myuser/public_html/test.php

将其移动到 /home/myuser/test.php

并放入 cron 作业:

php -q /home/myuser/test.php

现在,没有用户可以从浏览器进入您的页面,只有 cron 作业可以使用它。

The best way to secure your php cron job is putting the php file in a non-public_html folder.

For example:

Your page is in /home/myuser/public_html/test.php

Move it to /home/myuser/test.php

and put in the cron job :

php -q /home/myuser/test.php

Now, no user can enter your page from browser and only the cron job can use it.

眼泪也成诗 2024-10-26 12:13:37

不是由某些匿名用户或必须登录的人执行的吗?

使用 x.509 客户端证书。

Not by some anonymous user and not by someone that has to log in?

Use an x.509 client certificate.

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