# IP限制策略

<cite>
**本文档引用文件**  
- [restriction.go](file://api/restriction/restriction.go)
- [restriction.go](file://internal/controller/restriction/restriction.go)
- [restriction.go](file://internal/logic/restriction/restriction.go)
- [restriction.go](file://internal/service/restriction.go)
- [restriction.go](file://internal/consts/restriction.go)
- [v_1_restrict_ip_record.go](file://internal/dao/v_1_restrict_ip_record.go)
- [v_1_restrict_ip_order_access.go](file://internal/dao/v_1_restrict_ip_order_access.go)
- [model.go](file://internal/model/restriction.go)
- [restriction_v1_check_ip_allowed.go](file://internal/controller/restriction/restriction_v1_check_ip_allowed.go)
- [rate.go](file://utility/limiter/rate.go)
</cite>

## 目录
1. [简介](#简介)
2. [IP限制策略配置机制](#ip限制策略配置机制)
3. [策略生效流程与优先级规则](#策略生效流程与优先级规则)
4. [与其他安全策略的协同工作](#与其他安全策略的协同工作)
5. [动态策略调整机制](#动态策略调整机制)
6. [业务场景配置示例与最佳实践](#业务场景配置示例与最佳实践)

## 简介
本文档详细阐述kami_backend系统的IP限制策略，涵盖黑白名单机制、封禁时长设置、例外规则配置、策略优先级、与地域限制等安全策略的协同机制，以及基于系统负载或安全事件的动态调整能力。通过本策略，系统可有效防止恶意访问、异常请求和资源滥用，保障服务稳定性和数据安全性。

## IP限制策略配置机制

### 黑白名单定义
系统通过数据库表`restrict_ip_order_access`实现IP黑白名单机制。当IP被标记为限制状态（`RestrictStatus_Disable`）时，即进入黑名单；反之则为白名单。黑白名单的判定基于以下字段：
- `ip`: 被限制的IP地址
- `status`: 状态值，0表示启用（白名单），1表示禁用（黑名单）
- `cardPass`: 关联卡密，实现基于卡密的IP限制
- `deviceId`: 设备ID，支持设备级封禁

黑白名单记录通过`AddToRestrictIP`接口写入，由`V1RestrictIpOrderAccess` DAO操作数据库。

**Section sources**
- [restriction.go](file://internal/service/restriction.go#L31-L31)
- [v_1_restrict_ip_order_access.go](file://internal/dao/v_1_restrict_ip_order_access.go#L21-L23)
- [v_1_restrict_ip_order_access.go](file://internal/model/entity/v_1_restrict_ip_order_access.go#L11-L23)

### 封禁时长设置
系统当前采用永久封禁机制，封禁状态一旦设置，将持续有效直至手动解除。封禁记录存储在`restrict_ip_order_access`表中，通过`status`字段控制。未来可通过扩展`expire_at`字段实现临时封禁功能。

封禁操作由`SetCurrentOrderDisable`方法执行，支持事务处理，确保订单状态与IP限制状态的一致性。

**Section sources**
- [restriction.go](file://internal/logic/restriction/restriction.go#L64-L74)
- [restriction.go](file://internal/service/restriction.go#L27-L27)

### 例外规则配置
系统支持多种例外规则配置，允许特定IP或场景绕过限制：
1. **内网IP例外**：当`IsRestrictInternalIp`为false时，内网IP（RFC1918）自动放行
2. **策略开关控制**：通过`MerchantDeployInfo`中的`IsRestrictCardPass`、`IsRestrictDevice`等布尔字段控制不同维度的限制是否启用
3. **区域白名单**：通过`RestrictArea`字段配置允许访问的省份列表，非列表内IP将被拒绝

例外规则在`CheckIPAllowed`逻辑中统一处理，确保按优先级顺序执行。

**Section sources**
- [restriction_v1_check_ip_allowed.go](file://internal/controller/restriction/restriction_v1_check_ip_allowed.go#L35-L55)

## 策略生效流程与优先级规则

### 策略生效流程
IP限制策略的生效流程如下：
1. 接收客户端请求，获取IP、设备ID、卡密等信息
2. 查询商户部署策略（`MerchantDeployInfo`）
3. 按优先级依次检查各项限制条件
4. 记录本次检查结果到`restrict_ip_order_access`表
5. 返回是否允许访问的结果

```mermaid
flowchart TD
Start([开始]) --> GetStrategy["获取商户限制策略"]
GetStrategy --> CheckCardPass{"卡密限制启用?"}
CheckCardPass --> |是| CheckCardPassExist["检查卡密是否存在限制记录"]
CheckCardPassExist --> |存在| ReturnFalse["返回拒绝"]
CheckCardPass --> |否| CheckDevice{"设备限制启用?"}
CheckDevice --> |是| CheckDeviceExist["检查设备是否存在限制记录"]
CheckDeviceExist --> |存在| ReturnFalse
CheckDevice --> |否| CheckAgent{"代理限制启用?"}
CheckAgent --> |是| CheckProxy["检查是否使用代理"]
CheckProxy --> |是| ReturnFalse
CheckAgent --> |否| CheckPublicIP{"是否公网IP?"}
CheckPublicIP --> |是| CheckIPIsExist["检查IP是否存在限制记录"]
CheckIPIsExist --> |存在| ReturnFalse
CheckPublicIP --> |否| CheckInternalIP{"内网IP限制启用?"}
CheckInternalIP --> |否| ReturnTrue["返回允许"]
CheckInternalIP --> |是| CheckArea{"区域限制配置?"}
CheckArea --> |是| CheckAreaAllowed["检查IP所在省份是否在允许列表"]
CheckAreaAllowed --> |是| ReturnTrue
CheckAreaAllowed --> |否| ReturnFalse
CheckArea --> |否| ReturnTrue
ReturnTrue --> End([结束])
ReturnFalse --> End
```

**Diagram sources**
- [restriction_v1_check_ip_allowed.go](file://internal/controller/restriction/restriction_v1_check_ip_allowed.go#L15-L68)

### 优先级规则
策略检查遵循严格的优先级顺序：
1. 卡密级限制（最高优先级）
2. 设备级限制
3. 代理检测限制
4. IP级限制
5. 内网IP例外规则
6. 地域限制（最低优先级）

此优先级设计确保了更精细的控制策略优先于通用策略，避免例外情况被错误拦截。

**Section sources**
- [restriction_v1_check_ip_allowed.go](file://internal/controller/restriction/restriction_v1_check_ip_allowed.go#L30-L55)

## 与其他安全策略的协同工作

### 与地域限制的协同
IP限制策略与地域限制通过`CheckIPIsAllowed`方法协同工作。系统首先通过IP地理位置服务获取IP所在省份，然后与配置的`RestrictArea`列表进行比对。若IP省份不在允许列表中，则判定为不允许访问。

地域判断支持中英文自动转换，使用拼音库将中文省份名转换为英文进行匹配，确保国际化环境下的准确性。

```mermaid
sequenceDiagram
participant Client as "客户端"
participant Controller as "RestrictionController"
participant Service as "RestrictionService"
participant DAO as "V1RestrictIpRecordDAO"
Client->>Controller : CheckIPAllowed(IP, OrderNo)
Controller->>Service : GetRestrictStrategy(MerchantDeployID)
Service-->>Controller : Strategy
Controller->>Service : CheckIPIsAllowed(IP, Strategy.RestrictArea)
Service->>Service : IsInProvince(IP, RestrictArea)
Service->>DAO : Query IP Record
DAO-->>Service : IP Province
Service->>Service : Compare with RestrictArea
Service-->>Controller : IsAllowed
Controller->>Service : AddToRestrictIP(Result)
Controller-->>Client : Response
```

**Diagram sources**
- [restriction_v1_check_ip_allowed.go](file://internal/controller/restriction/restriction_v1_check_ip_allowed.go#L50-L53)
- [restriction.go](file://internal/logic/restriction/restriction.go#L98-L128)

### 与设备指纹的协同
系统通过`deviceId`实现设备级限制，与IP限制形成多维度防护。当`IsRestrictDevice`启用时，即使IP变化，只要设备ID被封禁，访问仍会被拒绝。设备信息由`RestrictionDeviceInput`结构体收集，包含设备型号、UserAgent等特征。

**Section sources**
- [restriction.go](file://internal/model/restriction.go#L6-L14)
- [restriction.go](file://internal/logic/restriction/restriction.go#L168-L173)

## 动态策略调整机制

### 基于系统负载的调整
虽然当前代码未直接实现基于系统负载的动态调整，但系统架构支持通过外部监控模块集成实现。可通过`SimpleLimiter`限流器（位于`utility/limiter/rate.go`）作为基础组件，当系统负载过高时，动态收紧IP限制策略，如：
- 临时启用内网IP限制
- 缩小允许访问的地域范围
- 降低请求频率阈值

```mermaid
classDiagram
class SimpleLimiter {
+Cap int
+Expire int
+rate []*simpleRateNode
+Allow(key string) bool
+checkAvailable() void
}
class Type {
+CardInfoJdAccountCookieChecker Type
+CardInfoRedeemAccountCookieChecker Type
}
SimpleLimiter --> Type : "使用"
```

**Diagram sources**
- [rate.go](file://utility/limiter/rate.go#L12-L70)

### 基于安全事件的调整
系统可通过分析`restrict_ip_record`表中的异常访问模式，自动触发安全响应。例如，当检测到某个IP在短时间内频繁尝试不同卡密时，可自动调用`AddToRestrictIP`将其加入黑名单。

安全事件响应可通过定时任务或实时流处理系统实现，结合`GetRestrictRecordByIP`和`IsRestrictExistByIP`等查询接口进行模式识别。

**Section sources**
- [restriction.go](file://internal/service/restriction.go#L45-L47)
- [restriction.go](file://internal/logic/restriction/restriction.go#L148-L158)

## 业务场景配置示例与最佳实践

### 高安全性业务场景
对于金融、支付等高安全性要求的业务，推荐配置：
```json
{
  "IsRestrictCardPass": true,
  "IsRestrictDevice": true,
  "IsRestrictAgent": true,
  "IsRestrictIp": true,
  "IsRestrictInternalIp": true,
  "RestrictArea": ["北京", "上海", "广东"]
}
```
此配置实现卡密、设备、代理、IP四重验证，并限制仅允许特定省份访问。

### 开放性业务场景
对于需要广泛访问的开放平台，推荐配置：
```json
{
  "IsRestrictCardPass": true,
  "IsRestrictDevice": false,
  "IsRestrictAgent": false,
  "IsRestrictIp": false,
  "IsRestrictInternalIp": false,
  "RestrictArea": []
}
```
此配置仅对卡密进行限制，允许任意设备、IP和地域访问，适合公开API服务。

### 最佳实践指南
1. **分阶段实施**：先启用卡密限制，再逐步增加其他维度限制
2. **监控与审计**：定期分析`restrict_ip_order_access`表，识别误封情况
3. **例外管理**：为运维、测试预留白名单IP段
4. **性能考虑**：避免过度复杂的限制规则影响请求处理性能
5. **用户通知**：当用户被限制时，提供清晰的错误信息和申诉渠道

**Section sources**
- [restriction_v1_check_ip_allowed.go](file://internal/controller/restriction/restriction_v1_check_ip_allowed.go#L15-L68)
- [restriction.go](file://internal/logic/restriction/restriction.go#L46-L62)