a6-plugin-ip-restriction
概述
ip-restriction 插件根据客户端 IP 地址控制对路由的访问。你可以配置白名单(仅允许列出的 IP)或黑名单(拒绝列出的 IP)。它同时支持 IPv4 和 IPv6 的单个 IP 地址及 CIDR 范围。
适用场景
- 将 API 访问限制为已知 IP 范围,例如办公室、VPN 或合作伙伴网络。
- 阻止恶意 IP 或 IP 范围。
- 将管理端点限制在内部网络中访问。
- 在 IP 层面实施基于地理位置的访问控制。
插件配置参考(路由/服务)
| 字段 | 类型 | 是否必填 | 默认值 | 描述 |
|---|---|---|---|---|
whitelist | 字符串数组 | 条件必填* | — | 允许访问的 IP 或 CIDR 范围 |
blacklist | 字符串数组 | 条件必填* | — | 拒绝访问的 IP 或 CIDR 范围 |
message | string | 否 | "Your IP address is not allowed" | 错误消息(1 至 1024 个字符) |
response_code | integer | 否 | 403 | 拒绝访问时的 HTTP 状态码(403 或 404) |
***约束:**必须且只能配置 whitelist 或 blacklist 中的一项,不能同时使用二者。
IP 匹配方式
- **白名单:**仅当客户端 IP 匹配某个条目时才允许请求,其余请求均被拒绝。
- **黑名单:**当客户端 IP 匹配某个条目时拒绝请求,其余请求均被允许。
- **CIDR 支持:**完全支持 CIDR 表示法,例如
192.168.1.0/24、10.0.0.0/8和2001:db8::/32。 - **IPv4 和 IPv6:**同时支持两种地址族。
- **默认 IP 来源:**使用
$remote_addr,即 TCP 连接中的直接客户端 IP。
分步操作:将 IP 范围加入白名单
1. 创建启用 ip-restriction 的路由
a6 route create -f - <<'EOF'
{
"id": "internal-api",
"uri": "/admin/*",
"plugins": {
"ip-restriction": {
"whitelist": [
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16"
]
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"backend:8080": 1
}
}
}
EOF
2. 验证访问
# From allowed IP (e.g., 10.0.1.5) → 200 OK
curl -i http://127.0.0.1:9080/admin/dashboard
# From blocked IP → 403 Forbidden
# {"message": "Your IP address is not allowed"}
分步操作:将指定 IP 加入黑名单
a6 route create -f - <<'EOF'
{
"id": "public-api",
"uri": "/api/*",
"plugins": {
"ip-restriction": {
"blacklist": [
"203.0.113.0/24",
"198.51.100.42"
],
"message": "Access denied from your network",
"response_code": 403
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"backend:8080": 1
}
}
}
EOF
常见模式
代理后的真实客户端 IP(X-Forwarded-For)
默认情况下,ip-restriction 使用 $remote_addr,即直接连接的客户端 IP,通常是负载均衡器的 IP。若要使用真实客户端 IP,请配合 real-ip 插件:
{
"plugins": {
"real-ip": {
"source": "http_x_forwarded_for",
"trusted_addresses": ["10.0.0.0/8"]
},
"ip-restriction": {
"whitelist": ["203.0.113.0/24"]
}
}
}
**重要:**务必在 real-ip 中设置 trusted_addresses,以防止 IP 欺骗。只能接受来自已知代理 IP 的 X-Forwarded-For。
自定义 404 响应(隐藏端点是否存在)
{
"plugins": {
"ip-restriction": {
"blacklist": ["0.0.0.0/0"],
"whitelist": ["10.0.0.0/8"],
"response_code": 404,
"message": "Not found"
}
}
}
注意:不能同时使用白名单和黑名单。单独使用白名单即可实现相同效果,所有不在白名单中的 IP 都会被拒绝。
IPv6 CIDR 范围
{
"plugins": {
"ip-restriction": {
"whitelist": [
"2001:db8::/32",
"::1"
]
}
}
}
故障排查
| 现象 | 原因 | 解决方法 |
|---|---|---|
| 合法用户被拒绝 | 在代理后使用了 $remote_addr | 添加 real-ip 插件并配置 trusted_addresses |
| 使用白名单后所有用户均被拒绝 | 客户端 IP 不在白名单 CIDR 范围内 | 在客户端使用 curl ifconfig.me 验证 IP 范围 |
| 无法同时使用白名单和黑名单 | 模式通过 oneOf 强制限制 | 仅使用白名单,它会拒绝所有未列出的 IP |
| 修改后 IP 限制未生效 | IP 匹配器使用 LRU 缓存 | 更新路由配置以刷新缓存 |
配置同步示例
version: "1"
routes:
- id: internal-api
uri: /admin/*
plugins:
ip-restriction:
whitelist:
- "10.0.0.0/8"
- "172.16.0.0/12"
upstream_id: admin-upstream
upstreams:
- id: admin-upstream
type: roundrobin
nodes:
"backend:8080": 1
本文根据 api7/a6 仓库中的 a6-plugin-ip-restriction/SKILL.md 生成。可在 AI Agent Skills 页面浏览全部 Skill。