Source VPN Autoban

Source code of specific applications

Janno

why let your life be controlled by fairytales
This source code was available back before the burndown as well, figured I'll start sharing some again.

For out-of-box usage, you need to be using q3panel, as the autoban application is linked with it.

Prerequisites:
IPHub account and an API key.
an SQL server, if q3panel is used, then mySQL or MariaDB.
2 tables called q3panel_allowed_ips and q3panel_banned_ips (specification below)

Allowed IPs table can act as a whitelist as well (as that is queried first, so if an IP exists there, it won't be checked further).

The code can be slightly messy as this was thrown together fast.

If you have any other autoban-specific questions, address them here.

Table spec:

SQL:
CREATE TABLE q3panel_allowed_ips (
    allowed_ip_id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY
    , ip_address VARCHAR(15)
    , blocklevel TINYINT DEFAULT 0 COMMENT '0 - allowed ip, 1 - blocked (but whitelisted IP)'
    , name VARCHAR(255) COMMENT 'player name'
);

CREATE TABLE q3panel_banned_ips (
    banned_ip_id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY
    , ip_address VARCHAR(15)
    , name VARCHAR(255) COMMENT 'player name'
    , server_id INTEGER
);

Script:
PHP:
<?php

$d = __DIR__;
require_once "$d/classes/sql/SQL.php";
require_once "$d/config.php";
require_once "$d/classes/Constants.php";
require_once "$d/classes/ssh/SSH.php";
require_once "$d/classes/servers/host/Host.php";
require_once "$d/classes/servers/Game.php";
require_once "$d/classes/servers/Server.php";
require_once "$d/classes/logger/Logger.php";
require_once "$d/classes/email/Email.php";
require_once "$d/classes/users/User.php";



$servers = Server::getRunningServers($sql);
$ips = array();
$srv = null;
foreach ($servers as $server) {
    if (intval($server['server_id']) !== 2) { //in our q3panel, server_id 2 is 3D H&S
        continue;
    }
    $host = new Host($server['host_id'], $server['servername'], $server['hostname'], $server['sshport'], $server['host_username'], $server['host_password']);
    $game = new Game($server['game_id'], $server['game_name'], $server['game_location'], $server['startscript']);
    $srv = new Server($server['server_id'], $host, $server['server_name'], $game, $server['server_port'], $server['server_account'], $server['server_password'], $server['server_status'], $server['server_startscript'], $server['current_players'], $server['max_players'], $server['rconpassword']);
    $str = $srv->sendQ3Command(Constants::$SERVER_ACTIONS['Q3_RCON_COMMAND'] . "status", true, true);
    $str = str_replace("\xFF\xFF\xFF\xFFprint\n", "", $str);
    $str = str_replace("\xFF\xFF\xFF\xFFprint", "", $str);
    $arr = explode("\n", $str);
    $players = false;
    foreach ($arr as $val) {
        if (strlen(trim($val)) === 0) {
            continue;
        }
        if (trim($val) === "--- ----- ---- --------------- ------- --------------------- ----- -----") {
            $players = true;
            continue;
        }
        if ($players) {
            $tt = preg_replace("!\s+!", " ", $val);
            $array = explode(" ", $tt);
            $id = intval($array[1]);
            $name = stripQ3Colors($array[4]);
            $last = "";
            $writeName = false;
            foreach ($array as $value) {
               
                if (stripQ3Colors($value) === $name) {
                    $writeName = true;
                    continue;
                }
               
                $value = trim($value);
                $arr22 = explode(":", $value);
                $chkIp = $arr22[0];
                if ($out = filter_var($chkIp, FILTER_VALIDATE_IP)) {
                    $writeName = false;
                    $ips[] = array("ip" => $out, "id" => $id, "name" => $name);
                    continue;
                }
                if ($writeName) {
                    $name .= stripQ3Colors($last);
                    $last = " $value";
                }
            }
        }
       
    }
   
}


$api_key = ""; //HERE YOU WILL NEED TO ENTER YOUR OWN IPHUB API KEY
if (!is_array($ips) || sizeof($ips) === 0) {
    die();
}
foreach ($ips as $arr) {
    $ip = $arr['ip'];
    $name = $arr['name'];
    $id = $arr['id'];
    if (trim($ip) === "") {
        break;
    }
    $query = "SELECT * FROM q3panel_banned_ips WHERE ip_address = ?";
    $params = array($ip);
    $dat = $sql->query($query, $params);
    if (sizeof($dat) !== 0) {
        $sqlId = $dat[0]['banned_ip_id'];
        sleep(0.5);
        $output = $srv->sendQ3Command(Constants::$SERVER_ACTIONS['Q3_RCON_COMMAND'] . "ban $id ID-$sqlId-VPN_Autoban", true, true);
        continue;
    }
    $query = "SELECT * FROM q3panel_allowed_ips WHERE ip_address = ?";
    $dat = $sql->query($query, $params);
    if (sizeof($dat) !== 0) {
//echo "ip $ip allowed";
      continue;
    }
    $ch = curl_init("http://v2.api.iphub.info/ip/" . trim($ip));
    curl_setopt_array($ch, array(
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => array("X-Key: $api_key")
    ));
    $ret = curl_exec($ch);
//print_r($ret);
    $jsonarr = json_decode($ret, true);
    $query = "";
    if (intval($jsonarr['block']) === 1) {
        $query = "INSERT INTO q3panel_banned_ips (name, ip_address, server_id) VALUES (?, ?, 2)";
        $params = array($name, $ip);
        $dat = $sql->query($query, $params);
        //echo Constants::$SERVER_ACTIONS['Q3_RCON_COMMAND'] . "ban $id ID-" . $dat['last_insert_id'] . "-VPN_Autoban";
        sleep(0.5);
        $output = $srv->sendQ3Command(Constants::$SERVER_ACTIONS['Q3_RCON_COMMAND'] . "ban $id ID-" . $dat['last_insert_id'] . "-VPN_Autoban", true, true);
       
    } else {
        $query = "INSERT INTO q3panel_allowed_ips (ip_address, blocklevel, name) VALUES (?, ?, ?)";
        $params = array($ip, $jsonarr['block'], $name);
        $sql->query($query, $params);
    }
}


function stripQ3Colors($input) {
    return preg_replace("/(\^.)/", "", $input);
}
 
Last edited:
Nice release there man!

Just a small tip from me, since you started to fiddle around with 1fxmod, maybe it would be better to implement this in the mod itself. This is what i have done with my mod. It gives you more control.
 
As a matter of fact, we haven't ran VPN autoban for almost a year now as we sent the message and got rid of the "trash" hhhhh. But if I do see the need in the future, I think it's a good idea.
 
Back
Top