2011-02-28 58 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作業可以使用它。