-
Notifications
You must be signed in to change notification settings - Fork 0
/
init.lua
147 lines (134 loc) · 5.25 KB
/
init.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
block_vps = {}
local http_api = minetest.request_http_api()
assert(http_api ~= nil, "Add 'block_vps' to secure.http_mods and restart server")
local mod_path = core.get_modpath(core.get_current_modname())
local mod_storage
-- support older minetest versions
if minetest.get_mod_storage then
mod_storage = minetest.get_mod_storage()
end
-- support older minetest versions
function block_vps.get_setting(name)
if core.settings then
return core.settings:get(name)
else
return core.setting_get(name)
end
end
local block_type = block_vps.get_setting("block_vps_type") or "activation"
assert(loadfile(mod_path .. "/api.lua"))(http_api)
dofile(mod_path .. "/iphub.lua")
dofile(mod_path .. "/iphub_legacy.lua")
dofile(mod_path .. "/nastyhosts.lua")
-- block other mods from register data source till better security code can be written
block_vps.register_datasource = nil
local function create_reject_message(ip, isp)
local message
if block_type ~= "kick" then
message = "\nCreating new accounts "
else
message = "\nConnecting "
end
message = message .. "from this IP address (%s) is blocked,\nas it appears to be belong to a hosting/VPN/proxy provider (%s)" ..
"%s\nplease contact the server owner if this is an error."
local note = ","
if block_type == "activation" then
note = ".\nConnect from an unblocked IP address to be able to use this account,"
end
return string.format(message, ip, isp, note)
end
local function log_block(name, ip, isp, datasource, kicked)
local prefix = "Blocking %q connecting"
if kicked then prefix = "Kicked %q connected" end
core.log("action", string.format("[block_vps] " .. prefix .. " from %q as the IP address appears to belong to %q (datasource = %q).", name, ip, isp, datasource))
end
if block_type == "creation" then
core.register_on_prejoinplayer(function(name, ip)
if not core.player_exists(name) then
local ip_info = block_vps.get_ip_info_sync(ip)
if ip_info and ip_info.is_blocked then
log_block(name, ip, ip_info.isp, ip_info.api)
return create_reject_message(ip, ip_info.isp)
end
end
end)
elseif block_type == "activation" then
-- support older minetest versions
assert(mod_storage ~= nil, "Your minetest version doesn't support mod storage, " ..
"it is required if 'block_vps_type' is set to 'activation' please change it to any other support setting ('none', 'kick', 'creation')")
local default_privs = core.string_to_privs(core.settings:get("default_privs"))
core.register_on_joinplayer(function(player)
local name = player:get_player_name()
-- Check if the account has yet to connect from a valid IP
if mod_storage:get_int(name) == 1 then
block_vps.get_ip_info(core.get_player_ip(name), function(ip, info)
if info and info.is_blocked then
-- if the player tries to connect from another banned IP kick and log.
log_block(name, ip, info.isp, info.api, true)
minetest.kick_player(name, create_reject_message(ip, info.isp))
else
-- give the player back the default privs we took
core.set_player_privs(name, default_privs)
mod_storage:set_string(name, "") -- only way to erase a mod storage key
end
end)
end
end)
core.register_on_newplayer(function(player)
local name = player:get_player_name()
-- revoke all of the players privs so they don't try to exploit the small delay between connection and IP lookup end.
core.set_player_privs(name, {})
block_vps.get_ip_info(core.get_player_ip(name), function(ip, info)
if info and info.is_blocked then
--[[
If the IP the player created the account with is banned,
kick them, log the event and record that they need to login with a normal IP to use the account in mod storage
--]]
mod_storage:set_int(name, 1)
log_block(name, ip, info.isp, info.api, true)
minetest.kick_player(name, create_reject_message(ip, info.isp, true))
else
-- give the player back the default privs we took
core.set_player_privs(name, default_privs)
end
end)
end)
elseif block_type == "kick" then
core.register_on_joinplayer(function(player)
local name = player:get_player_name()
if core.check_player_privs(name, {bypass_ip_check=true}) then
return
end
block_vps.get_ip_info(core.get_player_ip(name), function(ip, info)
if info and info.is_blocked then
log_block(name, ip, info.isp, info.api, true)
minetest.kick_player(name, create_reject_message(ip, info.isp))
end
end)
end)
end
core.register_privilege("bypass_ip_check", "Stops the users IP from being check on join by block_vps")
core.register_chatcommand("get_ip_info", {
params = "<ip_address>",
description = "Display IP address information",
privs = {server=true},
func = function(name, param)
param = param:trim()
if param == "" then
return false, "IP address needed"
end
local ip = param:match("^([^ ]+)")
block_vps.get_ip_info(ip, function(ip, info)
if not info then
core.chat_send_player(name, string.format("Failed to get IP info for %q", ip))
else
local message = string.format("\nIP Info for %q\nData Source: %s\nBlocked: %s\nISP: %q\nASN: %d\nHost Name: %s\n",
ip, info.api, tostring(info.is_blocked), info.isp, info.asn, info.hostname)
if info.country then
message = message .. "Country: " .. info.country .. "\n"
end
core.chat_send_player(name, message)
end
end)
end,
})