checkip - impelment vpnapi.io improved ip checking tool helper

* set the improved version of ip check, using apikey, if
  the apikey is not set or empty, it will use simple geoip
* the command `govip` will check ip in all ways, if error,
  i will suggest to try `geoip` command
* for geoip comman, no matter if mod its present or not..
  it will detect geoip mod and provide command and log for
* registered geoip privilegie if geoip mod is not present
* registered governing privilegie
* license of code and license headers
* improve README documentation
master
mckaygerhard 2023-06-22 00:24:06 -04:00
parent 4383e656fa
commit ad6e49f63f
6 changed files with 250 additions and 98 deletions

126
README.md
View File

@ -1,4 +1,4 @@
minetest mod goberning
minetest mod governing
======================
ADMIN mod, light version of various mods and extra tool for manage server
@ -6,78 +6,102 @@ ADMIN mod, light version of various mods and extra tool for manage server
Information
-----------
@mckaygerhard PICCORO's improvement administration combo and commands for minetest
## Technical info
-----------------
This mod attempts to be an improvement administration combo, but minimized
as a light version of some other tools like geoip, names-per-ip, antigrif, antihack,
etc etc etc
## LICENSE
Repository : https://git.minetest.io/minenux/minetest-mod-governing
(c) 2023 Lenz McKAY Gerhard mckaygerhard
#### Configurations
CC-BY-SA-NC 4.0
| config param | value | req | default | example |
| --------------------- | ---------- | --- | -------- | -------------------------------- |
| secure.http_mods | governing | yes | none set | geoip,governing |
| secure.trusted_mods | governing | yes | none set | auth_rx,governing |
| governing.checkapikey | `<string>` | yes | none set | 177cd4797a4949c4b1114d2e4ab9af11 |
The `governing.checkapikey` string is requested by registering a free (or paid)
account at https://vpnapi.io/ and **if not configured, will be used a simple geoip request**.
1. its powered by [VPNapi.io IP VPN & Proxy Detection API](https://vpnapi.io/api-documentation)
2. but if apykey is not set, its powered by [IP Location Finder by KeyCDN](https://tools.keycdn.com/geo)
#### Commands
| command & format | permission | description function | observations |
| --------------------- | --------- | ----------------------- | ----------------------- |
| `/killme` | interact | kill yourselft | no matter if killme mod is present or not |
| `/govip <playername>` | governing | complete ip player info | Will require keyapi configuration set |
| `/geoip <playername>` | geoip | simple ip player info | no matter if geoip mod is present or not |
it provides geoip mod for minetest
#### privs
Lets you resolve geoip requests on a player
* `geoip` can make a geoip query, no matter if geoip mod is present or missing
* `governing` can run administration command like ip check
powered by [IP Location Finder by KeyCDN](https://tools.keycdn.com/geo)
### minetest.conf
```
# enable curl/http on that mod
secure.http_mods = geoip,governing
```
### Commands
```
/geoip <playername>
```
### privs
* `geoip` can make a geoip query
# Api
#### Api
```lua
-- lookup command
governing.lookup("213.152.186.35", function(result)
-- see "Geoip result data"
governing.checkip("213.152.186.35", function(result)
-- see "Check ip information data"
end)
-- overrideable callback on player join
governing.joinplayer_callback = function(playername, result)
-- see "Geoip result data"
-- see "Check ip information result data"
end
```
## Geoip result data
Check IP information on data:
```json
{
"status": "success",
"description": "Data successfully received.",
"data": {
"geo": {
"host": "213.152.186.35",
"ip": "213.152.186.35",
"rdns": "213.152.186.35",
"asn": 49453,
"isp": "Global Layer B.V.",
"country_name": "Netherlands",
"country_code": "NL",
"region_name": null,
"region_code": null,
"city": null,
"postal_code": null,
"continent_name": "Europe",
"continent_code": "EU",
"latitude": 52.3824,
"longitude": 4.8995,
"metro_code": null,
"timezone": "Europe/Amsterdam",
"datetime": "2021-05-20 08:45:56"
"ip": "8.8.8.8",
"security": {
"vpn": false,
"proxy": false,
"tor": false,
"relay": false,
},
"location": {
"city": "",
"region": "",
"country": "United States",
"continent": "North America",
"region_code": "",
"country_code": "US",
"continent_code": "NA",
"latitude": "37.7510",
"longitude": "-97.8220",
"time_zone": "America/Chicago",
"locale_code": "en",
"metro_code": "",
"is_in_european_union": false
},
"network": {
"network": "8.8.8.0/24",
"autonomous_system_number": "AS15169",
"autonomous_system_organization": "GOOGLE"
}
}
}
```
## LICENSE
Copyright (C) 2023 mckaygerhard <mckaygerhard@gmail.com> CC-BY-SA-NC 4.0
Copyright (C) 2023 mckayshirou <mckayshirou@gmail.com> CC-BY-SA-NC 4.0
It applies CC-BY-SA-NC 4.0 unless you ask to request permission
with special conditions. The ipcheck idea, the mod inclusion,
can be distributed if the URL of repo are not altered when promotes.
URL : https://git.minetest.io/minenux and http://minetest.org

View File

@ -1,9 +1,9 @@
-- mod governor by mckaygerhard
-- mod governor by mckaygerhard - commands module
-- Copyright 2020
----------------------------------------------------------------------------
-- this program can be used free but cannot be used commertially or
-- modified for, licenced CC-BY-SA-NC 4.0
-- modified for, licenced CC-BY-SA-NC 4.0 unless explicit permission
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -63,3 +63,21 @@ if not governing.modgeoip then
})
end
minetest.register_chatcommand("govip", {
params = "<playername>",
privs = {governing=true},
description = "Governing geoip lookup + net detection details on the given player",
func = function(name, param)
if not param then return true, "usage: /govip <playername>" end
if not minetest.get_player_ip then return true, "[governing]: engine its too older, canot get ip of player." end
local ip = minetest.get_player_ip(param)
if not ip then return true, "[governing] no ip available! seems "..param.." does not provide such info!" end
governing.checkip(ip, function(result)
local txt = format_result_checkip(result)
if not txt then return true, "[governing]: "..param..":"..ip" error: "..(result.description or "unknown error") end
minetest.log("action", "[governing] "..param..": "..txt)
minetest.chat_send_player(name, param..": "..txt)
end)
end
})

162
geoip.lua
View File

@ -1,65 +1,139 @@
-- mod governor by mckaygerhard, geoip specific code
-- Copyright 2023
----------------------------------------------------------------------------
-- this program can be used free but cannot be used commertially or
-- modified for, licenced CC-BY-SA-NC 4.0 unless explicit permission
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
----------------------------------------------------------------------------
function format_result_geoip(result)
if result and result.status == "success" and result.data and result.data.geo then
local txt = " Place: "
if result.data.geo.ip then
if result.data.geo.ip == "127.0.0.1" then return txt .. " seems localhost " ..".. <_< ." end
local txt = " Place: "
if result then
if result.status == "success" and result.data and result.data.geo then
if result.data.geo.ip then
if result.data.geo.ip == "127.0.0.1" then return txt .. " seems localhost " ..".. <_< ." end
end
if result.data.geo.continent_name then
if result.data.geo.continent_name ~= "" then txt = txt .. result.data.geo.continent_name .."," end
end
if result.data.geo.country_name then
if result.data.geo.country_name ~= "" then txt = txt .. result.data.geo.country_name .."," end
end
if result.data.geo.region_name then
if result.data.geo.region_name ~= "" then txt = txt .. result.data.geo.region_name .. "," end
end
if result.data.geo.city then
if result.data.geo.city ~= "" then txt = txt .. result.data.geo.city .."" end
end
if result.data.geo.timezone then
if result.data.geo.timezone ~= "" then txt = txt .. " Timezone: " .. result.data.geo.timezone end
end
if result.data.geo.asn then
if result.data.geo.asn ~= "" then txt = txt .. " ASN: " .. result.data.geo.asn end
end
if result.data.geo.isp then
if result.data.geo.isp ~= "" then txt = txt .. " ISP: " .. result.data.geo.isp end
end
if result.data.geo.ip then
if result.data.geo.ip ~= "" then txt = txt .. " IP: " .. result.data.geo.ip end
end
return txt
else
return false
end
if result.data.geo.continent_name then
if result.data.geo.continent_name ~= "" then txt = txt .. result.data.geo.continent_name .."," end
end
if result.data.geo.country_name then
if result.data.geo.country_name ~= "" then txt = txt .. result.data.geo.country_name .."," end
end
if result.data.geo.region_name then
if result.data.geo.region_name ~= "" then txt = txt .. result.data.geo.region_name .. "," end
end
if result.data.geo.city then
if result.data.geo.city ~= "" then txt = txt .. result.data.geo.city .."" end
end
if result.data.geo.timezone then
if result.data.geo.timezone ~= "" then txt = txt .. " Timezone: " .. result.data.geo.timezone end
end
if result.data.geo.asn then
if result.data.geo.asn ~= "" then txt = txt .. " ASN: " .. result.data.geo.asn end
end
if result.data.geo.isp then
if result.data.geo.isp ~= "" then txt = txt .. " ISP: " .. result.data.geo.isp end
end
if result.data.geo.ip then
if result.data.geo.ip ~= "" then txt = txt .. " IP: " .. result.data.geo.ip end
end
return txt
else
return false
end
end
if not governing.modgeoip then
minetest.register_privilege("geoip", {
description = "can do geoip lookups on players for governing",
give_to_singleplayer = false
})
function format_result_checkip(result)
local txt = " Place: "
local flg = ""
if result then
if result.message then
return result.message .. ".. <_< . if no key, use /geoip command"
end
if result.security then
if result.security.vpn then
if result.security.vpn ~= "true" then flg = flg .. "+VPN" end
end
if result.security.proxy then
if result.security.proxy ~= "true" then flg = flg .. "+PRX" end
end
if result.security.tor then
if result.security.tor ~= "true" then flg = flg .. "+TOR" end
end
if result.security.relay then
if result.security.tor ~= "true" then flg = flg .. "+REL" end
end
end
if result.location then
if result.location then
if result.location.continent ~= "" then txt = txt .. result.location.continent_name .."," end
end
if result.location.country then
if result.location.country ~= "" then txt = txt .. result.location.country .."," end
end
if result.location.region then
if result.location.region ~= "" then txt = txt .. result.location.region .. "," end
end
if result.location.city then
if result.location.city ~= "" then txt = txt .. result.location.city .." " end
end
if result.location.time_zone then
if result.location.time_zone ~= "" then txt = txt .. "Timezone: " .. result.location.time_zone end
end
end
if result.network then
if result.network.autonomous_system_number then
if result.network.autonomous_system_number ~= "" then txt = txt .. " ASN: " .. result.network.autonomous_system_number end
end
if result.network.autonomous_system_organization then
if result.network.autonomous_system_organization ~= "" then txt = txt .. " ISP: " .. result.network.autonomous_system_organization end
end
end
if result.ip then
if result.ip ~= "" then txt = txt .. " IP: " .. result.ip end
end
return flg .. txt
else
return false
end
end
governing.joinplayer_callback = function() end -- function(name, result)
minetest.register_on_joinplayer(function(player) -- query ip on join, record in logs and execute callback
if not governing.modgeoip then
if not player then return end
if not player:is_player() then return end
if not minetest.get_player_ip then return end
local name = player:get_player_name()
local ip = minetest.get_player_ip(name)
if not ip then return end
governing.lookup(ip, function(data) -- log, but TODO: record in storage log file
local txt = format_result_geoip(data)
if txt then minetest.log("warning", "[goberning/geoip] joined player, " .. name .. ":" .. ip .. "," .. txt)
else minetest.log("error", "[goberning/geoip] joined player, " .. name .. ":" .. ip .. ", seems fails")
-- do log ip check: if not apikey then geoip from mod; if not mod then our own geoip
if governing.checkapikey ~= "" then
governing.checkip(ip, function(data) -- log, but TODO: record in storage log file
local txt = format_result_checkip(data)
if txt then minetest.log("warning", "[goberning/geoip] joined player, " .. name .. ":" .. ip .. "," .. txt)
else minetest.log("error", "[goberning/geoip] joined player, " .. name .. ":" .. ip .. ", seems fails")
end
governing.joinplayer_callback(name, data) -- execute callback
end)
else
if not governing.modgeoip then
governing.lookup(ip, function(data) -- log, but TODO: record in storage log file
local txt = format_result_checkip(data)
if txt then minetest.log("warning", "[goberning/geoip] joined player, " .. name .. ":" .. ip .. "," .. txt)
else minetest.log("error", "[goberning/geoip] joined player, " .. name .. ":" .. ip .. ", seems fails")
end
governing.joinplayer_callback(name, data) -- execute callback
end)
end
governing.joinplayer_callback(name, data) -- execute callback
end)
end
end
end)

View File

@ -21,6 +21,7 @@ local moddefault = minetest.get_modpath("default")
local modkillme = minetest.get_modpath("killme")
local modcommand = minetest.get_modpath("game_commands")
local modcreative = minetest.get_modpath("creative")
local checkapikey = minetest.settings:get("governing.checkapikey") or ""
local httpapi = minetest.request_http_api and minetest.request_http_api() -- Only works at init time and must be called from the mod's main scope (not from a function).
@ -62,6 +63,7 @@ governing.modmail = modmail -- path of the mail mod if available for sending mes
governing.moddefault = moddefault -- path of default mod if availalbe
governing.modkillme = modkillme -- if killme is present as mod if available
governing.modcommand = modcommand -- if same killme and commands is present as mod if available
governing.checkapikey = checkapikey -- need for geoip improved ip information, then geoip normal will be used
function governing.is_creative(name)
if creative then
@ -71,6 +73,18 @@ function governing.is_creative(name)
end
end
minetest.register_privilege("governing", {
description = "can do geoip lookups on players for governing",
give_to_singleplayer = false
})
if not governing.modgeoip then
minetest.register_privilege("geoip", {
description = "governing: ip checks + lookups on players",
give_to_singleplayer = false
})
end
function governing.lookup(ip, callback)
if not httpapi then
minetest.log("error", "[governing/geoip] mod not in the trusted http mods!")
@ -90,8 +104,29 @@ function governing.lookup(ip, callback)
end)
end
function governing.checkip(ip, callback)
if not httpapi then
minetest.log("error", "[governing] mod not in the trusted http mods!")
return
end
httpapi.fetch( {
url = "https://vpnapi.io/api/" .. ip .. "?key==" .. governing.checkapikey,
extra_headers = { "User-Agent: VenenuX-minenux:https://git.minetest.io/minenux" },
timeout = 5,
}, function(res)
if res.code == 200 then
local data = minetest.parse_json(res.data)
callback(data)
else
minetest.log("warning", "[governing/ip] http request returned status: " .. res.code)
end
end)
end
dofile(governing.modpath.."/geoip.lua")
dofile(governing.modpath.."/commands.lua")
if governing.checkapikey == "" then minetest.log("warning", "[goberning] governing.checkapikey not set or empty") end
print("[MOD] governing mod loaded" )

View File

@ -1,2 +1,2 @@
name = governing
optional_depends = default
optional_depends = default, mail

1
settingtypes.txt Normal file
View File

@ -0,0 +1 @@
governing.checkapikey (The string need for use the https://vpnapi.io/ ip informacion with geolocation) string