diff options
Diffstat (limited to 'usr/local')
-rwxr-xr-x | usr/local/www/diag_logs_filter_dynamic.php | 432 | ||||
-rw-r--r-- | usr/local/www/themes/metallic/all.css | 116 |
2 files changed, 527 insertions, 21 deletions
diff --git a/usr/local/www/diag_logs_filter_dynamic.php b/usr/local/www/diag_logs_filter_dynamic.php new file mode 100755 index 0000000..9790a89 --- /dev/null +++ b/usr/local/www/diag_logs_filter_dynamic.php @@ -0,0 +1,432 @@ +<?php +/* $Id$ */ +/* + diag_logs_filter.php + part of pfSesne by Scott Ullrich + originally based on m0n0wall (http://m0n0.ch/wall) + + Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +require("guiconfig.inc"); + +$filter_logfile = "{$g['varlog_path']}/filter.log"; + +/* AJAX related routines */ +handle_ajax(); + +$nentries = $config['syslog']['nentries']; +if (!$nentries) + $nentries = 50; + +if ($_POST['clear']) { + exec("killall syslogd"); + exec("/usr/sbin/clog -i -s 262144 /var/log/filter.log"); + system_syslogd_start(); +} + +/* format filter logs */ +function conv_clog($logfile, $tail = 50) { + global $config; + + /* make interface/port table */ + $iftable = array(); + $iftable[$config['interfaces']['lan']['if']] = "LAN"; + $iftable[get_real_wan_interface()] = "WAN"; + for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) + $iftable[$config['interfaces']['opt' . $i]['if']] = $config['interfaces']['opt' . $i]['descr']; + + $sor = isset($config['syslog']['reverse']) ? "-r" : ""; + + $logarr = ""; + exec("/usr/sbin/clog {$logfile} | /usr/bin/tail {$sor} -n {$tail}", $logarr); + + $filterlog = array(); + + $counter = 0; + + foreach ($logarr as $logent) { + + $log_split = ""; + + /* pf: 6. 272592 rule 218/0(match): block in on fxp0: X.XXX.XXX.XXX.4503 > XX.X.XXX.X.6881: S 1163549441:1163549441(0) win 65535 <mss 1432,nop,nop,sackOK> */ + + preg_match("/(.*)\s(.*)\spf:.*rule (.*)\(match\):\s(\w+)\sin\son\s(\w+:)\s([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,7})\s([\<|\>])\s([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,7}):.*/",$logent,$log_split); + + if($log_split[5] == "") + preg_match("/(.*)\s(.*)\spf:.*rule (.*)\(match\):\s(\w+)\sin\son\s(\w+:)\s([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})\s([\<|\>])\s([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}):.*/",$logent,$log_split); + + $logent = strtoupper($logent); + + $do_not_display = false; + if(stristr($logent, "UDP") == true) + $flent['proto'] = "UDP"; + else if(stristr($logent, "TCP") == true) + $flent['proto'] = "TCP"; + else if(stristr($logent, "ICMP") == true) + $flent['proto'] = "ICMP"; + else if(stristr($logent, "HSRP") == true) + $flent['proto'] = "HSRP"; + else if(stristr($logent, "ESP") == true) + $flent['proto'] = "ESP"; + else if(stristr($logent, "AH") == true) + $flent['proto'] = "AH"; + else if(stristr($logent, "GRE") == true) + $flent['proto'] = "GRE"; + else if(stristr($logent, "IGMP") == true) + $flent['proto'] = "IGMP"; + else if(stristr($logent, "CARP") == true) + $flent['proto'] = "CARP"; + else if(stristr($logent, "PFSYNC") == true) + $flent['proto'] = "PFSYNC"; + else + $do_not_display = true; + + $flent['time'] = $log_split[1]; + $flent['act'] = $log_split[4]; + $flent['interface'] = strtoupper(convert_real_interface_to_friendly_interface_name(str_replace(":","",$log_split[5]))); + + if($flent['proto'] == "TCP" or $flent['proto'] == "UDP") { + $flent['src'] = convert_port_period_to_colon($log_split[6]); + $flent['dst'] = convert_port_period_to_colon($log_split[8]); + } else { + $flent['src'] = $log_split[6]; + $flent['dst'] = $log_split[8]; + } + + $tmp = split("/", $log_split[3]); + $flent['rulenum'] = $tmp[0]; + + if($flent['src'] == "" or $flent['dst'] == "" or $do_not_display == true) { + /* do not display me! */ + } else { + $counter++; + $filterlog[] = $flent; + } + + } + + return $filterlog; +} + +function convert_port_period_to_colon($addr) { + $addr_split = split("\.", $addr); + if($addr_split[4] == "") + $newvar = $addr_split[0] . "." . $addr_split[1] . "." . $addr_split[2] . "." . $addr_split[3]; + else + $newvar = $addr_split[0] . "." . $addr_split[1] . "." . $addr_split[2] . "." . $addr_split[3] . ":" . $addr_split[4]; + if($newvar == "...") + return $addr; + return $newvar; +} + +function format_ipf_ip($ipfip) { + list($ip,$port) = explode(",", $ipfip); + if (!$port) + return $ip; + + return $ip . ", port " . $port; +} + +$filterlog = conv_clog($filter_logfile, $nentries); + +$pgtitle = "Diagnostics: System logs: Firewall"; +include("head.inc"); + +?> +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<?php include("fbegin.inc"); ?> +<script src="/javascript/scriptaculous/prototype.js" type="text/javascript"></script> +<script src="/javascript/scriptaculous/scriptaculous.js" type="text/javascript"></script> +<script language="javascript"> + lastsawtime = '<?php echo time(); ?>;'; + var lines = Array(); + var timer; + var updateDelay = 4000; + var isBusy = false; + var isPaused = false; +<?php + if(isset($config['syslog']['reverse'])) + echo " var isReverse = true;\n"; + else + echo " var isReverse = false;\n"; +?> +</script> +<br> +<table width="100%"> + <tr> + <td> + <div class="pgtitle"><?=$pgtitle?></div> + </td> + <td align="right"> + Pause:<input valign="middle" type="checkbox" onClick="javascript:toggle_pause();"> + </td> + </tr> +</table> +<br> +<table width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr><td> +<?php + $tab_array = array(); + $tab_array[] = array("System", false, "diag_logs.php"); + $tab_array[] = array("Firewall", true, "diag_logs_filter.php"); + $tab_array[] = array("DHCP", false, "diag_logs_dhcp.php"); + $tab_array[] = array("Portal Auth", false, "diag_logs_auth.php"); + $tab_array[] = array("IPSEC VPN", false, "diag_logs_ipsec.php"); + $tab_array[] = array("PPTP VPN", false, "diag_logs_vpn.php"); + $tab_array[] = array("Load Balance", false, "diag_logs_slbd.php"); + $tab_array[] = array("Settings", false, "diag_logs_settings.php"); + display_top_tabs($tab_array); +?> + </td></tr> + <tr> + <td> + <div id="mainarea"> + <div id="log"> + <div class="listtopic"> + Last <?php echo $nentries; ?> records + </div> + <div class="log-header"> + <span class="log-action">Act</span> + <span class="log-time">Time</span> + <span class="log-interface">If</span> + <span class="log-source">Source</span> + <span class="log-destination">Destination</span> + <span class="log-protocol">Proto</span> + </div> + <?php $counter=0; foreach ($filterlog as $filterent): ?> + <?php + if(isset($config['syslog']['reverse'])) { + /* honour reverse logging setting */ + if($counter == 0) + $activerow = " id=\"firstrow\""; + else + $activerow = ""; + + } else { + /* non-reverse logging */ + if($counter == count($filterlog)) + $activerow = " id=\"firstrow\""; + else + $activerow = ""; + } + ?> + <div class="log-entry" <?php echo $activerow; ?>> + <span class="log-action" nowrap><a href="#" onClick="javascript:getURL('diag_logs_filter.php?getrulenum=<?php echo $filterent['rulenum']; ?>', outputrule);"> + <?php + if (strstr(strtolower($filterent['act']), "p")) + $img = "/themes/metallic/images/icons/icon_pass.gif"; + else if(strstr(strtolower($filterent['act']), "r")) + $img = "/themes/metallic/images/icons/icon_reject.gif"; + else + $img = "/themes/metallic/images/icons/icon_block.gif"; + ?> + <img border="0" src="<?=$img;?>" width="11" height="11" align="absmiddle"></a></span> + <span class="log-time" ><?=htmlspecialchars($filterent['time']);?></span> + <span class="log-interface" ><?=htmlspecialchars(convert_real_interface_to_friendly_interface_name($filterent['interface']));?></span> + <span class="log-source" ><?=htmlspecialchars($filterent['src']);?></span> + <span class="log-destination" ><?=htmlspecialchars($filterent['dst']);?></span> + <span class="log-protocol" ><?=htmlspecialchars($filterent['proto']);?></span> + </div> + <?php $counter++; endforeach; ?> + </div> + </div> + </td> + </tr> +</table> +<script language="javascript"> +if (typeof getURL == 'undefined') { + getURL = function(url, callback) { + if (!url) + throw 'No URL for getURL'; + try { + if (typeof callback.operationComplete == 'function') + callback = callback.operationComplete; + } catch (e) {} + if (typeof callback != 'function') + throw 'No callback function for getURL'; + var http_request = null; + if (typeof XMLHttpRequest != 'undefined') { + http_request = new XMLHttpRequest(); + } + else if (typeof ActiveXObject != 'undefined') { + try { + http_request = new ActiveXObject('Msxml2.XMLHTTP'); + } catch (e) { + try { + http_request = new ActiveXObject('Microsoft.XMLHTTP'); + } catch (e) {} + } + } + if (!http_request) + throw 'Both getURL and XMLHttpRequest are undefined'; + http_request.onreadystatechange = function() { + if (http_request.readyState == 4) { + callback( { success : true, + content : http_request.responseText, + contentType : http_request.getResponseHeader("Content-Type") } ); + } + } + http_request.open('GET', url, true); + http_request.send(null); + } +} + +function outputrule(req) { + alert(req.content); +} +function fetch_new_rules() { + if(isPaused) + return; + if(isBusy) + return; + isBusy = true; + getURL('diag_logs_filter_dynamic.php?lastsawtime=' + lastsawtime, fetch_new_rules_callback); +} +function fetch_new_rules_callback(callback_data) { + if(isPaused) + return; + var data_split; + var new_data_to_add = Array(); + var data = callback_data.content; + data_split = data.split("\n"); + for(var x=0; x<data_split.length-1; x++) { + /* loop through rows */ + row_split = data_split[x].split("||"); + var line = ''; + line = '<div class="log-entry">'; + line += ' <span class="log-action" nowrap>' + row_split[0] + '</span>'; + line += ' <span class="log-time" nowrap>' + row_split[1] + '</span>'; + line += ' <span class="log-interface" nowrap>' + row_split[2] + '</span>'; + line += ' <span class="log-source" nowrap>' + row_split[3] + '</span>'; + line += ' <span class="log-destination" nowrap>' + row_split[4] + '</span>'; + line += ' <span class="log-protocol" nowrap>' + row_split[5] + '</span>'; + line += '</div>'; + lastsawtime = row_split[6]; + new_data_to_add[new_data_to_add.length] = line; + } + update_div_rows(new_data_to_add); + isBusy = false; +} +function update_div_rows(data) { + if(isPaused) + return; + var isIE = navigator.appName.indexOf('Microsoft') != -1; + var isSafari = navigator.userAgent.indexOf('Safari') != -1; + var isOpera = navigator.userAgent.indexOf('Opera') != -1; + var rulestable = document.getElementById('log'); + var rows = rulestable.getElementsByTagName('div'); + var showanim = 1; + if (isIE) { + showanim = 0; + } + for(var x=1; x<data.length; x++) { + var numrows = rows.length; + /* if reverse logging is enabled we need to show the + * records in a reverse order with new items appearing + * on the top + */ + if(isReverse == false) { + for (var i = numrows-1; i > 1; i--) { + rows[i].innerHTML = rows[i-1].innerHTML; + } + } else { + for (var i = 1; i < numrows+1; i++) { + rows[i].innerHTML = rows[i-1].innerHTML; + } + } + var item = document.getElementById('firstrow'); + if (showanim) { + rows[1].style.display = 'none'; + rows[1].innerHTML = data[x]; + new Effect.Appear(item); + } else { + rows[1].innerHTML = data[x]; + } + } + /* rechedule AJAX interval */ + timer = setInterval('fetch_new_rules()', updateDelay); +} +function toggle_pause() { + if(isPaused) { + isPaused = false; + fetch_new_rules(); + } else { + isPaused = true; + } +} +/* start local AJAX engine */ +lastsawtime = '<?php echo time(); ?>;'; +timer = setInterval('fetch_new_rules()', updateDelay); +</script> +<?php include("fend.inc"); ?> +</body> +</html> +<?php + +/* AJAX specific handlers */ +function handle_ajax() { + if($_GET['getrulenum'] or $_POST['getrulenum']) { + if($_GET['getrulenum']) + $rulenum = $_GET['getrulenum']; + if($_POST['getrulenum']) + $rulenum = $_POST['getrulenum']; + $rule = `pfctl -vvsr | grep @{$rulenum}`; + echo "The rule that triggered this action is:\n\n{$rule}"; + exit; + } + + if($_GET['lastsawtime'] or $_POST['lastsawtime']) { + global $filter_logfile,$filterent; + if($_GET['lastsawtime']) + $lastsawtime = $_GET['lastsawtime']; + if($_POST['lastsawtime']) + $lastsawtime = $_POST['lastsawtime']; + /* compare lastsawrule's time stamp to filter logs. + * afterwards return the newer records so that client + * can update AJAX interface screen. + */ + $new_rules = ""; + $filterlog = conv_clog($filter_logfile, 50); + foreach($filterlog as $log_row) { + $time_regex = ""; + preg_match("/.*([0-9][0-9]:[0-9][0-9]:[0-9][0-9])/", $log_row['time'], $time_regex); + $row_time = strtotime($time_regex[1]); + if (strstr(strtolower($log_row['act']), "p")) + $img = "<img border='0' src='/themes/metallic/images/icons/icon_pass.gif'>"; + else if(strstr(strtolower($filterent['act']), "r")) + $img = "<img border='0' src='/themes/metallic/images/icons/icon_reject.gif'>"; + else + $img = "<img border='0' src='/themes/metallic/images/icons/icon_block.gif'>"; + //echo "{$time_regex[1]} - $row_time > $lastsawtime<p>"; + if($row_time > $lastsawtime) + $new_rules .= "{$img}||{$log_row['time']}||{$log_row['interface']}||{$log_row['src']}||{$log_row['dst']}||{$log_row['proto']}||" . time() . "||\n"; + } + echo $new_rules; + exit; + } +} + +?>
\ No newline at end of file diff --git a/usr/local/www/themes/metallic/all.css b/usr/local/www/themes/metallic/all.css index ac439e7..558d0ed 100644 --- a/usr/local/www/themes/metallic/all.css +++ b/usr/local/www/themes/metallic/all.css @@ -4,6 +4,16 @@ html, body, td, th, input, select { font-size: 0.9em; } +div.GraphLink { + position: relative; +} + +span.GraphLinkLine { + position: absolute; + background-color: #990000; + width: 100%; +} + body { background-color: #333333; margin: 5px auto; @@ -34,7 +44,7 @@ iframe { } #header { - background: url('images/header.gif') no-repeat; + background: url('/themes/metallic/images/header.gif') no-repeat; background-position: 4px; height: 102px; width: 808px; @@ -43,7 +53,7 @@ iframe { } #header-left { position: relative; - /* background: url('images/logo.gif') no-repeat; */ + /* background: url('/themes/metallic/images/logo.gif') no-repeat; */ background-position: center; height: 65px; width: 145px; @@ -57,7 +67,7 @@ iframe { } #header-right { position: relative; - /* background: url('images/header.gif') no-repeat; */ + /* background: url('/themes/metallic/images/header.gif') no-repeat; */ height: 70px; color: #fff; left: 0px; @@ -65,7 +75,7 @@ iframe { } #header-right .alert { position: relative; - /* background: url('images/alert.gif') no-repeat; */ + /* background: url('/themes/metallic/images/alert.gif') no-repeat; */ background-position: 4px 2px; color: #fff; height: 17px; @@ -89,34 +99,32 @@ iframe { #header-right .container .right { position: relative; float: right; - top: 22px; + top: 10px; padding-right: 4px; z-index: 1; } -#header-right .container .right #alerts { +#header-right .container .right #marquee-text { + background: url('/themes/metallic/images/misc/status_alerter.gif') no-repeat; + margin: 0px; +} +#header-right .container .right #ajaxstatusbar { position: relative; - background: url('images/alert_bgr.gif') no-repeat; - height: 39px; + height: 13px; width: 431px; z-index: 1; - padding-top: 20px; - padding-left: 5px; margin: 0px; +text-align: right; } #header-right .container .right #hostname { position: relative; - height: 39px; - width: 431px; + height: 13px; z-index: 1; - padding-left: 5px; margin: 0px; - top: 25px; - left: 230px; +top: 25px; +text-align: right; } - - table#marquee { position: relative; top: -6px; @@ -164,7 +172,7 @@ table#marquee div#container div#scroller { margin-left: 5px; padding-top: 0px; width: 800px; - background: url('images/horizontal.gif') repeat-y; + background: url('/themes/metallic/images/horizontal.gif') repeat-y; } #left { @@ -187,15 +195,15 @@ table#marquee div#container div#scroller { #footer { position: relative; - background: url('images/footer.gif') no-repeat; + background: url('/themes/metallic/images/footer.gif') no-repeat; top: -18px; left: 7px; width: 800px; height: 75px; color: #ffffff; text-align: center;; - font-size: 0.9em; - padding-top: 17px; + font-size: 0.7em; + padding-top: 10px; margin-bottom: 20px; clear: both; } @@ -720,3 +728,69 @@ div.suggestions div.current { .r4,.rl4,.rr4,.re4,.rel4,.rer4,.ra4,.rar4,.ral4,.rx4,.rxl4,.rxr4{height:2px} .rer1,.rel1,.re1,.res1,.resl1,.resr1{border-width:1px 0 0;height:0px !important;height /**/:1px} /* End Nifty Corners Crap */ + + + +/* CSS for Dynamic Log Viewer */ +/* Author: Erik Kristensen */ +div#log div.log-entry { + clear: both; +} + +div#log div.log-entry span, +div#log div.log-header span { + padding: 3px 2px 3px 2px; + padding-left: 8px; +} + +div#log div.log-entry span.log-action { + padding-bottom: 6px; + padding-left: 5px; + padding-right: 5px; +} + +div#log div.log-header span { + border-top: 1px solid #999; + background-color: #bbb; + font-weight: bold; + text-align: left; +} + +div#log span.log-action, +div#log span.log-time, +div#log span.log-interface, +div#log span.log-source, +div#log span.log-destination, +div#log span.log-protocol { + float: left; + text-align: left; + border-left: 1px solid #999; + border-bottom: 1px solid #999; +} + +div#log span.log-protocol { + border-right: 1px solid #999; +} + +div#log span.log-action { + width: 2em; + text-align: center; +} + +div#log span.log-time { + width: 12.5em; +} + +div#log span.log-interface { + width: 5em; +} + +div#log span.log-source, +div#log span.log-destination { + width: 17.6em; +} + +div#log span.log-protocol { + width: 5.5em; +} +/* END CSS FOR DYNAMIC LOG VIEWER */ |