MC服务器异常ip入侵过滤——使用GeoLite2-Country.mmdb离线数据库定位玩家IP归属国家

服务器插件 ipvalidate-for-mcpaper1.21.jar

在搞一些东西时发现了GeoLite2这个数据库,本质上它应该算是一个离线的ip地理数据库,就是可以查询到IP对应的国家或地区,MAXMIND还提供了更具体的城市数据库,似乎也可以查到ip对应的城市位置。

那么言归正传,突然想起来之前我的世界服务器被入侵的鸟事🤬,就是有陌生的玩家闯入未设防的私人服务器,然后在里面搞破坏,或者乱插牌子。查询ip地址发现这些入侵者ip均来自国外虚拟服务提供商。
类似于[个人Minecraft服务器被境外黑客/熊孩子攻击的事例分享]。(https://www.bilibili.com/opus/829121476347035681?spm_id_from=333.1007.0.0&jump_opus=1)

这种类似的入侵其实不难理解,毕竟ipv4的范围也没多大,像咱们一般租用的这种阿里云或者腾讯云的小服务器本身就没啥防御,还在Discord上发现了一个叫ServerSeeker的机器人,声称能扫描到整个互联网的私人服务器。

所以之前的思路是写一个判断玩家的ip地址的paper插件Minecraft服务器被境外黑客/熊孩子入侵——开启IP验证,如果是国外ip就直接踢出去,但是当时采用的方法是插件查询类似http://www.cip.cc/这种网站,然后根据网站返回的结果判断ip属于哪个国家。但问题是这个网站也不太靠谱,经常拒绝访问什么的。

既然有GeoLite2这个东西,那就好办了,直接把数据库放到本地查询呗。

获取GeoLite2-Country.mmdb

从官网下载最新的离线数据库。
MAXMIND_GEOLITE2
在这里插入图片描述
解压后里面的GeoLite2-Country.mmdb就是我们需要的数据库。

代码

一点参考
intellij创建一个新项目,插件市场下载那个Minecraft developer插件
就是这个玩意
新建一个minecraft plugin项目,记得Build System选maven
在这里插入图片描述
在pom.xml里添加依赖

	<dependencies>
        <dependency>
            ...其他的一些依赖...
        </dependency>

        <dependency>
            <groupId>com.maxmind.geoip2</groupId>
            <artifactId>geoip2</artifactId>
            <version>3.0.1</version>
        </dependency>

    </dependencies>

把GeoLite2-Country.mmdb丢到resources文件夹下边
在这里插入图片描述
然后主函数里的代码:

package org.iplocation.ipvalidate;

import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.exception.GeoIp2Exception;
import com.maxmind.geoip2.model.CountryResponse;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.plugin.java.JavaPlugin;

import java.io.File;
import java.io.IOException;
import java.net.InetAddress;

public class Ipvalidate extends JavaPlugin implements Listener {

    private DatabaseReader databaseReader;

    @Override
    public void onEnable() {
        // 加载 GeoLite2 数据库
        try {
            File dbFile = new File(getDataFolder(), "GeoLite2-Country.mmdb");
            if (!dbFile.exists()) {
                saveResource("GeoLite2-Country.mmdb", false);
            }
            databaseReader = new DatabaseReader.Builder(dbFile).build();
            getLogger().info("GeoLite2-Country database loaded successfully.");
        } catch (IOException e) {
            getLogger().severe("Failed to load GeoLite2-Country.mmdb: " + e.getMessage());
            getServer().getPluginManager().disablePlugin(this);
        }

        // 注册事件监听器
        getServer().getPluginManager().registerEvents(this, this);
    }

    @Override
    public void onDisable() {
        // 关闭数据库连接
        if (databaseReader != null) {
            try {
                databaseReader.close();
            } catch (IOException e) {
                getLogger().severe("Failed to close GeoLite2-Country database: " + e.getMessage());
            }
        }
    }

    @EventHandler
    public void onPlayerLogin(PlayerLoginEvent event) {
        String playerName = event.getPlayer().getName();
        InetAddress ipAddress = event.getAddress();
        try {
            String country = getCountryByIp(ipAddress);
            if (!"China".equalsIgnoreCase(country)) {
                event.disallow(PlayerLoginEvent.Result.KICK_OTHER, "You are not welcomed.");
                getLogger().info("Player " + playerName + " was kicked. Country: " + country);

            }

            String message ="Player " + playerName + " enters the game. Player IP: " + ipAddress + " Location: " + country;
            Player player = event.getPlayer();
            player.sendMessage(message);
            Bukkit.broadcastMessage(message);
            getLogger().info(message);

        } catch (Exception e) {
            getLogger().severe("Failed to determine country for IP: " + ipAddress + " - " + e.getMessage());
        }
    }

    // 根据 IP 获取国家名称
    private String getCountryByIp(InetAddress ipAddress) throws IOException, GeoIp2Exception {
        CountryResponse response = databaseReader.country(ipAddress);
        return response.getCountry().getName();
    }

    // 测试函数
    public void testIp(String ipAddress) {
        try {
            InetAddress inetAddress = InetAddress.getByName(ipAddress);
            String country = getCountryByIp(inetAddress);
            getLogger().info("IP: " + ipAddress + " belongs to country: " + country);
        } catch (Exception e) {
            getLogger().severe("Error testing IP: " + ipAddress + " - " + e.getMessage());
        }
    }
}

接下来就可以构建jar包了

在这里插入图片描述
左侧,先双击clean,再双击package
导出的jar包丢到mc服务器的plugin目录下
启动服务器就行了。

ipvalidate-for-mcpaper1.21.jar

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值