HOW TO GET THE MOST OUT OF THE VELODATA BLACKHOLE SOFTWARE
Velodata Configuration Examples
Got some questions? By all means, contact us. Your privacy is paramount. We never share customer data with ANYONE.
Everyone is welcome to use the Velodata Cyber Security System for WordPress. It’s super fast, incredibly effective, and it’s free!
Download
Standalone PHP version, last updated: 2021/12/25
The standalone PHP version of Velodata’s Blackhole Cyber Security system contains four files: The only file you need to edit in any way is the configuration file, blackhole.ini
- .htaccess
- blackhole.php
- blackhole.ini
- blackhole.dat
- blackhole.css
The following example is our own blackhole.ini file which protects the Velodata website, with critical fields changed for privacy reasons. This particular example of blackhole.ini has every function turned on. Note the fields being used to create a Trusted Ring of IP Addresses.
## Miscellaneous Flags section
## Please Note: Set each category to equal NO if you don't want that category to activate
## dynamic "real time" banning at your IPTABLES Firewall level and/or the Cloudflare API
## If you accidentally delete any of these lines, fear not. The
## Blackhole software automatically creates these variables to equal 'NO' by default.
## Refer to the Fine Tuning Guide on the velodata.org website to get a complete explanation
## of how these options work.
PARD_BAN_UNAUTHORISED_POST_REQUESTS = "YES"
PARD_BAN_UNAUTHORISED_SPIDERBOTS = "YES"
PARD_BAN_UNAUTHORISED_PHP_REQUESTS = 'YES'
PARD_BAN_UNAUTHORISED_URI_REQUESTS = 'YES'
## Blackhole Email Notification Parameters
## Please Note: This section defines if you would like to receive emails when the Velodata Blackhole system bans a malicious IP address. Your webserver must be able to send outbound emails obviously.
##
## The field PARD_ARE_WE_SENDING_NOTIFICATIONS determines if Ban Notification emails are going to be sent to your email system.
## The field PARD_EMAIL_NOTIFICATION_ADDRESS determins where Ban Notification emails are going to be sent.
## The field PARD_EMAIL_REPLY_ADDRESS specifies the Contact email address when you give 'explanation feedback' to a Banned Malicious IP Address
## The field PARD_ARE_WE_PROVIDING_FEEDBACK determines if you give 'explanation feedback' to a Banned Malicious IP Address
##
##
PARD_ARE_WE_SENDING_NOTIFICATIONS = 'YES'
PARD_EMAIL_NOTIFICATION_ADDRESS = "webmaster@your_website"
PARD_ARE_WE_PROVIDING_FEEDBACK = "NO"
PARD_EMAIL_REPLY_ADDRESS = "reply_address@your_website"
## Blackhole Self Learning Algorithm
## Please Note: This function requires a plugin called Redirection. If you load the Redirection plugin you need to turn on 404 logging. Choose the setting which keeps 404 log files forever.
## And that's it, that's all you have to do regarding the plugin. It's a plug in which does other cool things too, but in the context of the Blackhole system, 404 logging is all we need.
## However, you also have to correctly fill in the four PARD_DB fields shown below too, this is so the Blackhole software can cross check the 404 log file to help fight DDOS attacks.
## To turn off the Self Learning Algorithm simply change PARD_ARE_WE_USING_SELF_LEARNING to say 'NO'
PARD_ARE_WE_USING_SELF_LEARNING = "YES"
PARD_BAN_UNAUTHORISED_404_REQUESTS = 'YES'
PARD_DB_NAME = "your_mysql_database"
PARD_DB_USER = "your_mysql_user_name"
PARD_DB_PASSWORD = "your_mysql_password"
PARD_DB_HOST = "localhost"
## Trusted Ring of IP Addresses
## Please Note: If you setup your Trusted Ring of IP Addreses correctly you can cut out greater than 99% of all potential hacking attempts.
## Nobody can access your WordPress or PHPMyadmin functions if their IP address is from outside your Trusted Ring.
## Always use IP ranges in preference to unique IP addresses. Seek advice on how to specify the best IP blocks for your application.
## The IP address can be inside double quotes, or you can scrap the double quotes. It makes no difference.
PARD_TRUSTED_RANGE_01 = "1.128.0.0/11"
PARD_TRUSTED_RANGE_02 = "101.112.0.0/13"
PARD_TRUSTED_RANGE_03 = "120.16.0.0/13"
PARD_TRUSTED_RANGE_04 = "163.116.192.0/24"
PARD_TRUSTED_RANGE_05 = ""
## VIP Access section
## Please Note: If you set these parameters correctly you can bypass the Trusted Ring of IP Addresses and log in to your Admin functions from outside your Trusted Ring.
## Hence, use with caution when you're logging in from devices which aren't yours. Delete cookies before you hand the device back, just to be super safe.
PARD_ARE_WE_USING_VIP_ACCESS = "YES"
PARD_BYPASS_XWORD = "your_bypass_code"
## Cloudflare section
## Set PARD_ARE_WE_USING_CLOUDFLARE to equal NO if you don't want bans to be sent to the Cloudflare API
PARD_ARE_WE_USING_CLOUDFLARE = "YES"
PARD_CLOUDFLARE_API_KEY = "your_cloudflare_API_Key"
PARD_CLOUDFLARE_AUTH_EMAIL = "your_cloudflare_login_email"
Let’s examine the Scanning Logic.
The standalone PHP version of Velodata’s Blackhole Cyber Security system contains four files: The following Code Snippet shown below is from the main executable file, blackhole.php – Please Note: We’re not showing all of the main executable, just the conditional logic.
- .htaccess
- blackhole.php
- blackhole.ini
- blackhole.dat
- blackhole.css
If you’ve loaded the Blackhole System and you’re experiencing issues (you shouldn’t by the way, we’ve tested it extensively for years) well you can at least refer to this PHP code and perhaps identify why the triggering logic is not working the way you’d expect.
function velodata_scan_the_request($ip, $ua, $request, $referrer, $ini_bypass_xword, $lxHTTP_REASON) {
$lxAuthorised = velodata_are_we_authorised();
/*
If lxAuthorised = "true" then the login screens can be reached.
If lxAuthorised = "false" the login screens CANNOT be reached.
*/
$lxFBCLID = filter_input(INPUT_GET, 'fbclid');
$GLOBALS['REASON_FOR_BAN'] = 'UNAUTHORISED_REQUEST';
if (\preg_match("/velodata.info.php/i", $request) === 1) {
echo '';
echo 'Good News! Your Blackhole Cyber Security is operational.
';
echo 'However, now we need to do some fine tuning. Let\'s get cracking then!
';
echo '';
console_log(' ');
console_log('PARD_ARE_WE_USING_CLOUDFLARE = ' . $GLOBALS['PARD_ARE_WE_USING_CLOUDFLARE']);
console_log(' ');
console_log("realpath(getenv('DOCUMENT_ROOT')) = " . realpath(getenv('DOCUMENT_ROOT')));
console_log(' ');
exit;
}
if ( preg_match("/index.phpinfo.php/i", $request) === 1) {
if ( $GLOBALS['PARD_ARE_WE_USING_VIP_ACCESS'] === 'YES' && $lxAuthorised !== true ) {
die;
}
if ( velodata_is_IP_whitelisted($ip ) === true ) {
console_log('GOOD NEWS!!! You IP Address is in The Trusted Ring of IP Addresses.');
} else {
die;
}
console_log(' ');
console_log('PARD_ARE_WE_USING_CLOUDFLARE = ' . $GLOBALS['PARD_ARE_WE_USING_CLOUDFLARE']);
console_log('PARD_ARE_WE_USING_TRUSTED_RING = ' . $GLOBALS['PARD_ARE_WE_USING_TRUSTED_RING']);
console_log('PARD_ARE_WE_USING_SELF_LEARNING = ' . $GLOBALS['PARD_ARE_WE_USING_SELF_LEARNING']);
console_log('PARD_ARE_WE_USING_VIP_ACCESS = ' . $GLOBALS['PARD_ARE_WE_USING_VIP_ACCESS']);
console_log('PARD_ARE_WE_SENDING_NOTIFICATIONS = ' . $GLOBALS['PARD_ARE_WE_SENDING_NOTIFICATIONS']);
console_log('PARD_ARE_WE_PROVIDING_FEEDBACK = ' . $GLOBALS['PARD_ARE_WE_PROVIDING_FEEDBACK']);
console_log(" ");
console_log("Default Notification email address = " . $GLOBALS['PARD_EMAIL_NOTIFICATION_ADDRESS']);
console_log("blackhole_exe_file = " . __FILE__ );
console_log("blackhole_ini_file = " . $_SERVER["blackhole_ini_path"] );
console_log("PARD_BAN_UNAUTHORISED_POST_REQUESTS = " . $GLOBALS['PARD_BAN_UNAUTHORISED_POST_REQUESTS']);
console_log("PARD_BAN_UNAUTHORISED_SPIDERBOTS = " . $GLOBALS['PARD_BAN_UNAUTHORISED_SPIDERBOTS']);
console_log("PARD_BAN_UNAUTHORISED_PHP_REQUESTS = " . $GLOBALS['PARD_BAN_UNAUTHORISED_PHP_REQUESTS']);
console_log("PARD_BAN_UNAUTHORISED_URI_REQUESTS = " . $GLOBALS['PARD_BAN_UNAUTHORISED_URI_REQUESTS']);
console_log("PARD_BAN_UNAUTHORISED_404_REQUESTS = " . $GLOBALS['PARD_BAN_UNAUTHORISED_404_REQUESTS']);
}
if (preg_match("/POST/", $_SERVER["REQUEST_METHOD"]) == 1) {
if ($lxAuthorised === true) {
return 999; // 999 = good to go, this means we're a logged in user
}
if (velodata_if_wordpress_useragent($GLOBALS['ua'])) {
// Dear User: What we're testing for here is (a) does the user-agent contain the string 'Wordpress'
// and (b) does the user_agent ALSO contain the HOST_ID (eg; yourwebsite.com )
return 999; // 999 = good to go
}
if (velodata_referrer_whitelist($GLOBALS['referrer'])) {
// Dear User: What we're testing for here is does the referrer field contain the HOST_ID (eg; yourwebsite.com )
return 999; // 999 = good to go
}
if ( velodata_is_IP_whitelisted($GLOBALS['ip']) ) {
$GLOBALS['REASON_FOR_BAN'] = "WPLOGIN_BYPASS_CODE_REQUIRED";
return 998; // 998 = remind the user to enter the Velodata Bypass Code
}
$GLOBALS['REASON_FOR_BAN'] = "UNAUTHORISED_HTTP_POST_REQUEST";
return 0;
}
if (preg_match("/(adreview|Baiduspider|Barkrowler|BPImageWalker|CensysInspect|coccocbot|CrowdTanglebot)/i", $ua) == 1 ||
preg_match("/(Dataprovider|Dispatch|DotBo|Go-http-client|ia_archiver|hypefactors|krzana-rss-bot)/i", $ua) == 1 ||
preg_match("/(linkfluence|MJ12bot|NetSystemsResearch|Nimbostratus|petalbot|python-requests|QIHU 360SE|Ruby)/i", $ua) == 1 ||
preg_match("/(Slackbot|SemrushBot|SeznamBot|Typhoeus|ubermetrics|yandex|zgrab|ZoominfoBot)/i", $ua) == 1) {
//
// Dear User:- Spiderbots are a pain in the ass, especially the ultra hungry Facebook version called cortex.
// But we don't want to necessarily ban the IP addresses they belong to - but you can if you want!
// So what we do is we reply with http 200 but then we divert them to their own http://127.0.0.1 localhost.
//
// Please note, a lot of unwanted Spiderbot problems go away if you're using a DNS Content Delivery service like Cloudflare
//
$GLOBALS['REASON_FOR_BAN'] = "UNAUTHORISED_SPIDERBOT_REQUEST";
return 0; // ban them!
}
if (preg_match("/blackhole/", $request) == 1) {
// Dear User:- This subroutine only gets called when .htaccess rewrites a request to the blackhole. This program subroutine then gets called because it's prepended.
// If we've reached this point in the program it's because htaccess directed us to this point in the program. htaccess is allowed to do that as part of the velodata system.
//
if (velodata_spiderbot_whitelist( $ua )) {
//
// Dear User:- We can live with an approved spiderbot like Google net getting banned. There's no menace involved so simply die the process.
//
die;
}
$GLOBALS['REASON_FOR_BAN'] = "HTACCESS_DECIDED_TO_BAN_THIS_REQUEST";
return 0; // ban them!
}
$request_only = $GLOBALS['request'];
if (preg_match("/\?/", $GLOBALS['request']) == 1) {
//
// Dear User:- This subroutine strips dodgy query string parameters from the original URL request to prevent 404 phishing...
// However, it only does this if you are NOT an authorised user of WordPress. If you ARE an authorised user, let the parameters exist.
//
//
$original_request = $GLOBALS['request'];
$query_string = '?' . $GLOBALS['query_string'];
$replace_string = '';
$request_only = str_replace($query_string, $replace_string, $original_request);
if (preg_match("/^abc=/", $GLOBALS['query_string']) == 1 ||
preg_match("/^author=/", $GLOBALS['query_string']) == 1 ||
preg_match("/^code=/", $GLOBALS['query_string']) == 1 ||
preg_match("/^d=/", $GLOBALS['query_string']) == 1 ||
preg_match("/^daksldlkdsadas=/", $GLOBALS['query_string']) == 1 ||
preg_match("/^emailaddress=/", $GLOBALS['query_string']) == 1 ||
preg_match("/^f=/", $GLOBALS['query_string']) == 1 ||
preg_match("/^file=/", $GLOBALS['query_string']) == 1 ||
preg_match("/^Ghost=/", $GLOBALS['query_string']) == 1 ||
preg_match("/^n=/", $GLOBALS['query_string']) == 1 ||
preg_match("/^p=/", $GLOBALS['query_string']) == 1 ||
preg_match("/^s=/", $GLOBALS['query_string']) == 1 ||
preg_match("/^test=/", $GLOBALS['query_string']) == 1 ||
preg_match("/^type=/", $GLOBALS['query_string']) == 1 ||
preg_match("/^u=/", $GLOBALS['query_string']) == 1 ||
preg_match("/^upload=/", $GLOBALS['query_string']) == 1 ||
preg_match("/^v=/", $GLOBALS['query_string']) == 1
)
{
if ($lxAuthorised !== true) {
$new_URL = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'] . $request_only;
header("Location: " . $new_URL);
die;
}
}
}
if (preg_match("/\?fbclid=/", $_SERVER['QUERY_STRING']) == 1) {
// Dear User:- This subroutine checks for the presence of a typical Facebook parameter in the QUERY STRING of the original URL
// If the QUERY STRING has a correctly formatted Facebook link then let's allow the request. It's a legitimate link to your website on Facebook.
//
//
return 999; // 999 = good to go
}
if (preg_match("/wp-login/", $request) == 1 || preg_match("/wp-admin/", $request) == 1) {
if (velodata_if_wordpress_useragent($ua)) {
return 999; // 999 = good to go
}
if ($lxAuthorised === true) {
return 999; // 999 = good to go
}
if ( velodata_is_IP_whitelisted($ip )) {
if ( $GLOBALS['PARD_ARE_WE_USING_VIP_ACCESS'] === 'YES' ) {
$GLOBALS['REASON_FOR_BAN'] = "WPLOGIN_ACCESS_CODE_REQUIRED";
return 998; // 998 = remind the user to enter a Velodata Bypass Code
} else {
return 999; // 999 = good to go
}
}
$GLOBALS['REASON_FOR_BAN'] = "WPLOGIN_ADMIN_FAIL";
return 0; // 0 = BAN THEM and die!
}
if (preg_match("/phpmyadmin/i", $request) == 1) {
if ($lxAuthorised === true) {
return 999; // 999 = good to go
}
if ( velodata_is_IP_whitelisted($ip )) {
if ( $GLOBALS['PARD_ARE_WE_USING_VIP_ACCESS'] === 'YES' ) {
$GLOBALS['REASON_FOR_BAN'] = "WPLOGIN_ACCESS_CODE_REQUIRED";
return 998; // 998 = remind the user to enter a Velodata Bypass Code
} else {
return 999; // 999 = good to go
}
}
$GLOBALS['REASON_FOR_BAN'] = "PHP_MY_ADMIN_FAIL";
return 0; // 0 = BAN THEM and die!
}
if (preg_match("/wp-json/", $request) == 1 ) {
if ($lxAuthorised == true) {
return 999; // 999 = good to go
}
if (velodata_if_wordpress_useragent($ua)) {
return 999; // 999 = good to go
}
header("HTTP/1.1 403 PREPEND Blackhole Software");
die;
}
if (preg_match("/xmlrpc.php/i", $request) == 1 || preg_match("/xmlprc.php/i", $request) == 1) {
$GLOBALS['REASON_FOR_BAN'] = "XMLRPC_REQUEST_FAIL";
return 0;
}
if (preg_match("/wp-config.php/", $request) == 1 || preg_match("/wp-config-sample.php/", $request) == 1) {
$GLOBALS['REASON_FOR_BAN'] = "WP_CONFIG_FAIL";
return 0;
}
if ( preg_match("/\/.env/i", $request) == 1 ||
preg_match("/\/autodiscover/i", $request) == 1 ||
preg_match("/\/license.txt/i", $request) == 1 ||
preg_match("/\/readme.html/i", $request) == 1 ||
preg_match("/\/readme.txt/i", $request) == 1 ||
preg_match("/\/.htaccess/i", $request) == 1 ||
preg_match("/\/debug.log/i", $request) == 1 ||
preg_match("/XXX_END_OF_LIST/", $ua) == 1 )
{
$GLOBALS['REASON_FOR_BAN'] = "UNAUTHORISED_FILE_REQUEST";
return 0;
}
// Dear User:- OK, we've come this far which means EITHER we're going to process a REAL WordPress request or we're going to reach a 404...
// So let's check and see if the REQUEST has previously added 404 records in the 404 database....
//
if ($GLOBALS['PARD_ARE_WE_USING_SELF_LEARNING'] === 'YES') {
if ($lxAuthorised == true) {
return 999; // 999 = good to go
//
// Dear User:- If we're an Authorised user of the WordPress/PhpMyAdmin system, proceed without visiting the 404 Anti Phishing Self Learning Algorithm.
// After all, it is possible that we ourselves create a legitimate 404 error by mistake, so we SHOULD know about that.
//
}
velodata_check_for_not_found();
}
return 999; // 999 = good to go
}
// END OF MAIN SCAN LOOP