2013-12-09 89 views
0

我試圖在我的Debian服務器中整齊地列出數據庫中的當前IPTables規則。將IPTables輸出分割爲數據庫的多維數組

要做到這一點,我寫了幾個步驟。

  1. 首先,我們得到IPTables輸出的行號。 (INPUT鏈爲例)

    的iptables -L INPUT -nvx --line

我得到一個整潔的輸出,我想在我的數據庫來獲取完全相同的方式。例如, ;

Number, Chain, Protocol, Port, in, out 

等等。

爲了使這個輸出與導入到數據庫兼容,我需要把它變成一個多維數組。這是我卡住的地方。這需要是這樣的;

[0] (entry of rule) 
[number],[chain],[protocol]... 

[1] 
[number],[chain],[protocol] 

我該如何以最有效的方式做到這一點?

- 更新的代碼 -

function getIPTables() { 
$processHandle = popen('/usr/bin/sudo /sbin/iptables -L INPUT -nvx --line-numbers | tail -n +3', 'r'); 
$content = ''; 
    while (!feof($processHandle)) { 
     $content .= fread($processHandle, 4096); 
    } 
pclose($processHandle); 



// break out all new lines into an array 
$lines = explode("\n", $content); 


foreach ($lines as $line) { 
    $commands = array(); 

    $segments = explode(" ", $line); 

    $newEntry = array(
     'Number' => $segments[0], 
     'Chain'  => $segments[1], 
     'Protocol' => $segments[2], 
     'Port'  => $segments[3], 
     'in'  => $segments[4], 
     'out'  => $segments[5] 
    ); 
    array_push($commands, $newEntry); 
    print_r($commands); 
} 



} 

- 輸出 -

[email protected]:/home/michael/Documents/PHPCLIFILES# php getAllRules 
Local DB rules from users loaded in array 
PHP Notice: Undefined offset: 1 in /home/michael/Documents/PHPCLIFILES/getAllRules on line 47 
PHP Notice: Undefined offset: 2 in /home/michael/Documents/PHPCLIFILES/getAllRules on line 48 
PHP Notice: Undefined offset: 3 in /home/michael/Documents/PHPCLIFILES/getAllRules on line 49 
PHP Notice: Undefined offset: 4 in /home/michael/Documents/PHPCLIFILES/getAllRules on line 50 
PHP Notice: Undefined offset: 5 in /home/michael/Documents/PHPCLIFILES/getAllRules on line 51 

回答

1

我會假設你的正則表達式的是正確的。實際上,您使用$commands .= <some text>將所有內容附加到同一個字符串中。 而不是將它追加到相同的字符串,您應該使$commands數組。然後你想爲每一行你想要的實例化一個新的數組($line)。 push你想保留到您$line陣列的事情,並在每一行,你array_push($commands, $line)

Array_push()結束:http://php.net/manual/en/function.array-push.php

這可能是您的foreach()

foreach ($lines as $line) { 
    $commands = new array; 
    if (empty($line)) { 
     continue; //empty lines are silly 
    } 
    // ... do all the checks to validate if you currently have a valid LINE 
    //We know that whatever we have now is a valid line 
    $segments = explode(line bla bla); //explode this line on tabs or spaces .. dunno what the output of your console is. 
    //At this point you know exactly where every part you need is, considering the console always gives the same output. 
    //Either you do some validations here, or you go for the lazy approach and go: 
    $newEntry = array(
     'Number' => $segments[0], 
     'Chain'  => $segments[1], 
     'Protocol' => $segments[2], 
     'Port'  => $segments[3], 
     'in'  => $segments[4], 
     'out'  => $segments[5] 
    ); 
    array_push($commands, $newentry); 
} 

代碼的做法是不測試,但你應該知道我要去哪裏。

您的代碼:

//instantiate a new empty named variable. 
$commands = ''; 
//for every line in your console-dump file 
foreach ($lines as $line) { 
    //Is the line empty 
    if (empty($line)) { 
     //skip line and go to next line 
     continue; 
    } 
    //Does the line start with # 
    if (preg_match('/^#/', $line) === 1) { 
     //skip line and go to next line 
     continue; 
    } 
    //Does the line start with * 
    if (preg_match('/^\*/', $line) === 1) { 
     //skip line and go to next line 
     continue; 
    } 
    //Does the line start with 'COMMIT' 
    if (preg_match('/^COMMIT/', $line) === 1) { 
     //skip line and go to next line 
     continue; 
    } 
    //we have a valid line now, so let's do stuff 
    $match = array(); 
    //Does the line contain: 
    if (preg_match('/^:([A-Z ]*).*/', $line, $match) === 1) { 
     //skip line and go to next line 
     continue; 
    } 
    //Only if the line is a 'valid' line, and does not have your last match, 
    //Then you will append "iptables {$line}\n" to $commands 
    $commands .= "iptables {$line}\n"; 
    //This way it was a bit useless for you to cut up the line using the preg_match 
    //and store it into $match, cause you don't do anything with $match 
} 

您最初的做法是很好的。取決於您的控制檯如何返回可預測的值,您可以使用正則表達式(但實際上使用結果)遵循您的方法,或者您只需採用懶惰方法並使用我建議的方法即可。

請注意CONTINUE實際上會打破您當前的循環,並進入下一次迭代。

$array = array(1, 2, 3, 4, 5); 
foreach($array as $number){ 
    if($number < 3){ 
     continue; 
    } 
    print($number .'\n'); 
} 

結果將是:

3\n 
4\n 
5\n 

根據實際繼續完全停止這樣的嘗試在你的foreach()

+0

你說什麼是;我現在正在推動整個規則的制定,當它結束時,我會創建一個新的行。但是,我可以像-A那樣停止每一個條帶並將它推入新的堆棧? 你能幫我一個例子嗎?我是PHP的初學者,所以這對我來說有點高級。 – MichaelP

+0

編輯我的答案,我希望它更有意義。 – Viridis

+0

現在看看它,並嘗試一些事情。我瞭解你的方法概念,我非常感謝! – MichaelP