Merge pull request #165 from CHOMPStation2/Razgriz1032-patch-20

[MIRROR] IP Reputation Tracking
This commit is contained in:
Razgriz
2020-01-16 03:37:39 -07:00
committed by GitHub
4 changed files with 161 additions and 6 deletions

View File

@@ -63,8 +63,8 @@ var/list/gamemode_cache = list()
var/allow_random_events = 0 // enables random events mid-round when set to 1
var/enable_game_master = 0 // enables the 'smart' event system.
var/allow_ai = 1 // allow ai job
var/allow_ai_shells = TRUE // allow AIs to enter and leave special borg shells at will, and for those shells to be buildable.
var/give_free_ai_shell = TRUE // allows a specific spawner object to instantiate a premade AI Shell
var/allow_ai_shells = FALSE // allow AIs to enter and leave special borg shells at will, and for those shells to be buildable.
var/give_free_ai_shell = FALSE // allows a specific spawner object to instantiate a premade AI Shell
var/hostedby = null
var/respawn = 1
var/guest_jobban = 1
@@ -104,6 +104,13 @@ var/list/gamemode_cache = list()
var/panic_bunker = 0
var/paranoia_logging = 0
var/ip_reputation = FALSE //Should we query IPs to get scores? Generates HTTP traffic to an API service.
var/ipr_email //Left null because you MUST specify one otherwise you're making the internet worse.
var/ipr_block_bad_ips = FALSE //Should we block anyone who meets the minimum score below? Otherwise we just log it (If paranoia logging is on, visibly in chat).
var/ipr_bad_score = 1 //The API returns a value between 0 and 1 (inclusive), with 1 being 'definitely VPN/Tor/Proxy'. Values equal/above this var are considered bad.
var/ipr_allow_existing = FALSE //Should we allow known players to use VPNs/Proxies? If the player is already banned then obviously they still can't connect.
var/ipr_minimum_age = 5 //How many days before a player is considered 'fine' for the purposes of allowing them to use VPNs.
var/serverurl
var/server
var/banappeals
@@ -806,6 +813,24 @@ var/list/gamemode_cache = list()
if ("paranoia_logging")
config.paranoia_logging = 1
if("ip_reputation")
config.ip_reputation = 1
if("ipr_email")
config.ipr_email = value
if("ipr_block_bad_ips")
config.ipr_block_bad_ips = 1
if("ipr_bad_score")
config.ipr_bad_score = text2num(value)
if("ipr_allow_existing")
config.ipr_allow_existing = 1
if("ipr_minimum_age")
config.ipr_minimum_age = text2num(value)
if("random_submap_orientation")
config.random_submap_orientation = 1
@@ -994,4 +1019,4 @@ var/list/gamemode_cache = list()
if(world.system_type == UNIX)
config.python_path = "/usr/bin/env python2"
else //probably windows, if not this should work anyway
config.python_path = "python"
config.python_path = "python"

View File

@@ -36,11 +36,12 @@
//SECURITY//
////////////
// comment out the line below when debugging locally to enable the options & messages menu
control_freak = CONTROL_FREAK_ALL
//control_freak = 1
var/received_irc_pm = -99999
var/irc_admin //IRC admin that spoke with them last.
var/mute_irc = 0
var/ip_reputation = 0 //Do we think they're using a proxy/vpn? Only if IP Reputation checking is enabled in config.
////////////////////////////////////
@@ -55,4 +56,4 @@
preload_rsc = PRELOAD_RSC
var/global/obj/screen/click_catcher/void
var/global/obj/screen/click_catcher/void

View File

@@ -74,7 +74,6 @@
..() //redirect to hsrc.Topic()
//This stops files larger than UPLOAD_LIMIT being sent from client to server via input(), client.Import() etc.
/client/AllowUpload(filename, filelength)
if(filelength > UPLOAD_LIMIT)
@@ -169,10 +168,19 @@
hook_vr("client_new",list(src)) //VOREStation Code
if(config.paranoia_logging)
var/alert = FALSE //VOREStation Edit start.
if(isnum(player_age) && player_age == 0)
log_and_message_admins("PARANOIA: [key_name(src)] has connected here for the first time.")
alert = TRUE
if(isnum(account_age) && account_age <= 2)
log_and_message_admins("PARANOIA: [key_name(src)] has a very new BYOND account ([account_age] days).")
alert = TRUE
if(alert)
for(var/client/X in admins)
if(X.is_preference_enabled(/datum/client_preference/holder/play_adminhelp_ping))
X << 'sound/voice/bcriminal.ogg'
window_flash(X)
//VOREStation Edit end.
//////////////
//DISCONNECT//
@@ -274,6 +282,31 @@
qdel(src)
return 0
// IP Reputation Check
if(config.ip_reputation)
if(config.ipr_allow_existing && player_age >= config.ipr_minimum_age)
log_admin("Skipping IP reputation check on [key] with [address] because of player age")
else if(update_ip_reputation()) //It is set now
if(ip_reputation >= config.ipr_bad_score) //It's bad
//Log it
if(config.paranoia_logging) //We don't block, but we want paranoia log messages
log_and_message_admins("[key] at [address] has bad IP reputation: [ip_reputation]. Will be kicked if enabled in config.")
else //We just log it
log_admin("[key] at [address] has bad IP reputation: [ip_reputation]. Will be kicked if enabled in config.")
//Take action if required
if(config.ipr_block_bad_ips && config.ipr_allow_existing) //We allow players of an age, but you don't meet it
to_chat(src,"Sorry, we only allow VPN/Proxy/Tor usage for players who have spent at least [config.ipr_minimum_age] days on the server. If you are unable to use the internet without your VPN/Proxy/Tor, please contact an admin out-of-game to let them know so we can accomidate this.")
qdel(src)
return 0
else if(config.ipr_block_bad_ips) //We don't allow players of any particular age
to_chat(src,"Sorry, we do not accept connections from users via VPN/Proxy/Tor connections.")
qdel(src)
return 0
else
log_admin("Couldn't perform IP check on [key] with [address]")
// VOREStation Edit Start - Department Hours
if(config.time_off)
var/DBQuery/query_hours = dbcon.NewQuery("SELECT department, hours FROM vr_player_hours WHERE ckey = '[sql_ckey]'")
@@ -407,3 +440,63 @@ client/verb/character_setup()
if(var_name == NAMEOF(src, holder))
return FALSE
return ..()
//This is for getipintel.net.
//You're welcome to replace this proc with your own that does your own cool stuff.
//Just set the client's ip_reputation var and make sure it makes sense with your config settings (higher numbers are worse results)
/client/proc/update_ip_reputation()
var/request = "http://check.getipintel.net/check.php?ip=[address]&contact=[config.ipr_email]"
var/http[] = world.Export(request)
/* Debug
world.log << "Requested this: [request]"
for(var/entry in http)
world.log << "[entry] : [http[entry]]"
*/
if(!http || !islist(http)) //If we couldn't check, the service might be down, fail-safe.
log_admin("Couldn't connect to getipintel.net to check [address] for [key]")
return FALSE
//429 is rate limit exceeded
if(text2num(http["STATUS"]) == 429)
log_and_message_admins("getipintel.net reports HTTP status 429. IP reputation checking is now disabled. If you see this, let a developer know.")
config.ip_reputation = FALSE
return FALSE
var/content = file2text(http["CONTENT"]) //world.Export actually returns a file object in CONTENT
var/score = text2num(content)
if(isnull(score))
return FALSE
//Error handling
if(score < 0)
var/fatal = TRUE
var/ipr_error = "getipintel.net IP reputation check error while checking [address] for [key]: "
switch(score)
if(-1)
ipr_error += "No input provided"
if(-2)
fatal = FALSE
ipr_error += "Invalid IP provided"
if(-3)
fatal = FALSE
ipr_error += "Unroutable/private IP (spoofing?)"
if(-4)
fatal = FALSE
ipr_error += "Unable to reach database"
if(-5)
ipr_error += "Our IP is banned or otherwise forbidden"
if(-6)
ipr_error += "Missing contact info"
log_and_message_admins(ipr_error)
if(fatal)
config.ip_reputation = FALSE
log_and_message_admins("With this error, IP reputation checking is disabled for this shift. Let a developer know.")
return FALSE
//Went fine
else
ip_reputation = score
return TRUE

View File

@@ -447,3 +447,39 @@ ENGINE_MAP Supermatter Engine,Edison's Bane
## Uncomment to allow specific solar control computers to set themselves up.
## This requires solar controller computers in the map to be set up to use it, with the auto_start variable.
# AUTOSTART_SOLARS
## Rate of radiation decay (how much it's reduced by) per life tick
RADIATION_DECAY_RATE 1
## Lower limit on radiation for actually irradiating things on a turf
RADIATION_LOWER_LIMIT 0.01
## Multiplier for radiation resistances when tracing a ray from source to destination to compute radiation on a turf
RADIATION_RESISTANCE_MULTIPLIER 2.1
## Divisor for material weights when computing radiation resistance of a material object (walls)
RADIATION_MATERIAL_RESISTANCE_DIVISOR 16
## Mode of computing radiation resistance into effective radiation on a turf
## One and only one of the following options must be uncommented
RADIATION_RESISTANCE_CALC_DIVIDE
# RADIATION_RESISTANCE_CALC_SUBTRACT
## IP Reputation Checking
# Enable/disable IP reputation checking (present/nonpresent)
#IP_REPUTATION
# Set the e-mail address problems can go to for IPR checks (e-mail address)
IPR_EMAIL whatever@whatever.com
# Above this value, reputation scores are considered 'bad' (number)
IPR_BAD_SCORE 1
# If you want the people disconnected. Otherwise it just logs. (present/nonpresent)
IPR_BLOCK_BAD_IPS
# If players of a certain length of playtime are allowed anyway (REQUIRES DATABASE) (present/nonpresent)
IPR_ALLOW_EXISTING
# And what that age is (number)
IPR_MINIMUM_AGE 5