From aab26f5b9da0e1bc28a1a2c28793a386757ea27f Mon Sep 17 00:00:00 2001 From: = <=> Date: Wed, 6 Dec 2023 09:58:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=89=E5=85=A8=E7=BB=84=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../neutrinoproxy/core/util/IpUtil.java | 18 +++ .../controller/PortMappingController.java | 25 ++++ .../server/controller/SecurityController.java | 65 +++++---- .../res/system/SecurityGroupListReq.java | 19 --- .../res/system/SecurityGroupRes.java | 47 +++++++ ...yRuleListRes.java => SecurityRuleRes.java} | 4 +- .../server/dal/entity/SecurityGroupDO.java | 18 +++ .../server/dal/entity/SecurityRuleDO.java | 9 ++ .../proxy/core/TcpVisitorChannelHandler.java | 16 ++- .../server/service/PortMappingService.java | 34 +++++ .../server/service/SecurityGroupService.java | 126 +++++++++++++++++- .../resources/sql/mysql/init-structure.sql | 1 + 12 files changed, 325 insertions(+), 57 deletions(-) create mode 100644 neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/util/IpUtil.java delete mode 100644 neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/res/system/SecurityGroupListReq.java create mode 100644 neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/res/system/SecurityGroupRes.java rename neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/res/system/{SecurityRuleListRes.java => SecurityRuleRes.java} (92%) diff --git a/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/util/IpUtil.java b/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/util/IpUtil.java new file mode 100644 index 00000000..74ec5859 --- /dev/null +++ b/neutrino-proxy-core/src/main/java/org/dromara/neutrinoproxy/core/util/IpUtil.java @@ -0,0 +1,18 @@ +package org.dromara.neutrinoproxy.core.util; + +import io.netty.channel.ChannelHandlerContext; + +import java.net.InetSocketAddress; + +public class IpUtil extends org.noear.solon.core.util.IpUtil { + + public static String getRemoteIp(ChannelHandlerContext ctx) { + String remoteAddress = ""; + InetSocketAddress socketAddress = (InetSocketAddress) ctx.channel().remoteAddress(); + if (socketAddress != null) { + remoteAddress = socketAddress.getAddress().getHostAddress(); + } + return remoteAddress; + } + +} diff --git a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/PortMappingController.java b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/PortMappingController.java index e9f536e0..5cde88c9 100644 --- a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/PortMappingController.java +++ b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/PortMappingController.java @@ -13,6 +13,8 @@ import org.dromara.neutrinoproxy.server.util.ParamCheckUtil; import org.apache.commons.lang3.StringUtils; import org.noear.solon.annotation.*; +import java.util.List; + /** * 端口映射 * @author: aoshiguchen @@ -119,4 +121,27 @@ public class PortMappingController { portMappingService.delete(req.getId()); } + + /** + * 绑定安全组 + * @param portMappingId 端口映射Id + * @param securityGroupId 安全组Id + */ + @Post + @Mapping("/bind/security-group") + public void bindSecurityGroup(Integer portMappingId, Integer securityGroupId) { + portMappingService.portBindSecurityGroup(portMappingId, securityGroupId); + } + + /** + * 安全组解绑 + * @param portMappingId 端口映射Id + */ + @Post + @Mapping("/unbind/security-group") + public void unbindSecurityGroup(Integer portMappingId) { + portMappingService.portUnbindSecurityGroup(portMappingId); + } + + } diff --git a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/SecurityController.java b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/SecurityController.java index d3514afe..443965aa 100644 --- a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/SecurityController.java +++ b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/SecurityController.java @@ -1,108 +1,117 @@ package org.dromara.neutrinoproxy.server.controller; -import org.dromara.neutrinoproxy.server.base.page.PageInfo; +import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum; import org.dromara.neutrinoproxy.server.controller.req.system.SecurityGroupCreateReq; import org.dromara.neutrinoproxy.server.controller.req.system.SecurityGroupUpdateReq; -import org.dromara.neutrinoproxy.server.controller.res.system.SecurityGroupListReq; -import org.dromara.neutrinoproxy.server.controller.res.system.SecurityRuleListRes; -import org.noear.solon.annotation.Controller; -import org.noear.solon.annotation.Get; -import org.noear.solon.annotation.Mapping; -import org.noear.solon.annotation.Post; +import org.dromara.neutrinoproxy.server.controller.req.system.SecurityRuleCreateReq; +import org.dromara.neutrinoproxy.server.controller.req.system.SecurityRuleUpdateReq; +import org.dromara.neutrinoproxy.server.controller.res.system.SecurityGroupRes; +import org.dromara.neutrinoproxy.server.controller.res.system.SecurityRuleRes; +import org.dromara.neutrinoproxy.server.dal.entity.SecurityGroupDO; +import org.dromara.neutrinoproxy.server.dal.entity.SecurityRuleDO; +import org.dromara.neutrinoproxy.server.service.PortMappingService; +import org.dromara.neutrinoproxy.server.service.SecurityGroupService; +import org.noear.solon.annotation.*; import java.util.List; +import java.util.stream.Collectors; @Controller @Mapping("/security") public class SecurityController { + @Inject + private SecurityGroupService groupService; + + @Inject + private PortMappingService portMappingService; /** * 获取当前用户权限下的安全组 */ @Get @Mapping("/group/s") - public List getGroups() { - - return null; + public List getGroups() { + List groupDOList = groupService.queryGroupList(); + return groupDOList.stream().map(SecurityGroupDO::toRes).collect(Collectors.toList()); } @Post @Mapping("/group/create") public void createGroup(SecurityGroupCreateReq req) { - + groupService.createGroup(req); } @Post @Mapping("/group/update") public void updateGroup(SecurityGroupUpdateReq req) { - + groupService.updateGroup(req); } /** - * 将级联删除对应规则 + * 将级联删除对应规则,并更新缓存 * @param groupId */ @Post @Mapping("/group/delete") - public void updateGroup(Integer groupId) { - + public void deleteGroup(Integer groupId) { + groupService.deleteGroup(groupId); } @Post @Mapping("/group/enable") public void enableGroup(Integer groupId) { - + groupService.setGroupStatus(groupId, EnableStatusEnum.ENABLE); } @Post @Mapping("/group/disable") public void disableGroup(Integer groupId) { - + groupService.setGroupStatus(groupId, EnableStatusEnum.DISABLE); } @Post @Mapping("/port/bind/group") public void portBindGroup(Integer portId, Integer groupId) { - + portMappingService.portBindGroup(portId, groupId); } @Get @Mapping("/rule/s") - public List getRulesByGroupId(Integer groupId) { - - return null; + public List getRulesByGroupId(Integer groupId) { + List ruleDOList = groupService.queryRuleListByGroupId(groupId); + return ruleDOList.stream().map(SecurityRuleDO::toRes).collect(Collectors.toList()); } @Post @Mapping("/rule/create") - public void createRule() { - + public void createRule(SecurityRuleCreateReq req) { + groupService.createRule(req); } @Post @Mapping("/rule/update") - public void updateRule() { - + public void updateRule(SecurityRuleUpdateReq req) { + groupService.updateRule(req); } @Post @Mapping("/rule/delete") public void deleteRule(Integer ruleId) { - + groupService.deleteRule(ruleId); } @Post @Mapping("/rule/enable") public void enableRule(Integer ruleId) { - + groupService.setRuleStatus(ruleId, EnableStatusEnum.ENABLE); } @Post @Mapping("/rule/disable") public void disableRule(Integer ruleId) { - + groupService.setRuleStatus(ruleId, EnableStatusEnum.DISABLE); } } diff --git a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/res/system/SecurityGroupListReq.java b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/res/system/SecurityGroupListReq.java deleted file mode 100644 index 8d39485b..00000000 --- a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/res/system/SecurityGroupListReq.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.dromara.neutrinoproxy.server.controller.res.system; - -import lombok.Data; - -@Data -public class SecurityGroupListReq { - - private Integer id; - - /** - * 组名 - */ - private String name; - - /** - * 描述 - */ - private String description; -} diff --git a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/res/system/SecurityGroupRes.java b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/res/system/SecurityGroupRes.java new file mode 100644 index 00000000..656154b8 --- /dev/null +++ b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/res/system/SecurityGroupRes.java @@ -0,0 +1,47 @@ +package org.dromara.neutrinoproxy.server.controller.res.system; + +import lombok.Data; +import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum; +import org.dromara.neutrinoproxy.server.constant.SecurityRulePassTypeEnum; + +import java.util.Date; + +@Data +public class SecurityGroupRes { + + private Integer id; + + /** + * 组名 + */ + private String name; + + /** + * 描述 + */ + private String description; + + /** + * 启用状态 + * {@link EnableStatusEnum} + */ + private String enable; + + /** + * 默认放行类型 + * {@link SecurityRulePassTypeEnum} + */ + private String defaultPassType; + + /** + * 创建时间 + */ + private Date createTime; + /** + * 更新时间 + */ + private Date updateTime; + + + +} diff --git a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/res/system/SecurityRuleListRes.java b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/res/system/SecurityRuleRes.java similarity index 92% rename from neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/res/system/SecurityRuleListRes.java rename to neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/res/system/SecurityRuleRes.java index a71fbae0..31b94869 100644 --- a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/res/system/SecurityRuleListRes.java +++ b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/controller/res/system/SecurityRuleRes.java @@ -8,7 +8,7 @@ import org.dromara.neutrinoproxy.server.constant.SecurityRulePassTypeEnum; @Data @ToString @Accessors(chain = true) -public class SecurityRuleListRes { +public class SecurityRuleRes { private Integer id; @@ -41,7 +41,7 @@ public class SecurityRuleListRes { * 放行类型,reject 或 allow * {@link SecurityRulePassTypeEnum} */ - private SecurityRulePassTypeEnum passType; + private String passType; /** * 优先级,数字越小,优先级越高 diff --git a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/dal/entity/SecurityGroupDO.java b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/dal/entity/SecurityGroupDO.java index b1129c7b..b98a1072 100644 --- a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/dal/entity/SecurityGroupDO.java +++ b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/dal/entity/SecurityGroupDO.java @@ -1,5 +1,6 @@ package org.dromara.neutrinoproxy.server.dal.entity; +import cn.hutool.core.bean.BeanUtil; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -7,6 +8,8 @@ import lombok.Data; import lombok.ToString; import lombok.experimental.Accessors; import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum; +import org.dromara.neutrinoproxy.server.constant.SecurityRulePassTypeEnum; +import org.dromara.neutrinoproxy.server.controller.res.system.SecurityGroupRes; import java.util.Date; @@ -39,6 +42,13 @@ public class SecurityGroupDO { * {@link EnableStatusEnum} */ private EnableStatusEnum enable; + + /** + * 默认放行类型 + * {@link SecurityRulePassTypeEnum} + */ + private SecurityRulePassTypeEnum defaultPassType; + /** * 创建时间 */ @@ -48,5 +58,13 @@ public class SecurityGroupDO { */ private Date updateTime; + public SecurityGroupRes toRes() { + SecurityGroupRes res = new SecurityGroupRes(); + BeanUtil.copyProperties(this, res); + res.setEnable(enable.getDesc()); + res.setDefaultPassType(defaultPassType.getDesc()); + return res; + } + } diff --git a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/dal/entity/SecurityRuleDO.java b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/dal/entity/SecurityRuleDO.java index 128940d4..2b0c8525 100644 --- a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/dal/entity/SecurityRuleDO.java +++ b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/dal/entity/SecurityRuleDO.java @@ -1,5 +1,6 @@ package org.dromara.neutrinoproxy.server.dal.entity; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.net.Ipv4Util; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.annotation.IdType; @@ -10,6 +11,7 @@ import lombok.ToString; import lombok.experimental.Accessors; import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum; import org.dromara.neutrinoproxy.server.constant.SecurityRulePassTypeEnum; +import org.dromara.neutrinoproxy.server.controller.res.system.SecurityRuleRes; import java.util.Date; @@ -139,4 +141,11 @@ public class SecurityRuleDO { return SecurityRulePassTypeEnum.NONE; } + public SecurityRuleRes toRes() { + SecurityRuleRes res = new SecurityRuleRes(); + BeanUtil.copyProperties(this, res); + res.setPassType(this.passType.getDesc()); + return res; + } + } diff --git a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/core/TcpVisitorChannelHandler.java b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/core/TcpVisitorChannelHandler.java index 3110dec7..8dcb9bda 100644 --- a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/core/TcpVisitorChannelHandler.java +++ b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/proxy/core/TcpVisitorChannelHandler.java @@ -9,11 +9,15 @@ import io.netty.channel.SimpleChannelInboundHandler; import lombok.extern.slf4j.Slf4j; import org.dromara.neutrinoproxy.core.Constants; import org.dromara.neutrinoproxy.core.ProxyMessage; +import org.dromara.neutrinoproxy.core.util.IpUtil; import org.dromara.neutrinoproxy.server.constant.NetworkProtocolEnum; import org.dromara.neutrinoproxy.server.proxy.domain.VisitorChannelAttachInfo; import org.dromara.neutrinoproxy.server.service.FlowReportService; +import org.dromara.neutrinoproxy.server.service.PortMappingService; +import org.dromara.neutrinoproxy.server.service.SecurityGroupService; import org.dromara.neutrinoproxy.server.util.ProxyUtil; import org.noear.solon.Solon; +import org.noear.solon.annotation.Inject; import java.net.InetSocketAddress; @@ -25,6 +29,12 @@ import java.net.InetSocketAddress; @Slf4j public class TcpVisitorChannelHandler extends SimpleChannelInboundHandler { + @Inject + private SecurityGroupService securityGroupService; + + @Inject + private PortMappingService portMappingService; + @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // 当出现异常就关闭连接 @@ -64,7 +74,11 @@ public class TcpVisitorChannelHandler extends SimpleChannelInboundHandler portToSecurityGroupMap = new ConcurrentHashMap<>(); + public PageInfo page(PageQuery pageQuery, PortMappingListReq req) { if (StringUtils.isNotEmpty(req.getDescription())) { //描述字段为模糊查询,在应用层处理,否则sqlite不支持 @@ -281,6 +285,28 @@ public class PortMappingService implements LifecycleBean { } } + public void portBindSecurityGroup(Integer portMappingId, Integer groupId) { + PortMappingDO mappingDO = portMappingMapper.findById(portMappingId); + if (mappingDO == null) { + throw new RuntimeException("指定的端口映射不存在"); + } + mappingDO.setSecurityGroupId(groupId); + mappingDO.setUpdateTime(new Date()); + portMappingMapper.updateById(mappingDO); + portToSecurityGroupMap.put(mappingDO.getServerPort(), groupId); + } + + public void portUnbindSecurityGroup(Integer portMappingId) { + PortMappingDO mappingDO = portMappingMapper.findById(portMappingId); + if (mappingDO == null) { + throw new RuntimeException("指定的端口映射不存在"); + } + mappingDO.setSecurityGroupId(null); + mappingDO.setUpdateTime(new Date()); + portMappingMapper.updateById(mappingDO); + portToSecurityGroupMap.remove(mappingDO.getServerPort()); + } + /** * 根据license查询可用的端口映射列表 * @@ -291,6 +317,11 @@ public class PortMappingService implements LifecycleBean { return portMappingMapper.findEnableListByLicenseId(licenseId); } + public Integer getSecurityGroupIdByMappingPor(Integer port) { + return portToSecurityGroupMap.get(port); + } + + /** * 服务端项目停止、启动时,更新在线状态为离线 */ @@ -315,6 +346,9 @@ public class PortMappingService implements LifecycleBean { return; } ProxyUtil.setSubdomainToServerPort(item.getSubdomain(), item.getServerPort()); + if (item.getSecurityGroupId() != null) { + portToSecurityGroupMap.put(item.getServerPort(), item.getSecurityGroupId()); + } }); } diff --git a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/service/SecurityGroupService.java b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/service/SecurityGroupService.java index cea9c78c..29398c02 100644 --- a/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/service/SecurityGroupService.java +++ b/neutrino-proxy-server/src/main/java/org/dromara/neutrinoproxy/server/service/SecurityGroupService.java @@ -2,21 +2,33 @@ package org.dromara.neutrinoproxy.server.service; import cn.hutool.cache.Cache; import cn.hutool.cache.CacheUtil; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import jdk.jshell.Snippet; +import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.solon.annotation.Db; +import org.dromara.neutrinoproxy.server.base.rest.SystemContextHolder; import org.dromara.neutrinoproxy.server.constant.EnableStatusEnum; import org.dromara.neutrinoproxy.server.constant.SecurityRulePassTypeEnum; +import org.dromara.neutrinoproxy.server.controller.req.system.SecurityGroupCreateReq; +import org.dromara.neutrinoproxy.server.controller.req.system.SecurityGroupUpdateReq; +import org.dromara.neutrinoproxy.server.controller.req.system.SecurityRuleCreateReq; +import org.dromara.neutrinoproxy.server.controller.req.system.SecurityRuleUpdateReq; import org.dromara.neutrinoproxy.server.dal.SecurityGroupMapper; import org.dromara.neutrinoproxy.server.dal.SecurityRuleMapper; import org.dromara.neutrinoproxy.server.dal.entity.SecurityGroupDO; import org.dromara.neutrinoproxy.server.dal.entity.SecurityRuleDO; import org.noear.solon.annotation.Component; +import org.noear.solon.annotation.Init; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Component +@Slf4j public class SecurityGroupService { @Db @@ -25,20 +37,119 @@ public class SecurityGroupService { @Db private SecurityRuleMapper securityRuleMapper; - private Map securityGroupMap = new ConcurrentHashMap<>(); + private final Map securityGroupMap = new ConcurrentHashMap<>(); // 允许通过控制的缓存,缓存类型最近最久未使用缓存,容量100,超时时间5分钟 - private Cache ipAllowControlCache = CacheUtil.newLRUCache(100, 1000 * 60 * 5); + private final Cache ipAllowControlCache = CacheUtil.newLRUCache(100, 1000 * 60 * 5); - public void init() { - List groupDOList = securityGroupMapper.selectList(Wrappers.lambdaQuery(SecurityGroupDO.class)); + @Init + public synchronized void init() { + securityGroupMap.clear(); + List groupDOList = securityGroupMapper.selectList(Wrappers.lambdaQuery(SecurityGroupDO.class) + .eq(SecurityGroupDO::getEnable, EnableStatusEnum.ENABLE)); groupDOList.forEach(securityGroupDO -> securityGroupMap.put(securityGroupDO.getId(), securityGroupDO)); + ipAllowControlCache.clear(); } - public boolean judgeAllow(String ip, Integer groupId) { + public void clearCache() { + ipAllowControlCache.clear(); + } + public List queryGroupList() { + return securityGroupMapper.selectList(Wrappers.lambdaQuery(SecurityGroupDO.class) + .eq(SecurityGroupDO::getUserId, SystemContextHolder.getUserId())); + } + + public void createGroup(SecurityGroupCreateReq req) { + SecurityGroupDO groupDO = new SecurityGroupDO(); + BeanUtil.copyProperties(req, groupDO); + groupDO.setUserId(SystemContextHolder.getUserId()); + securityGroupMapper.insert(groupDO); + init(); + } + + public void updateGroup(SecurityGroupUpdateReq req) { + SecurityGroupDO groupDO = securityGroupMapper.selectById(req.getId()); + BeanUtil.copyProperties(req, groupDO); + securityGroupMapper.updateById(groupDO); + init(); + } + + public void setGroupStatus(Integer groupId, EnableStatusEnum statusEnum) { SecurityGroupDO groupDO = securityGroupMap.get(groupId); if (groupDO == null || groupDO.getEnable() == EnableStatusEnum.DISABLE) { + throw new RuntimeException("指定的安全组不存在"); + } + groupDO.setEnable(statusEnum); + securityGroupMapper.updateById(groupDO); + init(); + } + + /** + * 删除安全组,并级联删除安全组下的规则,删除后,需缓存 + * @param groupId + */ + public void deleteGroup(Integer groupId) { + securityGroupMapper.deleteById(groupId); + securityRuleMapper.delete(Wrappers.lambdaQuery(SecurityRuleDO.class) + .eq(SecurityRuleDO::getGroupId, groupId)); + init(); + } + + public List queryRuleListByGroupId(Integer groupId) { + return securityRuleMapper.selectList(Wrappers.lambdaQuery(SecurityRuleDO.class) + .eq(SecurityRuleDO::getGroupId, groupId) + .orderByAsc(SecurityRuleDO::getPriority) + ); + } + + public void createRule(SecurityRuleCreateReq req) { + SecurityRuleDO ruleDO = new SecurityRuleDO(); + BeanUtil.copyProperties(req, ruleDO); + ruleDO.setUserId(SystemContextHolder.getUserId()); + securityRuleMapper.insert(ruleDO); + clearCache(); + } + + public void updateRule(SecurityRuleUpdateReq req) { + SecurityRuleDO ruleDO = securityRuleMapper.selectById(req.getId()); + BeanUtil.copyProperties(req, ruleDO); + securityRuleMapper.updateById(ruleDO); + clearCache(); + } + + public void deleteRule(Integer ruleId) { + securityRuleMapper.deleteById(ruleId); + clearCache(); + } + + public void setRuleStatus(Integer ruleId, EnableStatusEnum statusEnum) { + SecurityRuleDO ruleDO = securityRuleMapper.selectById(ruleId); + ruleDO.setEnable(statusEnum); + ruleDO.setUpdateTime(new Date()); + securityRuleMapper.updateById(ruleDO); + clearCache(); + } + + /** + * 判断ip在该安全组下是否允许,如果安全组没有创建,则放行,默认黑名单规则 + * @param ip 被判断的IP地址 + * @param groupId 安全组Id + * @return 是否放行 + */ + public boolean judgeAllow(String ip, Integer groupId) { + + // 不能判断当前连接的IP,保守处理,拒绝放行 + if (StrUtil.isEmpty(ip)) { + return false; + } + + // 黑名单规则,没有该安全组,则放行 + if (groupId == null) { + return true; + } + SecurityGroupDO groupDO = securityGroupMap.get(groupId); + if (groupDO == null) { return true; } @@ -49,6 +160,7 @@ public class SecurityGroupService { List ruleDOList = securityRuleMapper.selectList(Wrappers.lambdaQuery(SecurityRuleDO.class) .eq(SecurityRuleDO::getGroupId, groupId) + .eq(SecurityRuleDO::getEnable, EnableStatusEnum.ENABLE) .orderByAsc(SecurityRuleDO::getPriority) ); Boolean allow = null; @@ -64,11 +176,11 @@ public class SecurityGroupService { } } + // 当前IP没有匹配到任何一条规则,则使用安全组默认规则 if (allow == null) { - allow = true; + allow = groupDO.getDefaultPassType() == SecurityRulePassTypeEnum.ALLOW; } - // 当前IP没有匹配到任何一条规则,则放行 ipAllowControlCache.put(judgeAllowMapKey, allow); return allow; diff --git a/neutrino-proxy-server/src/main/resources/sql/mysql/init-structure.sql b/neutrino-proxy-server/src/main/resources/sql/mysql/init-structure.sql index e6ea837f..aa422022 100644 --- a/neutrino-proxy-server/src/main/resources/sql/mysql/init-structure.sql +++ b/neutrino-proxy-server/src/main/resources/sql/mysql/init-structure.sql @@ -57,6 +57,7 @@ CREATE TABLE IF NOT EXISTS `security_group` ( `description` varchar(255) COMMENT '安全组描述', `user_id` int NOT NULL COMMENT '用户ID', `enable` int(1) NOT NULL COMMENT '启用状态', + `default_pass_type` int(1) NOT NULL COMMENT '默认放行类型', `create_time` datetime(3) NOT NULL COMMENT '创建时间', `update_time` datetime(3) NOT NULL COMMENT '更新时间', PRIMARY KEY (`id`)