Dynamic firewall met CLI parser
Gepost door Peter Davidse op 23-04-2009 13:42.
Command Line script voor het dynamisch verwijderen en toevoegen van host in een iptables firewall.
De CLI parameter parser is zo opgebouwd dat het script eenvoudig is aan te passen voor andere toepassingen.
Het script maakt gebruik van "exec", dus shell commando's om te functioneren, controleer zelf of deze voldoen aan jouw systeem eisen.
Zonder parameters of bij fouten krijg je een uitgebreide help.
Het gebruik als Dynamische Firewall is "proof of concept" voor de CLI parser.
Doel van het script is om snel een host toe te voegen die bv je ssh bashed.
Het is geen firewall builder script en is ook nooit zo bedoeld!
Knownbug :
Het verwijderen gaat niet altijd goed wanneer ipv het ipaddress de hostname is vermeld en vice versa.
Bestanden van dit script
index.php
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | #!/usr/bin/php -q
<?php
/** Description : Dynamic Firewall.
* Function : Configure iptables dynamically from CLI
* Author : Peter Davidse (phpscripts at esdivad dot com)
* Version : 1.0
* Date : 30.3.2009
* notes - Linux with iptables only
* - loosely based on dynfw
* - you can use the parameter parser for other CLI scripts
*/
// Parse the parameter and put them in an array for evaluation
function parseOptions($array) {
$isoption = FALSE;
$parameters['filename'] = str_replace("./","",$array[0]);
array_shift($array); //we do not need the program name
foreach ($array as $val) {
if ($isoption) {
// check if we have an option
if (strpos($val,"-")===0) {
$parameters[$option] = '';
$option = $val;
$isoption = TRUE;
} else {
$option = str_replace("-","", $option);
$parameters[$option] = $val;
$isoption = FALSE;
}
} else {
if (strpos($val,"-")===0) {
$option = str_replace("-","", $val);
$isoption = TRUE;
} else {
$isoption = FALSE;
}
}
// if there is an last option
if (current($array) && (strpos($val,"-")===0)) {
$option = str_replace("-","", $val);
$parameters[$option] = '';
}
}
return $parameters;
}
// see if the ipaddress is correctly formed
function checkIPAddress($address) {
if (preg_match( "/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/", $address)) {
return TRUE;
} else {
echo FALSE;
}
}
function checkParameters($parameters) {
// sanitize the parameters given on the command line
if (array_key_exists('h',$parameters) || count($parameters)==0) {
help();
}
$error = '';
//convert all parameters in array to variables
foreach ($parameters as $key => $value) {
global $$key;
$$key = $value;
}
if (isset($b) && isset($d)) {
$error .= "\nconfused! do not set -b and -d together";
}
if (isset($i) && isset($n)) {
$error .= "\nconfused! do not use -i and -n together";
}
// check action parameter, needs to be on or off
if (!isset($a)) {
$error .= "\nparameter -a not set";
} else {
if(!in_array($a,array("on","off"))) {
$error .= "\nparameter -a needs to be valid";
}
}
// see if we have a valid hostname or ipaddress (ip v4 only)
if (!isset($i) && !isset($n)) {
$error .= "\nparameter -i or -n not set";
} else {
if(isset($i)) {
if(!checkIPAddress($i)) {
$error .= "\nparameter -i not a valid IP Address";
}
} else {
if(!checkIPAddress(gethostbyname($n))) {
$error .= "\nparameter -n does not return a valid IP Address";
}
}
}
if(!empty($error)) {
echo "\nErrors found in parameters:\n";
echo $error."\n";
help();
}
}
// displays help
function help() {
//show help and quit
$help = "\nusage:\n";
$help .= "\n";
$help .= "block : -b -i [ipaddress] / -n [hostname] -a {on/off} {-f} \n";
$help .= "drop : -d -i [ipaddress] /- n [hostname] -a {on/off} {-f} \n";
$help .= "-f forces an addition even if the host is already listed\n";
$help .= "Use drop if the host is really intrusive, otherwise use block!";
$help .= "\n";
echo $help;
exit;
}
// BEGIN OF THE SCRIPT
checkParameters(parseOptions($argv)); // if parameter are wrong script exits in help()
if ($a=="on") {
$action = "-I";
} else {
$action = "-D";
}
// use hostname as option
if (isset($n)) {
$i = $n;
}
// is the address already in iptables
$ipexists = exec("iptables -L | grep $i | wc -l");
if ($ipexists!=0 && $a == "on") {
echo "IP address already exists in iptables! You can use -f to force addition!\n";
if (!isset($f)) { // force the rule even if the ip address exists
exit;
}
}
if ($ipexists==0 && $a == "off") {
echo "IP address does not exist in iptables!\n";
exit;
}
// do the drop action
if (isset($d)) {
exec("iptables $action INPUT -s $i -j DROP");
exec("iptables $action OUTPUT -s $i -j DROP");
exec("iptables $action FORWARD -s $i -j DROP");
echo "IP address $i drop $a\n";
}
// do the block action
if (isset($b)) {
exec("iptables $action INPUT -s $i -j DROP");
exec("iptables $action INPUT -p tcp -s $i -j REJECT --reject-with tcp-reset");
exec("iptables $action OUTPUT -d $i -j DROP");
exec("iptables $action OUTPUT -p tcp -d $i -j REJECT --reject-with tcp-reset");
exec("iptables $action FORWARD -d $i -j DROP");
exec("iptables $action FORWARD -p tcp -d $i -j REJECT --reject-with tcp-reset");
echo "IP address $i block $a\n";
} |


