java配置nginx网络安全,防止国外ip访问,自动添加黑名单,需手动重新加载nginx

通过访问日志自动添加国外ip黑名单





创建一个类,自己添加一个main启动类即可测试

复制代码
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static java.lang.Character.LINE_SEPARATOR;

@Slf4j
@Component
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class SecurityIp {
    private final static String[] privinces = {"北京市", "天津市", "河北省", "山西省", "内蒙古", "辽宁省", "吉林省", "黑龙江省", "上海市", "江苏省", "浙江省", "安徽省", "福建省", "江西省", "山东省", "河南省", "湖北省", "湖南省", "广东省", "广西", "海南省", "重庆市", "四川省", "贵州省", "云南省", "西藏", "陕西省", "甘肃省", "青海省", "宁夏", "新疆", "台湾省", "香港", "澳门", "此IP属于本地局域网","本地局域网"};

    //nginx的工作空间
    private final static String nginxPath = "F:/zty/testlinux/usr/local/nginx/";
    //nging的access.log路径
    private final static String logPath = nginxPath + "logs/access.log";
    //黑名单配置文件路径
    private final static String blackListPath = nginxPath + "conf/blackListIp.conf";
    private final static String blackListLogPath = nginxPath + "conf/blackListIpLog.log";
    //启动脚本文件路径
    private final static String binPath = nginxPath + "";

    private static String getAddressByIp(String ip) {
        try {
            URL url = new URL("http://opendata.baidu.com/api.php?query=" + ip + "&co=&resource_id=6006&t=1433920989928&ie=utf8&oe=utf-8&format=json");
            URLConnection conn = url.openConnection();
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            String line = null;
            StringBuffer result = new StringBuffer();
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }
            reader.close();
            JSONObject jsStr = new JSONObject(result.toString());
            JSONArray jsData = (JSONArray) jsStr.get("data");
            JSONObject data = (JSONObject) jsData.get(0);//位置
            return (String) data.get("location");
        } catch (IOException e) {
            log.error("getAddressByIp error, ip={},msg={}", ip, e);
            return null;
        }
    }

    /**
     * 扫描非法IP
     * 每隔30秒扫描一次非法IP并加入黑名单
     */
    @Scheduled(fixedDelay = 3000)
    public void scanForIllegalIP() throws Exception {
        List<String> ips = getIps();// 将当前检测国外ip加入黑名单并且返回
        if(ips.size() > 0) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            System.out.println("deny,国外ip:" + ips + "已写入nginx黑名单列表"+sdf.format(new Date()));
        }
    }

    /**
     * 获取国外ip
     *
     * @return
     */
    private List<String> getIps() {
        File file = new File(logPath);
        if (!file.exists()) {
            log.error("{} not exists", logPath);
            return null;
        }
        try {
            List<String> lines = new ArrayList<>();
            try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    // 获取access.log中ip
                    String ip = line.substring(0, line.indexOf(" - - ["));
                    if (!ip.equals("127.0.0.1")) {
                        String securityIps = securityIps(ip);// 校验ip是否是国外ip,如果是的写入黑名单
                        if (Objects.nonNull(securityIps) && !securityIps.isEmpty()) {
                            lines.add(securityIps);// 国外ip加入黑名单的相应
                        }
                    }
                }
            }
            return lines;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 将ip写入黑名单
     *
     * @param ip
     * @return
     */
    private String securityIps(String ip) {
        String location = getAddressByIp(ip);
        if (Objects.nonNull(location) && privinces.length > 0) {
            List<String> lines = new ArrayList<>();
            List<String> notIps = Arrays.stream(privinces).filter(p -> p.contains(location)).collect(Collectors.toList());
            if (Objects.nonNull(notIps) && notIps.size() == 0) {

                // 写入黑名单时先查询此ip是否写入黑名单
                File isExsitfile = new File(blackListPath);
                if (!isExsitfile.exists()) {
                    log.error("{} not exists", logPath);
                    return null;
                }
                try {
                    try (BufferedReader reader = new BufferedReader(new FileReader(isExsitfile))) {
                        String line;
                        while ((line = reader.readLine()) != null) {
                            // 获取blackListIp.conf,判断是否已经写入
                            if (Objects.nonNull(line) && !line.isEmpty() && !line.contains("127.0.0.1") && !line.contains("#")) {
                                String newLines = line.replace(" deny ", "").replace(";", "");
                                lines.add(newLines);
                            }
                        }
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            //第二步,写入非法IP进nginx的blackList文件
            try {
                List<String> isExit = lines.stream().filter(line -> line.contains(ip)).collect(Collectors.toList());
                if (notIps.size()==0&&isExit.size() == 0) {// 国外ip不在白名单中并且没有写入黑名单
                    File file = new File(blackListPath);
                    FileWriter out = new FileWriter(file, true);
                    BufferedWriter bw = new BufferedWriter(out);
                    bw.write(LINE_SEPARATOR);
                    bw.write(" deny " + ip + ";");
                    bw.flush();
                    bw.close();
                    log.info("国外:" + location + "IP:{} 已写入nginx黑名单列表", ip);

                    // 写入nginx黑名单日志
                    File blackListLog = new File(blackListLogPath);
                    FileWriter blackListout = new FileWriter(blackListLog, true);
                    BufferedWriter blackListbw = new BufferedWriter(blackListout);
                    blackListbw.write(LINE_SEPARATOR);
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                    blackListbw.write("deny,国外:" + location + ip + "已写入nginx黑名单列表"+sdf.format(new Date()));
                    blackListbw.flush();
                    blackListbw.close();
                    return ip;
                }

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return "";
    }
}
相关推荐
BillKu23 分钟前
Java + Spring Boot + Mybatis 插入数据后,获取自增 id 的方法
java·tomcat·mybatis
全栈凯哥24 分钟前
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
java·算法·leetcode·链表
chxii25 分钟前
12.7Swing控件6 JList
java
全栈凯哥27 分钟前
Java详解LeetCode 热题 100(27):LeetCode 21. 合并两个有序链表(Merge Two Sorted Lists)详解
java·算法·leetcode·链表
YuTaoShao27 分钟前
Java八股文——集合「List篇」
java·开发语言·list
PypYCCcccCc32 分钟前
支付系统架构图
java·网络·金融·系统架构
冰橙子id36 分钟前
centos7编译安装LNMP架构
mysql·nginx·架构·centos·php
华科云商xiao徐1 小时前
Java HttpClient实现简单网络爬虫
java·爬虫
扎瓦1 小时前
ThreadLocal 线程变量
java·后端
BillKu1 小时前
Java后端检查空条件查询
java·开发语言