2011-02-28 27 views
7

我已经看到很多关于cron和ZF的文章,但大多数解决方案都让工作可以被公众触发。使用Zend框架安全地运行Cron作业

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

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

为了说明,下面是我在做什么(的作品),用于从PHP命令行cron作业运行,并在同一台服务器上,这样的事情:

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

Webroot的是:/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); 
?> 

所以,正如我所说,这个工作,所以我不找人给我写一个解决方案...只是CUR对做这件事“更好”感到厌烦。另外,如果我需要通过网络访问它,但仍希望仅通过cron运行它,该怎么办?如何让它更灵活(因为在这里我很难编码几条我怀疑可以变得更加动态的路径)?

我假设我可以创建一个允许的服务器列表,然后用$_SERVER['REMOTE_ADDR']进行测试?

你们都在想什么?建议?我一个人工作,所以我没有同事在这方面寻求帮助......这是我的同事,在某种程度上。

回答

8

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

所以在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注入一个环境变量。

+0

啊!我不知道你可以在crontab中设置一个变量。这很有用,但正如你所说,任何人都可以添加这个变量......我仍然希望为整个事情提供更安全的解决方案。 – Lothar 2011-02-28 19:52:26

+2

仅请求的代码属于Web根目录。如果Web服务器无法使用它,请将其移到Web根目录(包括框架库等)之外。只有提供给浏览器的内容属于... – ircmaxell 2011-02-28 19:54:02

+1

对,但如果您需要访问远程服务器上的cron实例(使用wget,lynx,curl或somesuch)的某些内容,您需要保留它网络根。因此,使其安全的问题仍然存在。确保它是我的问题中的真正问题。 – Lothar 2011-02-28 20:30:15

4

那么,当通过cron和web服务器运行时,PHPSAPI的值应该有所不同。

+1

+1,它更好用你的方式来确定环境 - – tawfekov 2011-02-28 20:20:19

+0

它总是;) – 2011-02-28 20:32:06

+0

我刚刚测试过这个,通过wron从cron运行它,以及phpsapi输出:'apache2handler'。所以wget会显示apache sapi,而来自cron的php会显示cli sapi ...似乎cron与它没有任何关系。 – Lothar 2011-02-28 21:09:57

1

不是由某个匿名用户,而不是由某人必须登录?

使用x.509客户端证书。

3

确保您的php cron工作的最佳方式是将php文件放入非public_html文件夹中。

例如:

你的网页是在/home/myuser/public_html/test.php

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

,并把在cron作业:

php -q /home/myuser/test.php 

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