From aeb0696f457ca85b62d15ab6586c5779cf5cd97b Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Fri, 31 Jul 2026 16:56:21 +0800
Subject: [PATCH] feat(firewall): 添加访问日志功能
---
src/main/java/cc/mrbird/febs/firewall/nginx/NginxConfigGenerator.java | 93 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 93 insertions(+), 0 deletions(-)
diff --git a/src/main/java/cc/mrbird/febs/firewall/nginx/NginxConfigGenerator.java b/src/main/java/cc/mrbird/febs/firewall/nginx/NginxConfigGenerator.java
new file mode 100644
index 0000000..661b82b
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/firewall/nginx/NginxConfigGenerator.java
@@ -0,0 +1,93 @@
+package cc.mrbird.febs.firewall.nginx;
+
+import cc.mrbird.febs.firewall.entity.FirewallSite;
+import cc.mrbird.febs.firewall.mapper.FirewallCountryRuleMapper;
+import cc.mrbird.febs.firewall.mapper.FirewallSiteMapper;
+import cn.hutool.core.io.FileUtil;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+/**
+ * Nginx 国家黑名单配置文件生成器
+ * <p>
+ * 默认放行所有国家,仅拦截配置中选中的国家(黑名单模式)。
+ * <p>
+ * 输出文件: /etc/nginx/conf.d/firewall_country_{siteId}.conf
+ * <p>
+ * 不直接执行 reload,仅负责文件生成。
+ * reload 由 NginxReloadTask 消费 Redis 队列后执行,防止误操作。
+ *
+ * @author auto-generated
+ * @date 2026-07-31
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class NginxConfigGenerator {
+
+ private final FirewallCountryRuleMapper mapper;
+ private final FirewallSiteMapper siteMapper;
+
+ /** Nginx 配置目录 */
+ private static final String NGINX_CONF_DIR = "/etc/nginx/conf.d/";
+ /** 配置文件前缀 */
+ private static final String CONF_PREFIX = "firewall_country_";
+
+ /**
+ * 生成 Nginx 国家黑名单 map 配置
+ * <pre>
+ * map $geoip_country_code $allow_country {
+ * default 1;
+ * JP 0;
+ * US 0;
+ * }
+ * </pre>
+ * default 1 表示默认放行,列表中国家设为 0 表示拦截。
+ * Nginx 中判断: if ($allow_country_1 = 0) { return 403; }
+ *
+ * @param siteId 站点ID
+ */
+ public void generate(Long siteId) {
+ // 查询站点配置路径
+ FirewallSite site = siteMapper.selectById(siteId);
+ if (site == null) {
+ log.warn("防火墙站点不存在: siteId={}", siteId);
+ return;
+ }
+
+ List<String> countries = mapper.selectEnableCountry(siteId);
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("# Firewall Country Block Map (Blacklist)\n");
+ sb.append("# Site: ").append(site.getSiteName()).append(" (").append(site.getDomain()).append(")\n");
+ sb.append("# Generated at: ").append(new java.util.Date()).append("\n\n");
+ sb.append("map $geoip_country_code $allow_country_").append(siteId).append(" {\n");
+ sb.append(" default 1;\n");
+
+ for (String c : countries) {
+ sb.append(" ").append(c.toUpperCase()).append(" 0;\n");
+ }
+
+ sb.append("}\n");
+
+ // 写入文件
+ String confFileName = site.getNginxConf();
+ if (confFileName == null || confFileName.isEmpty()) {
+ confFileName = NGINX_CONF_DIR + CONF_PREFIX + siteId + ".conf";
+ }
+
+ File confFile = new File(confFileName);
+ try {
+ FileUtil.writeString(sb.toString(), confFile, StandardCharsets.UTF_8);
+ log.info("Nginx 黑名单配置已生成: {}, 拦截国家: {}", confFile.getAbsolutePath(), countries);
+ } catch (Exception e) {
+ log.error("Nginx 配置文件写入失败: path={}", confFile.getAbsolutePath(), e);
+ throw new RuntimeException("Nginx 配置文件写入失败: " + e.getMessage(), e);
+ }
+ }
+}
--
Gitblit v1.9.1