mirror of
https://github.com/myvesta/vesta
synced 2025-07-06 04:51:54 -07:00
Merge pull request #175 from VasilisParaschos/174-banned-ip-quick-info
Get quick info about a banned IP (Host, Banlist, Location)
This commit is contained in:
commit
5acdfb6158
5 changed files with 231 additions and 1 deletions
26
web/css/styles.min.css
vendored
26
web/css/styles.min.css
vendored
|
@ -4236,3 +4236,29 @@ div.ui-dialog + div div{
|
||||||
padding: 5px 10px !important;
|
padding: 5px 10px !important;
|
||||||
border-radius: 13px;
|
border-radius: 13px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.get-ip-info-btn {
|
||||||
|
cursor: pointer;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
.get-ip-info-btn:hover {
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
.get-ip-info-btn + .get-ip-info-result {
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
.get-ip-info-btn + .get-ip-info-result dl dt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.get-ip-info-btn + .get-ip-info-result dl dd {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
}
|
||||||
|
.get-ip-info-btn + .get-ip-info-result dl .fa-exclamation-triangle {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
.get-ip-info-btn + .get-ip-info-result dl .fa-check-circle {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
.get-ip-info-btn + .get-ip-info-result dl .fa-exclamation-circle {
|
||||||
|
color: orange;
|
||||||
|
}
|
||||||
|
|
|
@ -377,6 +377,7 @@ $LANG['en'] = array(
|
||||||
'ErrorLog' => 'ErrorLog',
|
'ErrorLog' => 'ErrorLog',
|
||||||
'Download AccessLog' => 'Download AccessLog',
|
'Download AccessLog' => 'Download AccessLog',
|
||||||
'Download ErrorLog' => 'Download ErrorLog',
|
'Download ErrorLog' => 'Download ErrorLog',
|
||||||
|
'Continent' => 'Continent',
|
||||||
'Country' => 'Country',
|
'Country' => 'Country',
|
||||||
'2 letter code' => '2 letter code',
|
'2 letter code' => '2 letter code',
|
||||||
'State / Province' => 'State / Province',
|
'State / Province' => 'State / Province',
|
||||||
|
|
|
@ -1072,3 +1072,42 @@ function elementHideShow(elementToHideOrShow){
|
||||||
el.style.display = el.style.display === 'none' ? 'block' : 'none';
|
el.style.display = el.style.display === 'none' ? 'block' : 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(function($) {
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('.get-ip-info-btn').click(function() {
|
||||||
|
var token = $('#token').attr('token');
|
||||||
|
var index = $(this).attr('data-index');
|
||||||
|
var btn_el = $('.get-ip-info-btn[data-index="' + index + '"]');
|
||||||
|
var result_el = $('.get-ip-info-btn[data-index="' + index + '"] + .get-ip-info-result');
|
||||||
|
var ip = btn_el.attr('data-ip');
|
||||||
|
|
||||||
|
var url_params = new URLSearchParams(window.location.search);
|
||||||
|
var clear_cache = url_params.get('clear_cache');
|
||||||
|
|
||||||
|
if (!$.trim(result_el.html())) {
|
||||||
|
result_el.html('<i class="fas fa-spin fa-2x fa-spinner"></i>');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
method: "POST",
|
||||||
|
url: "/list/firewall/banlist/ip_info.php",
|
||||||
|
data: { ip: ip, clear_cache: clear_cache, token: token },
|
||||||
|
cache: false,
|
||||||
|
error: function(jqXHR, textStatus, errorThrown) {
|
||||||
|
result_el.html('<strong>GENERAL ERROR</strong><br>' + errorThrown);
|
||||||
|
},
|
||||||
|
success: function(result_data) {
|
||||||
|
if (btn_el.find('i').hasClass('fa-times')) {
|
||||||
|
result_el.html(result_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
btn_el.find('i').removeClass('fa-search').addClass('fa-times');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result_el.html('');
|
||||||
|
btn_el.find('i').removeClass('fa-times').addClass('fa-search');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})(jQuery);
|
||||||
|
|
164
web/list/firewall/banlist/ip_info.php
Normal file
164
web/list/firewall/banlist/ip_info.php
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
<?
|
||||||
|
error_reporting(NULL);
|
||||||
|
session_start();
|
||||||
|
|
||||||
|
include($_SERVER['DOCUMENT_ROOT']."/inc/main.php");
|
||||||
|
|
||||||
|
if (!function_exists('str_contains')) {
|
||||||
|
function str_contains($haystack, $needle)
|
||||||
|
{
|
||||||
|
return $needle !== '' && mb_strpos($haystack, $needle) !== false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// cidrMatch() based on https://stackoverflow.com/a/14535823
|
||||||
|
function cidrMatch($ip, $range)
|
||||||
|
{
|
||||||
|
if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) return false;
|
||||||
|
list($subnet, $bits) = explode('/', $range);
|
||||||
|
$ip = substr(ipToBinary($ip), 0, $bits);
|
||||||
|
$subnet = substr(ipToBinary($subnet), 0, $bits);
|
||||||
|
return ($ip == $subnet);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ipToBinary based on https://stackoverflow.com/a/14535823
|
||||||
|
function ipToBinary($ip)
|
||||||
|
{
|
||||||
|
$ipbin = '';
|
||||||
|
$ips = explode(".", $ip);
|
||||||
|
foreach ($ips as $iptmp) {
|
||||||
|
$ipbin .= sprintf("%08b", $iptmp);
|
||||||
|
}
|
||||||
|
return $ipbin;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchURL($url, &$info = [])
|
||||||
|
{
|
||||||
|
$curl_handle = curl_init();
|
||||||
|
curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, true);
|
||||||
|
curl_setopt($curl_handle, CURLOPT_ENCODING, 'gzip, deflate');
|
||||||
|
curl_setopt($curl_handle, CURLOPT_URL, $url);
|
||||||
|
curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 10);
|
||||||
|
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
|
||||||
|
$data = curl_exec($curl_handle);
|
||||||
|
$info = curl_getinfo($curl_handle);
|
||||||
|
curl_close($curl_handle);
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseCacheEntries($strEntries)
|
||||||
|
{
|
||||||
|
$parsed = [];
|
||||||
|
$entries = explode("\n", $strEntries);
|
||||||
|
if ($entries) {
|
||||||
|
foreach ($entries as $entry) {
|
||||||
|
list($entry,) = explode("#", $entry);
|
||||||
|
list($entry,) = explode(";", $entry);
|
||||||
|
$entry = trim($entry);
|
||||||
|
if (!empty($entry)) $parsed[] = $entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $parsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkIP($ip)
|
||||||
|
{
|
||||||
|
$check_results = [];
|
||||||
|
$lists = [
|
||||||
|
'BDEALL' => 'http://lists.blocklist.de/lists/all.txt',
|
||||||
|
'BFB' => 'http://danger.rulez.sk/projects/bruteforceblocker/blist.php',
|
||||||
|
'CIARMY' => 'http://www.ciarmy.com/list/ci-badguys.txt',
|
||||||
|
'GREENSNOW' => 'https://blocklist.greensnow.co/greensnow.txt',
|
||||||
|
'SPAMDROP' => 'https://www.spamhaus.org/drop/drop.txt',
|
||||||
|
'SPAMEDROP' => 'https://www.spamhaus.org/drop/edrop.txt',
|
||||||
|
'TOR' => 'https://check.torproject.org/cgi-bin/TorBulkExitList.py',
|
||||||
|
];
|
||||||
|
$today = date('Y-m-d');
|
||||||
|
|
||||||
|
foreach ($lists as $code => $url) {
|
||||||
|
$cache_tag = 'ip-blacklist-' . $code . '-cache';
|
||||||
|
|
||||||
|
// init cache
|
||||||
|
if (!isset($_SESSION[$cache_tag])) $_SESSION[$cache_tag] = ['updated' => '', 'items' => [], 'http_code' => ''];
|
||||||
|
|
||||||
|
// invalidate cache if clear_cache parameter is 1
|
||||||
|
if (!empty($_REQUEST['clear_cache']) && $_REQUEST['clear_cache'] == 1) $_SESSION[$cache_tag]['updated'] = '2000-01-01';
|
||||||
|
|
||||||
|
// if cache is not updated, fetch new data and save to cache
|
||||||
|
if (strtotime($today) > strtotime($_SESSION[$cache_tag]['updated'])) {
|
||||||
|
$new_cache_data = fetchURL($url, $url_result);
|
||||||
|
if ($url_result['http_code'] == '200') $new_cache_items = parseCacheEntries($new_cache_data);
|
||||||
|
$_SESSION[$cache_tag] = ['updated' => $today, 'items' => $new_cache_items, 'http_code' => $url_result['http_code']];
|
||||||
|
}
|
||||||
|
|
||||||
|
// check ip
|
||||||
|
$matched_ips = array_filter($_SESSION[$cache_tag]['items'], function ($item) use ($ip) {
|
||||||
|
if (str_contains($item, '/')) return cidrMatch($ip, $item);
|
||||||
|
if ($ip == $item) return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$check_results[$code]['found'] = count($matched_ips) > 0 ? true : false;
|
||||||
|
$check_results[$code]['updated'] = $_SESSION[$cache_tag]['updated'];
|
||||||
|
$check_results[$code]['http_code'] = $_SESSION[$cache_tag]['http_code'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $check_results;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check token
|
||||||
|
if ((!isset($_REQUEST['token'])) || ($_SESSION['token'] != $_REQUEST['token'])) {
|
||||||
|
die("Wrong token");
|
||||||
|
}
|
||||||
|
|
||||||
|
$ip = $_REQUEST['ip'];
|
||||||
|
|
||||||
|
// Validate IP format
|
||||||
|
if (filter_var($ip, FILTER_VALIDATE_IP) === false) {
|
||||||
|
die('<strong>GENERAL ERROR</strong><br>BAD_IP_FORMAT');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query host
|
||||||
|
$host = gethostbyaddr($ip);
|
||||||
|
|
||||||
|
// Query blocklists
|
||||||
|
$result_blocklists = '';
|
||||||
|
$ip_check = checkIP($ip);
|
||||||
|
if ($ip_check) {
|
||||||
|
foreach ($ip_check as $list_code => $list_results) {
|
||||||
|
$result_blocklists .= '<div title="'.$list_results['updated'].' / '.$list_results['http_code'].'">';
|
||||||
|
$result_blocklists .= $list_results['found'] ? '<i class="fas fa-fw fa-exclamation-triangle"></i>' : '<i class="fas fa-fw fa-check-circle"></i>';
|
||||||
|
$result_blocklists .= ' <span>'.$list_code.'</span> ';
|
||||||
|
$result_blocklists .= $list_results['http_code'] == '200' ? '' : '<i class="fas fa-fw fa-exclamation-circle"></i>';
|
||||||
|
$result_blocklists .= '</div>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query location
|
||||||
|
$url = 'https://api.db-ip.com/v2/free/'.$ip;
|
||||||
|
$result = fetchURL($url);
|
||||||
|
$result_array = json_decode($result, true);
|
||||||
|
if (!is_array($result_array)) {
|
||||||
|
die('<strong>GENERAL ERROR</strong><br>BAD_JSON');
|
||||||
|
}
|
||||||
|
if (!empty($result_array['errorCode'])) {
|
||||||
|
die('<strong>GENERAL ERROR</strong><br>'.$result_array['errorCode']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output
|
||||||
|
echo "
|
||||||
|
<dl>
|
||||||
|
<dt>".__('Host')."</dt>
|
||||||
|
<dd>".$host."</dd>
|
||||||
|
<dt>".__('Banlist')."</dt>
|
||||||
|
<dd>".$result_blocklists."</dd>
|
||||||
|
<dt>".__('Continent')."</dt>
|
||||||
|
<dd>".$result_array['continentName']." [".$result_array['continentCode']."]</dd>
|
||||||
|
<dt>".__('Country')."</dt>
|
||||||
|
<dd>".$result_array['countryName']." [".$result_array['countryCode']."]</dd>
|
||||||
|
<dt>".__('State / Province')."</dt>
|
||||||
|
<dd>".$result_array['stateProv']." [".$result_array['stateProvCode']."]</dd>
|
||||||
|
<dt>".__('City / Locality')."</dt>
|
||||||
|
<dd>".$result_array['city']."</dd>
|
||||||
|
</dl>
|
||||||
|
";
|
|
@ -80,7 +80,7 @@
|
||||||
<div class="clearfix l-unit__stat-col--left wide"><b><?=$data[$key]['DATE']?></b> <?=$data[$key]['TIME']?> </div>
|
<div class="clearfix l-unit__stat-col--left wide"><b><?=$data[$key]['DATE']?></b> <?=$data[$key]['TIME']?> </div>
|
||||||
<div class="clearfix l-unit__stat-col--left"></div>
|
<div class="clearfix l-unit__stat-col--left"></div>
|
||||||
<div class="clearfix l-unit__stat-col--left wide-3"><b><?=__($value['CHAIN'])?></b></div>
|
<div class="clearfix l-unit__stat-col--left wide-3"><b><?=__($value['CHAIN'])?></b></div>
|
||||||
<div class="clearfix l-unit__stat-col--left"><b><?=$ip?></b></div>
|
<div class="clearfix l-unit__stat-col--left"><b><?=$ip?></b><a class="get-ip-info-btn" data-index="<?=$i?>" data-ip="<?=$ip?>"><i class="fas fa-search"></i></a><div class="get-ip-info-result"></div></div>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.l-unit__stats -->
|
<!-- /.l-unit__stats -->
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue