Coder Social home page Coder Social logo

vpnblocker's Introduction

VPN Blocker

GitHub release Minimum BZFlag Version License

A BZFlag plug-in that will make an API call to a third-party service to check whether or not an IP address is a VPN.

Requirements

  • BZFlag 2.4.12+
  • C++11

Usage

Loading the plug-in

Load the plug-in with a single command line argument, which is the path to the required configuration file.

-loadplugin VPNBlocker,/path/to/VPNBlocker.config.json

Configuration File

The configuration file is required to load the plug-in and have it function properly. A sample configuration is available as VPNBlocker.config.json.

  • allow_vpn (string) - Configure which players are allowed to use VPNs
    • none - No players, so API calls will be made for each player
    • verified - Only authenticated players with accounts older than max_bzid will be allowed to use VPNs
  • max_bzid (int) - When allow_vpn is set to verified, then only players with a BZID lower than this value will be allowed to use a VPN
  • report_url (string) - A POST request will be sent to this URL with information about IPs that were detected as VPNs
  • block_list_url (string) - Currently unimplemented
  • services (object[]) - An array of API URLs to query on the VPN status of an IP

This plug-in checks for an ALLOWVPN permission that supersedes the allow_vpn setting, so you can allow admins or specific players use VPNs.

Services

This plug-in will occasionally have built-in support for certain services. Multiple services can be configured and they are checked in order, one at a time for each VPN check that is needed. If one service classifies the IP as a VPN, it will cancel the remaining API calls for that IP and move on to checking the next IP.

IPHub v2

Create an account on IPHub and read up on getting an API key from their documentation. A free account is more than enough for a typical BZFlag server.

To use IPHub as a service in this plugin, here is the structure of the object. Simply use iphub for type and set your API key for key.

{
  "type": "iphub",
  "key": "CHANGE_ME"
}
Custom Queries

When a service does not have built-in support, you can create your own definitions by simply defining what a GET request will look like. All fields are required, even if they're just {} for objects, [] for arrays, or "" for strings.

To create your own request, use custom for the type and define all of the following fields. The special {ip} placeholder can be used to define how the player's IP will be sent. This placeholder is available in the following fields:

  • url
  • query_params

Here is an example structure to send a GET request to https://example.com/api.php?ip=127.0.0.1.

{
  "type": "custom",
  "url": "https://example.com/api.php",
  "query_params": {
    "ip": "{ip}"
  },
  "headers": {
    "X-API-KEY": "CHANGE_ME_MAYBE",
  },
  "response": {
    "report": ["ip"],
    "disallow": {
      "key": "block",
      "value": "1"
    }
  }
}

The response object defines the logic on when to kick a player for VPN usage.

  • The report field is a list of keys that will be sent to the report_url link
  • The disallow object defines on what key to check and the value that would result in a kick. The value definition must always be a string; even when the JSON response from the service returns it as a boolean or integer, you will define it as a string in your configuration.

As an example, the following JSON response from example.com would result in a kick:

{
  "ip": "127.0.0.1",
  "block": 1
}

Custom Slash Commands

This plug-in implements or overrides the following slash commands.

Command Permission Description
/reload [vpnblocker] setAll Reload the configuration file this plug-in has loaded
/vpnblocker shutdownserver See the status of the plug-in and see if it's running correctly
/vpnblocklist playerList Displays a list of IPs that have been blocked as VPNs
/vpnunblock unban Remove an IP from the VPN block list loaded in the plug-in's memory

License

MIT

vpnblocker's People

Contributors

allejo avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vpnblocker's Issues

Support for Ubuntu 18.04+

Going off of allejo/LeagueOverseer#51, in order to compile on Ubuntu 18.04+ and likely whatever the new Debian LTS is, you must install libjson-c-dev and apply the following changes.

diff --git a/Makefile.am b/Makefile.am
index 871946d..a24a552 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,7 +2,7 @@ lib_LTLIBRARIES = VPNBlocker.la

 VPNBlocker_la_SOURCES = VPNBlocker.cpp JsonObject/JsonObject.h JsonObject/JsonObject.cpp
 VPNBlocker_la_CPPFLAGS= -I$(top_srcdir)/include -I$(top_srcdir)/plugins/plugin_utils
-VPNBlocker_la_LDFLAGS = -module -avoid-version -shared -ljson
+VPNBlocker_la_LDFLAGS = -module -avoid-version -shared -ljson-c
 VPNBlocker_la_LIBADD = $(top_builddir)/plugins/plugin_utils/libplugin_utils.la

 AM_CPPFLAGS = $(CONF_CPPFLAGS)
diff --git a/VPNBlocker.cpp b/VPNBlocker.cpp
index 948f837..34a152e 100644
--- a/VPNBlocker.cpp
+++ b/VPNBlocker.cpp
@@ -21,7 +21,7 @@ THE SOFTWARE.
 */

 #include <cstdarg>
-#include <json/json.h>
+#include <json-c/json.h>
 #include <queue>

 #include "bzfsAPI.h"
diff --git a/JsonObject/JsonObject.cpp b/JsonObject/JsonObject.cpp
index 42f1222..e8ea7ba 100644
--- a/JsonObject.cpp
+++ b/JsonObject.cpp
@@ -20,7 +20,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 THE SOFTWARE.
 */

-#include <json/json.h>
+#include <json-c/json.h>
 #include <map>
 #include <string>
 #include <vector>
diff --git a/JsonObject/JsonObject.h b/JsonObject/JsonObject.h
index 95b8394..43a6461 100644
--- a/JsonObject.h
+++ b/JsonObject.h
@@ -23,7 +23,7 @@ THE SOFTWARE.
 #ifndef __JsonObject_H_
 #define __JsonObject_H_

-#include <json/json.h>
+#include <json-c/json.h>
 #include <string>
 #include <vector>
 #include <map>

While I investigate a way of possibly maintaining backward-compatibility with Ubuntu 16.04 LTS, these changes need to be made manually.

libjson0-dev has libjson-c-dev as a dependency, so I would hope that a swap to json-c in the #include would be ok and potentially -ljson too?

For now, consider this plug-in untested on 18.04+

Be careful about kicking players based on ID

I need to be careful about kicking players. While in this example, it looks like a partial join, don't kick solely based on the ID and confirm we're kicking the same player.

Because API calls are delayed, if a person leaves and another person joins with the same ID while the API call is happening the wrong person will get kicked.

2017-08-11 00:19:56: Player Green Manalishi [1] has joined from [redacted 1] at 2017-08-11 00:19:56 with token "940804132"
2017-08-11 00:19:58: Player Green Manalishi [1] removed at 2017-08-11 00:19:58: unidentified
2017-08-11 00:20:05: Player [1] accept() from [redacted 2]:36490 on 7
2017-08-11 00:20:05: Player [1] submitted reverse resolve query
2017-08-11 00:20:05: Player [1] resolved to [redacted 2 host]
2017-08-11 00:20:05: Player slot 1 inbound UDP up [redacted 2]:36490 actual 36490
2017-08-11 00:20:06: Player 1 outbound UDP up
2017-08-11 00:20:07: Player  [1] removed at 2017-08-11 00:20:07: Your host has been detected as a VPN.
2017-08-11 00:20:07: NOTICE :: VPN Blocker :: Player Green Manalishi ([redacted 1]) removed for VPN usage

Explore new JSON implementation

Though I doubt that the libjson-c-dev will change names again, the fact remains that it's not easy to use and requires my JsonObject wrapper to make JSON usable.

There's a new contender over at nlohmann/json that:

  • is distributed as a single .hpp file meaning it can be dropped in this repo and you'll never have to worry about external dependencies for compiling this plug-in ever again
  • allows JSON to be accessed like a first-class data type in C++
  • does not require linking in any of our build systems

Add support for nested JSON response

In some APIs, such as AbuseIPDB, the JSON response has some nested data. There's no way to currently access nested values via our custom API configurations. The proposed syntax is to add support for dot notation of nested information.

For example, given the following JSON response:

{
    "data": {
      "ipAddress": "118.25.6.39",
      "isPublic": true,
      "ipVersion": 4,
      "isWhitelisted": false,
      "abuseConfidenceScore": 100,
      "countryCode": "CN",
      "countryName": "China",
      "usageType": "Data Center/Web Hosting/Transit",
      "isp": "Tencent Cloud Computing (Beijing) Co. Ltd",
      "domain": "tencent.com",
      "hostnames": [],
      "totalReports": 1,
      "numDistinctUsers": 1,
      "lastReportedAt": "2018-12-20T20:55:14+00:00",
      "reports": [
        {
          "reportedAt": "2018-12-20T20:55:14+00:00",
          "comment": "Dec 20 20:55:14 srv206 sshd[13937]: Invalid user oracle from 118.25.6.39",
          "categories": [
            18,
            22
          ],
          "reporterId": 1,
          "reporterCountryCode": "US",
          "reporterCountryName": "United States"
        }
      ]
    }
  }

A key of data.usageType would allow us to access the "Data Center/Web Hosting/Transit" value.

Add `/vpnunblock` command

In case an IP is marked as a VPN, there should be a way to remove an IP from the plugin cache of VPN IPs

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.