Skip to main content
 首页 » 编程设计

php之将 IPTables 输出拆分为数据库的多维数组

2023年11月22日18虾米哥

我正在尝试将我的 Debian 服务器中的当前 IPTables 规则整齐地列在数据库中。

为此,我编写了几个步骤。

  1. 首先,我们获得带有行号的 IPTables 输出。 (以输入链为例)

    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); 
} 
 
 
 
} 

-- 输出--

root@debian:/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 

请您参考如下方法:

我假设您的正则表达式是正确的。您实际上是使用 $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 

as continue 实际上完全停止了在您的 foreach() 中的这种尝试