使用 Zend 框架安全地运行 Cron 作业
我看过很多关于 cron 和 ZF 的帖子,但大多数解决方案都让工作运行,以供公众触发.
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.
如果你想设置一个只能由cron运行的动作怎么办?不是某个匿名用户,也不是必须登录的人?
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?
我使用的解决方案涉及将一个文件放在我的网络根目录之外,让它引导足够的 ZF 来使用我需要的东西(比如,我不需要视图),然后从 cron 中点击它.我的问题是,这是一种最佳实践"方式吗?如果您需要使代码可通过网络访问,但仍需要防止随机用户找到并运行它,该怎么办?
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?
为了说明,这是我正在为从 php 命令行和在同一台服务器上运行的 cron 作业执行的操作(有效),如下所示:
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 是:/Apps/ZF/someproject/
crontest.php:
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 运行怎么办?让它更灵活怎么样(因为在这里我硬编码了一些我怀疑可以变得更加动态的路径)?
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)?
我假设我可以列出允许的服务器列表,然后使用 $_SERVER['REMOTE_ADDR']
进行测试?
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.
推荐答案
一种方法是设置环境变量.
One way is to set an environmental variable.
所以在你的 crontab 中
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
";
exit(1);
}
现在,任何人都可以将他们的环境变量设置为该值并成功运行 cron,但它应该停止琐碎的运行(或意外)...
Now, anyone can set their environmental variable to that value and successfully run the cron, but it should stop the trivial running (or accidental)...
但还要注意,任何可以在服务器上编辑环境变量的人都可以执行它,所以没有真正的方法从那个角度来保护它(至少没有一个是自动化的)......还值得注意的是你无法通过 HTTP 注入环境变量.
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.
相关文章