| | |
| | | import cc.mrbird.febs.common.utils.RedisUtils; |
| | | import cc.mrbird.febs.firewall.dto.CountryVo; |
| | | import cc.mrbird.febs.firewall.entity.FirewallCountryRule; |
| | | import cc.mrbird.febs.firewall.entity.FirewallIpWhite; |
| | | import cc.mrbird.febs.firewall.entity.FirewallSite; |
| | | import cc.mrbird.febs.firewall.mapper.FirewallCountryRuleMapper; |
| | | import cc.mrbird.febs.firewall.mapper.FirewallIpWhiteMapper; |
| | | import cc.mrbird.febs.firewall.mapper.FirewallSiteMapper; |
| | | import cc.mrbird.febs.firewall.nginx.IpWhitelistNginxConfigGenerator; |
| | | import cc.mrbird.febs.firewall.nginx.NginxConfigGenerator; |
| | | import cc.mrbird.febs.firewall.service.IFirewallRuleService; |
| | | import cn.hutool.core.util.StrUtil; |
| | |
| | | public class FirewallRuleServiceImpl implements IFirewallRuleService { |
| | | |
| | | private final FirewallCountryRuleMapper countryRuleMapper; |
| | | private final FirewallIpWhiteMapper ipWhiteMapper; |
| | | private final FirewallSiteMapper siteMapper; |
| | | private final NginxConfigGenerator generator; |
| | | private final IpWhitelistNginxConfigGenerator ipWhitelistGenerator; |
| | | private final RedisUtils redisUtils; |
| | | |
| | | /** Redis 中 Nginx reload 任务队列 key */ |
| | |
| | | // 删除站点关联的国家规则 |
| | | countryRuleMapper.delete(new LambdaQueryWrapper<FirewallCountryRule>() |
| | | .eq(FirewallCountryRule::getSiteId, id)); |
| | | // 删除Nginx配置文件 |
| | | // 删除站点关联的IP白名单 |
| | | ipWhiteMapper.delete(new LambdaQueryWrapper<FirewallIpWhite>() |
| | | .eq(FirewallIpWhite::getSiteId, id)); |
| | | // 删除Nginx配置文件(国家黑名单 + IP白名单) |
| | | if (StrUtil.isNotBlank(site.getNginxConf())) { |
| | | cn.hutool.core.io.FileUtil.del(site.getNginxConf()); |
| | | } |
| | | cn.hutool.core.io.FileUtil.del(IpWhitelistNginxConfigGenerator.getConfPath(id)); |
| | | siteMapper.deleteById(id); |
| | | log.info("防火墙站点已删除: id={}, name={}", id, site.getSiteName()); |
| | | return new FebsResponse().success().message("删除成功"); |
| | |
| | | private void regenerateNginxConfig(Long siteId) { |
| | | try { |
| | | generator.generate(siteId); |
| | | ipWhitelistGenerator.generate(siteId); |
| | | redisUtils.lSet(NGINX_RELOAD_QUEUE_KEY, String.valueOf(siteId)); |
| | | log.info("Nginx reload 信号已入队: siteId={}", siteId); |
| | | } catch (Exception e) { |
| | |
| | | |
| | | // 3. 生成 Nginx 配置文件 |
| | | generator.generate(siteId); |
| | | ipWhitelistGenerator.generate(siteId); |
| | | |
| | | // 4. 发送 reload 信号 |
| | | redisUtils.lSet(NGINX_RELOAD_QUEUE_KEY, String.valueOf(siteId)); |
| | |
| | | @Override |
| | | public void triggerNginxReload(Long siteId) { |
| | | generator.generate(siteId); |
| | | ipWhitelistGenerator.generate(siteId); |
| | | redisUtils.lSet(NGINX_RELOAD_QUEUE_KEY, String.valueOf(siteId)); |
| | | log.info("手动触发 Nginx reload: siteId={}", siteId); |
| | | } |
| | | |
| | | // ==================== IP白名单管理 ==================== |
| | | |
| | | @Override |
| | | public IPage<FirewallIpWhite> ipWhiteList(FirewallIpWhite ipWhite, QueryRequest request) { |
| | | Page<FirewallIpWhite> page = new Page<>(request.getPageNum(), request.getPageSize()); |
| | | LambdaQueryWrapper<FirewallIpWhite> wrapper = new LambdaQueryWrapper<FirewallIpWhite>() |
| | | .eq(ipWhite.getSiteId() != null, FirewallIpWhite::getSiteId, ipWhite.getSiteId()) |
| | | .eq(ipWhite.getEnabled() != null, FirewallIpWhite::getEnabled, ipWhite.getEnabled()) |
| | | .like(StrUtil.isNotBlank(ipWhite.getIp()), FirewallIpWhite::getIp, ipWhite.getIp()) |
| | | .like(StrUtil.isNotBlank(ipWhite.getRemark()), FirewallIpWhite::getRemark, ipWhite.getRemark()) |
| | | .orderByDesc(FirewallIpWhite::getCreatedTime); |
| | | return ipWhiteMapper.selectPage(page, wrapper); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public FebsResponse saveIpWhite(FirewallIpWhite ipWhite) { |
| | | if (ipWhite.getSiteId() == null) { |
| | | return new FebsResponse().fail().message("请选择站点"); |
| | | } |
| | | if (StrUtil.isBlank(ipWhite.getIp())) { |
| | | return new FebsResponse().fail().message("IP地址不能为空"); |
| | | } |
| | | ipWhite.setIp(ipWhite.getIp().trim()); |
| | | |
| | | if (ipWhite.getId() != null) { |
| | | ipWhiteMapper.updateById(ipWhite); |
| | | log.info("防火墙IP白名单已更新: id={}, siteId={}, ip={}", ipWhite.getId(), ipWhite.getSiteId(), ipWhite.getIp()); |
| | | } else { |
| | | // 检查同站点下是否已存在相同IP |
| | | Integer count = ipWhiteMapper.selectCount(new LambdaQueryWrapper<FirewallIpWhite>() |
| | | .eq(FirewallIpWhite::getSiteId, ipWhite.getSiteId()) |
| | | .eq(FirewallIpWhite::getIp, ipWhite.getIp())); |
| | | if (count > 0) { |
| | | return new FebsResponse().fail().message("该站点下已存在相同IP: " + ipWhite.getIp()); |
| | | } |
| | | ipWhiteMapper.insert(ipWhite); |
| | | log.info("防火墙IP白名单已新增: siteId={}, ip={}", ipWhite.getSiteId(), ipWhite.getIp()); |
| | | } |
| | | |
| | | // 保存后自动生成Nginx配置并发送reload信号 |
| | | ipWhitelistGenerator.generate(ipWhite.getSiteId()); |
| | | redisUtils.lSet(NGINX_RELOAD_QUEUE_KEY, String.valueOf(ipWhite.getSiteId())); |
| | | return new FebsResponse().success().message("保存成功,Nginx 配置已更新"); |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public FebsResponse deleteIpWhite(Long id) { |
| | | FirewallIpWhite ipWhite = ipWhiteMapper.selectById(id); |
| | | if (ipWhite == null) { |
| | | return new FebsResponse().fail().message("IP白名单不存在"); |
| | | } |
| | | Long siteId = ipWhite.getSiteId(); |
| | | ipWhiteMapper.deleteById(id); |
| | | log.info("防火墙IP白名单已删除: id={}, siteId={}, ip={}", id, siteId, ipWhite.getIp()); |
| | | |
| | | // 删除后自动生成Nginx配置并发送reload信号 |
| | | ipWhitelistGenerator.generate(siteId); |
| | | redisUtils.lSet(NGINX_RELOAD_QUEUE_KEY, String.valueOf(siteId)); |
| | | return new FebsResponse().success().message("删除成功,Nginx 配置已更新"); |
| | | } |
| | | } |