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) {
203 if ($row['target'] != 'INPUT') {
206 // got input rules now..
207 if (!empty($row['comment'])) {
208 foreach((array)json_decode($row['comment']) as $k=>$v) {
212 if (!empty($row['expires'])) {
213 if (strtotime($row['expires']) < time()) {
214 $remove[ $row['source'] ] = $row;
217 $old[ $row['source'] ] = $row;
219 $lastrulenum = $row['num'];
229 foreach($this->ips as $ip=>$expires) {
230 $old = isset($cur[$ip]) ? $cur[$ip] : false;
232 if (strtotime($expires) <= strtotime($old['expires'])) {
233 // expires time is the same..
234 //?? make sure it's not flagged for removal..
241 $this->exec("{$iptables} -R postgres {$old['num']} -s {$ip}/32 -j ACCEPT --comment ".
242 escapeshellarg(json_encode(array('expires'=>$expires)))) ;
244 if (isset($remove[$ip])) {
250 $this->exec("{$iptables} -I postgres {$lastrulenum} -s {$ip}/32 -j ACCEPT --comment ".
251 escapeshellarg(json_encode(array('expires'=>$expires))));
256 // remove rules that need deleting..
257 foreach($remove as $ip => $r) {
258 $this->exec("{$iptables} -d postgres {$r['num']} ");
268 function createBase()
271 $iptables = System::which('iptables');
273 $this->jerr("iptables could not be found.");
278 $this->exec("{$iptables} -F postgres"); // flush old
279 $this->exec("{$iptables} -N postgres"); // create new..
281 $this->exec($iptables. ' -A postgres -m limit --limit 2/min -j LOG '.
282 '--log-prefix "IPTables-Dropped: " --log-level 4');
283 $this->exec("$iptables -A postgres -j DROP");