3 * how this might work..
5 * a) login - if it's a new IP not seen that day
6 * --> touch /tmp/run_pman_admin_iptables
8 * cron every minute... ?? << could do some kind of IPC?!?
10 * if file exists -> run this code.
12 * This code finds all the IP's used in the last 24 hours.
13 * and opens the firew all for them.
25 require_once 'Pman.php';
27 class Pman_Admin_Iptables extends Pman {
29 static $cli_desc = "Read ip addresses that have been used to log in, and add them to the iptables list..";
37 if (!$this->bootLoader->cli) {
42 function monitorFile()
44 $ev = DB_DataObject::Factory('Events');
45 $db = $ev->database();
47 return '/tmp/run_pman_admin_iptables-'.$db;
50 function get($opt = '')
55 $mf = $this->monitorFile();
57 $fe = file_exists($mf);
67 // find IP's that have been used to log in.
68 // dump them to the iptables file.
69 // if it's different - apply it...
70 //DB_DataObject::debugLevel(1);
71 // need to get a list of users who have Admin.Iptables rights..
72 /*$gr = DB_DataObject::factory('group_rights');
73 $grps = $gr->groupsWithRights('Admin.Iptables', 'S');
75 $gr = DB_DataObject::factory('groups');
76 $gr->get('name', 'Administrators');
79 $gm = DB_DataObject::factory('group_members');
80 $gm->whereAddIn('group_id', $grps, 'int');
82 $gm->selectAdd('distinct(user_id) as user_id');
83 $peps = $gm->fetchAll('user_id');
89 $p = DB_DataObject::Factory('Person');
91 $p->whereAdd("join_company_id_id.comptype = 'OWNER'");
93 $p->selectAdd("{$p->tableName()}.id as id");
95 $peps = $p->fetchAll('id');
98 switch( $p->getDatabaseConnection()->phptype) {
100 $interval = "INTERVAL 1 DAY";
103 $interval = " INTERVAL '1 DAY'";
106 die("database NOT SUPPORTED?!");
109 $e = DB_DataObject::factory('Events');
110 $e->action = 'LOGIN';
113 distinct(ipaddr) as ipaddr
114 max(event_when) + $interval as expires
117 $e->person_table = DB_DataObject::factory('person')->tableName();
118 $e->whereAddIn('person_id', $peps, 'int');
119 $e->groupBy('ipaddr');
120 $e->whereAdd("event_when > NOW() - $interval");
123 $ips = $e->fetchAll('ipaddr','expires');
125 require_once 'System.php';
126 //inet addr:202.67.151.28 Bcast:202.67.151.255 Mask:255.255.255.0
127 $ifconfig = System::which('ifconfig');
130 $this->jerr("ifconfig could not be found.");
133 $if = $this->exec($ifconfig);
136 foreach(explode("\n", $if) as $l) {
138 if (!preg_match('/inet addr/', $l)) {
142 preg_match('/\s*inet addr:([0-9.]+)\s+/', $l, $match);
143 $ips[$match[1]] = ''; // no expiry...
147 $cache = ini_get('session.save-path') . '/pman_admin_iptables.cache';
149 $this->updateTables();
155 function updateTables()
158 require_once 'System.php';
160 $iptables = System::which('iptables');
163 $this->jerr("iptables could not be found.");
165 // this should have been set up already..
166 // in the base firewall code.
169 // -A INPUT -p udp -m udp --dport 5432 -j postgres
170 // -A INPUT -p tcp -m tcp --dport 5432 -j postgres
173 // /sbin/iptables -L postgres -v -n --line-numbers
175 $res = $this->exec("{$iptables} -L postgres -v -n --line-numbers");
183 foreach(explode("\n", $res) as $i => $line) {
185 $head = preg_split('/\s+/', $line);
186 $head[10] = 'comments';
192 $ar = preg_split('/\s+/', $line);
193 if (count($ar) < 3) {
196 $ar[10] = implode(' ',array_slice($ar, 10));
198 foreach($head as $k=>$v) {
202 //var_dump($row['target']);
203 if ($row['target'] != 'ACCEPT') {
207 // got input rules now..
208 if (!empty($row['comment'])) {
209 foreach((array)json_decode($row['comment']) as $k=>$v) {
214 if (!empty($row['expires'])) {
215 if (strtotime($row['expires']) < time()) {
216 $remove[ $row['source'] ] = $row;
220 $old[ $row['source'] ] = $row;
222 $lastrulenum = $row['num'];
231 foreach($this->ips as $ip=>$expires) {
232 $old = isset($cur[$ip]) ? $cur[$ip] : false;
234 if (strtotime($expires) <= strtotime($old['expires'])) {
235 // expires time is the same..
236 //?? make sure it's not flagged for removal..
243 $this->exec("{$iptables} -R postgres {$old['num']} -s {$ip}/32 -j ACCEPT --comment ".
244 escapeshellarg(json_encode(array('expires'=>$expires)))) ;
246 if (isset($remove[$ip])) {
252 $this->exec("{$iptables} -I postgres {$lastrulenum} -s {$ip}/32 -j ACCEPT --comment ".
253 escapeshellarg(json_encode(array('expires'=>$expires))));
258 // remove rules that need deleting..
259 foreach($remove as $ip => $r) {
260 $this->exec("{$iptables} -d postgres {$r['num']} ");
270 function createBase()
273 $iptables = System::which('iptables');
275 $this->jerr("iptables could not be found.");
280 $this->exec("{$iptables} -F postgres"); // flush old
281 $this->exec("{$iptables} -N postgres"); // create new..
283 $this->exec($iptables. ' -A postgres -m limit --limit 2/min -j LOG '.
284 '--log-prefix "IPTables-Dropped: " --log-level 4');
285 $this->exec("$iptables -A postgres -j DROP");