Compare commits
1 commit
main
...
release-5.
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2262b36606 |
5
.dockerignore
Normal file
|
@ -0,0 +1,5 @@
|
|||
website/node_modules
|
||||
website/build
|
||||
website/.docusaurus
|
||||
|
||||
blazehttp/.github
|
30
.github/ISSUE_TEMPLATE/1feature-request.yaml
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
name: 功能建议
|
||||
# Feature request
|
||||
description: 新功能或现有能力的优化建议
|
||||
title: "[建议] "
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
提示:创建前请搜索一下是否有重复问题。一个 issue 尽量只描述一个问题。简洁、准确的描述有助于集中大家的意见,推进问题尽快解决
|
||||
# Please check for duplicate issue first.
|
||||
# 尽量描述需求的背景、原始问题,避免出现 X-Y 问题,参考: https://coolshell.cn/articles/10804.html
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: 背景与遇到的问题
|
||||
# Background and the problem that frustrates you
|
||||
placeholder: |
|
||||
例如:我的业务有xxx特性,当我在使用xxx功能的时候,会遇到xxx情况...
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: solution
|
||||
attributes:
|
||||
label: 建议的解决方案
|
||||
# Describe the solution you'd like
|
||||
placeholder: |
|
||||
例如:建议增加xxx功能;将xxx改为xxx...
|
||||
validations:
|
||||
required: false
|
42
.github/ISSUE_TEMPLATE/2bug-report.yaml
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
name: Bug
|
||||
description: 明确的软件故障或缺陷
|
||||
# Create a report to help us improve
|
||||
title: "[Bug] "
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
提示:提问前请先搜索一下是否存在重复问题
|
||||
# Please check for duplicate issue first.
|
||||
- type: textarea
|
||||
id: Description
|
||||
attributes:
|
||||
label: 问题描述
|
||||
# Describe the bug
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: 版本号
|
||||
placeholder: 3.0.0
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: Reproduce
|
||||
attributes:
|
||||
label: 复现方法
|
||||
# To Reproduce
|
||||
placeholder: |
|
||||
1. ...
|
||||
2. ...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: Expected
|
||||
attributes:
|
||||
label: 期望的结果
|
||||
# Expected behavior. Descript what you expected to happen.
|
||||
validations:
|
||||
required: true
|
14
.github/ISSUE_TEMPLATE/3other.yaml
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
name: 其他问题与反馈
|
||||
description: 文档、部署失败等其他问题。
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
提示:创建前请先搜索一下是否存在重复问题
|
||||
# Please check for duplicate issue first.
|
||||
# 尽量描述需求的背景、原始问题,避免出现 X-Y 问题,参考: https://coolshell.cn/articles/10804.html
|
||||
# 提問的智慧: https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md
|
||||
- type: textarea
|
||||
id: content
|
||||
attributes:
|
||||
label: 反馈内容
|
45
.github/ISSUE_TEMPLATE/bug-report.yaml
vendored
|
@ -1,45 +0,0 @@
|
|||
name: Bug
|
||||
description: Report a bug
|
||||
# Create a report to help us improve
|
||||
title: "[Bug] "
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please search the [open issues](https://github.com/chaitin/SafeLine/issues) and [discussion](https://github.com/chaitin/SafeLine/discussions) for duplicate issue first.
|
||||
The more information you share, the faster we can identify and fix the bug.
|
||||
# Please check for duplicate issue first.
|
||||
- type: textarea
|
||||
id: Description
|
||||
attributes:
|
||||
label: What happened?
|
||||
# Describe the bug
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: Reproduce
|
||||
attributes:
|
||||
label: How we reproduce?
|
||||
description: |
|
||||
Reports cannot be reproduced will Most likely be closed.
|
||||
# To Reproduce
|
||||
value: |
|
||||
1. ...
|
||||
2. ...
|
||||
3. ...
|
||||
- type: textarea
|
||||
id: Expected
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
# placeholder: |
|
||||
# Descript what you expected to happen.
|
||||
# Expected behavior. Descript what you expected to happen.
|
||||
- type: textarea
|
||||
id: Errorlog
|
||||
attributes:
|
||||
label: Error log
|
||||
placeholder: |
|
||||
Paste the error logs if any.
|
||||
# Expected behavior. Descript what you expected to happen.
|
||||
|
10
.github/ISSUE_TEMPLATE/config.yml
vendored
|
@ -1,11 +1,5 @@
|
|||
blank_issues_enabled: false
|
||||
blank_issues_enabled: Ture
|
||||
contact_links:
|
||||
- name: Discord
|
||||
url: https://discord.gg/wyshSVuvxC
|
||||
about: Ask questions and discuss with other SafeLine users in real time.
|
||||
- name: Home page 官网
|
||||
url: https://waf.chaitin.com/
|
||||
about: Get feature descriptions, technical documentation and more information. 获取功能描述、技术文档和更多信息。
|
||||
- name: 绕过反馈
|
||||
url: https://stack.chaitin.com/security-challenge/safeline/index
|
||||
about: Waf 绕过可在 CT Stack 安全挑战赛提交细节
|
||||
about: Waf 绕过可在 CT Stack 安全挑战赛提交细节
|
||||
|
|
28
.github/ISSUE_TEMPLATE/feature-request.yaml
vendored
|
@ -1,28 +0,0 @@
|
|||
name: Suggestion
|
||||
# Feature request
|
||||
description: New feature or improvements.
|
||||
title: "[Suggestion] "
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please search the [open issues](https://github.com/chaitin/SafeLine/issues) and [discussion](https://github.com/chaitin/SafeLine/discussions) for duplicate issue first.
|
||||
Please rise only one suggestion in an issue.
|
||||
- type: textarea
|
||||
id: solution
|
||||
attributes:
|
||||
label: What would you like to be added or improved?
|
||||
# Describe the solution you'd like
|
||||
# placeholder: |
|
||||
#
|
||||
- type: textarea
|
||||
id: problem
|
||||
attributes:
|
||||
label: Why is it needed?
|
||||
# Background and the specific problem that frustrates you
|
||||
placeholder: |
|
||||
Background and the problem that frustrates you
|
||||
|
||||
validations:
|
||||
required: true
|
12
.github/ISSUE_TEMPLATE/other.yaml
vendored
|
@ -1,12 +0,0 @@
|
|||
name: Other
|
||||
description: Other issues such as Doc
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please search the [open issues](https://github.com/chaitin/SafeLine/issues) and [discussion](https://github.com/chaitin/SafeLine/discussions) for duplicate issue first.
|
||||
Please rise only one suggestion in an issue.
|
||||
- type: textarea
|
||||
id: content
|
||||
attributes:
|
||||
label: Content
|
8
.gitmodules
vendored
|
@ -1,5 +1,9 @@
|
|||
[submodule "blazehttp"]
|
||||
path = blazehttp
|
||||
url = https://github.com/chaitin/blazehttp
|
||||
|
||||
|
||||
[submodule "lua-resty-t1k"]
|
||||
path = lua-resty-t1k
|
||||
url = https://github.com/chaitin/lua-resty-t1k
|
||||
[submodule "plugins"]
|
||||
path = plugins
|
||||
url = https://github.com/chaitin/safeline-open-platform
|
||||
|
|
824
CHANGELOG.md
Normal file
|
@ -0,0 +1,824 @@
|
|||
# SAFELINE-CE CHANGELOG
|
||||
|
||||
## [5.2.0] - 2024-03-28
|
||||
|
||||
### 新增
|
||||
|
||||
* 黑白名单、人机验证、身份认证中,规则匹配条件增加 “Method”(请求方法),方便对 POST、PUT、DELETE 等客户端操作进行限制
|
||||
* 攻击原始日志的防护模块为 “补充规则” 时,“命中规则” 处增加规则的 ID
|
||||
|
||||
### 优化
|
||||
|
||||
* 优化导航,调整功能位置,方便寻找:
|
||||
* 证书管理 移动到 防护站点->证书管理
|
||||
* IP 组 移动到 防护配置->通用配置->IP 组
|
||||
* 源 IP 获取方式、站点通用配置 移动到 防护站点->代理设置
|
||||
* 拦截页面附加说明、自定义拦截页面、IP 情报共享计划 移动到 防护配置->通用配置->拦截页面、IP 情报共享计划
|
||||
* 雷池控制台登录设置、雷池控制台证书、Syslog 设置、系统信息 移动到一级导航 系统设置
|
||||
* 密码登录框增加请求频率限制,提高暴力猜解的难度
|
||||
* 免费证书由过期前 10 天自动续期,改为过期前 30 天就自动续期
|
||||
* 修复站点数量较多时,站点管理处采集不到资源的问题
|
||||
* 修复移动端点击登录页的 “忘记密码” 无法弹出重置命令的问题
|
||||
* 修复 syslog 因请求内容较多被截断时,json 格式会被截得不合法的问题
|
||||
* 修复其他一些已知问题
|
||||
* 优化一些 UI 交互细节
|
||||
|
||||
## [5.1.0] - 2024-03-21
|
||||
|
||||
### 新增
|
||||
|
||||
- 专业版支持 syslog 转发攻击日志到外部服务器。
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复某些情况下站点资源批量删除失败的问题。
|
||||
- 修复身份认证中配置 ip 组规则时功能异常的问题。
|
||||
- 修复某些攻击日志不显示地址位置的问题。
|
||||
- 修复页面缓存导致显示错误的问题。
|
||||
- 修复其他一些已知问题。
|
||||
|
||||
## [5.0.0] - 2024-03-14
|
||||
|
||||
### 新增
|
||||
|
||||
- 社区版支持密码登录。系统登录方式改为 密码+可选开启二步验证
|
||||
- 专业版
|
||||
- 支持添加多个用户
|
||||
- 支持导出攻击日志为 .csv 文件
|
||||
- 站点的负载均衡支持 IP Hash 算法、最小连接数算法
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复 luigi 容器有时负载过高降不下来的问题
|
||||
- 修复其他一些已知问题
|
||||
|
||||
## [4.4.2] - 2024-03-09
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复 FVM 服务在某些情况下 TCP 连接异常升高的问题
|
||||
|
||||
## [4.4.1] - 2024-03-07
|
||||
|
||||
### 优化
|
||||
|
||||
- 专业版支持在明亮主题和黑金主题之间切换
|
||||
- 优化人机验证([#693](https://github.com/chaitin/SafeLine/issues/693),云端更新,历史版本也生效)
|
||||
- 降低旋转图片的误差要求
|
||||
- 图片不容易对齐时,支持刷新图片
|
||||
- 修复一些低版本浏览器转不动图片的问题
|
||||
- 删除某些特别难对齐的图片
|
||||
- 优化一些界面 UI 和交互细节
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复防护配置某些极端情况下会失效的问题
|
||||
- 修复向 luigi 发大量日志后,CPU 占用畸高不下的问题
|
||||
- 修复升级或重启后限频可能失效,直到修改任意防护配置的问题
|
||||
- 修复站点选择证书后再直接关闭 SSL,证书管理处 “使用站点” 仍然显示该站点的问题([#656](https://github.com/chaitin/SafeLine/issues/656))
|
||||
- 修复攻击事件页面中,允许把 IP 加入至内置 IP 组的问题
|
||||
- 修复其他一些已知问题
|
||||
|
||||
## [4.4.0] - 2024-02-29
|
||||
|
||||
### 新增
|
||||
|
||||
- 支持升级至专业版,包含内容:
|
||||
- 自定义拦截页面
|
||||
- 商用地理位置库
|
||||
- 额外补充规则
|
||||
- 节点负载均衡
|
||||
- 专属黑金主题
|
||||
|
||||
### 优化
|
||||
|
||||
- 大幅优化频率限制的即时性,解决限频延迟时间过长的问题
|
||||
|
||||
## [4.1.1] - 2024-01-11
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复 IP 组在线订阅失败时会保存错误内容的问题
|
||||
|
||||
## [4.1.0] - 2024-01-11
|
||||
|
||||
### 新增
|
||||
|
||||
- 拦截日志一键复制为 cURL ([#531](https://github.com/chaitin/SafeLine/issues/531))
|
||||
|
||||
### 优化
|
||||
|
||||
- IP 组若为在线订阅,显示更新时间([#574](https://github.com/chaitin/SafeLine/issues/574))
|
||||
- 优化 safeline-fvm 容器重启速度,重启时间减少 10s
|
||||
- 优化 safeline-mgt 容器镜像层数,从 39 层下降到 24 层
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复日志列表 IP 来源地区未翻译国家编号的问题([#578](https://github.com/chaitin/SafeLine/issues/578))
|
||||
- 修复英文翻译问题([#591](https://github.com/chaitin/SafeLine/issues/591))
|
||||
- 修复雷池管理后台证书更新后未自动重启问题
|
||||
|
||||
## [4.0.2] - 2024-01-06
|
||||
|
||||
### 修复
|
||||
|
||||
- 管理后台 mgt 启动时提示证书异常
|
||||
- 统计页面中 QPS 数据统计方法由窗口时间(5s)改为按秒计算平均值
|
||||
|
||||
## [4.0.1] - 2024-01-05
|
||||
|
||||
### 修复
|
||||
|
||||
- safeline-luigi 容器打印与功能无关的错误日志
|
||||
- 统计页面中不显示 QPS 数据
|
||||
|
||||
## [4.0.0] - 2024-01-05
|
||||
|
||||
### 新增
|
||||
|
||||
- 完整支持 **流式语义分析检测**,包含 协议解析、解码、模式匹配 三个阶段的改造,解决经典 “大包绕过” 问题
|
||||
- IP 组支持通过 URL 在线订阅内容([#414](https://github.com/chaitin/SafeLine/issues/414))
|
||||
- 新增 “搜索引擎爬虫 IP”,包含 Google、Bing、百度、360 的爬虫 IP([#374](https://github.com/chaitin/SafeLine/issues/374)、[#399](https://github.com/chaitin/SafeLine/issues/399))
|
||||
- 出厂预置 “搜索引擎爬虫白名单” 和 “长亭社区恶意 IP 情报黑名单”,方便配置
|
||||
|
||||
### 优化
|
||||
- 支持类 ChatGPT 应用的流式 HTTP 响应([#513](https://github.com/chaitin/SafeLine/issues/513))
|
||||
- 在 证书管理 编辑证书后,若证书正被站点使用,自动重启 nginx 使新证书生效([#534](https://github.com/chaitin/SafeLine/issues/534))
|
||||
- safeline-fvm 容器体积减小 60%
|
||||
- safeline-mgt 服务减少宿主机文件依赖
|
||||
- safeline-mgt 服务日志全部写入 docker 标准输出,默认仅输出启动信息和错误日志,减小磁盘占用
|
||||
- safeline-mgt 服务、safeline-tengine 服务支持运行时日志输出范围设置,方便问题调试
|
||||
- 更新 compose.yaml 文件配置,移除非必要环境变量配置,规范环境变量名称,移除非必要卷配置
|
||||
- 增加新统计服务 safeline-luigi,为更精细的统计能力做准备
|
||||
- 优化若干 UI 交互、文字描述、英文翻译的细节(感谢国际友人的帮助)
|
||||
- 修复 3.16 以及之前版本的一些问题:
|
||||
- safeline-tcd 启动时因启动顺序导致输出错误提示
|
||||
- http 强制跳转到 https 功能未生效
|
||||
- 修复 4.0.0-beta.x 版本中的一些问题:
|
||||
- 登录雷池失败,提示 HTTP/2 协议错误([#564](https://github.com/chaitin/SafeLine/issues/564))
|
||||
- 升级脚本未正常检测到雷池安装目录([#561](https://github.com/chaitin/SafeLine/pull/561),感谢热心网友 nmgliangwei)
|
||||
- safeline-mgt 持续输出版本号错误日志
|
||||
- 拦截页面未显示时间
|
||||
|
||||
|
||||
## [4.0.0-beta.3] - 2023-12-28
|
||||
|
||||
### 优化
|
||||
|
||||
- 支持类 ChatGPT 应用的流式 HTTP 响应([#513](https://github.com/chaitin/SafeLine/issues/513))
|
||||
- 更新流式检测引擎到 (20231228) 版本
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复由于服务启动顺序导致输出非必要的错误日志
|
||||
|
||||
## [4.0.0-beta.2] - 2023-12-22
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复 safeline-tcd 启动时因启动顺序导致输出错误提示信息
|
||||
- 修复 safeline-mgt 在 beta 版本下持续输出版本号错误日志
|
||||
- 修复 http 强制跳转到 https 功能未生效问题
|
||||
|
||||
### 优化
|
||||
|
||||
- 更新流式检测引擎版本到 20231222 版本
|
||||
|
||||
## [4.0.0-beta.1] - 2023-12-21
|
||||
|
||||
### 新增
|
||||
|
||||
- 完整支持 **流式语义分析检测**,包含 协议解析、解码、模式匹配 三个阶段的改造,解决经典 “大包绕过” 问题
|
||||
|
||||
### 优化
|
||||
|
||||
- safeline-fvm 容器体积减小 60%
|
||||
- safeline-mgt 服务减少宿主机文件依赖
|
||||
- safeline-mgt 服务日志全部写入 docker 标准输出,默认仅输出启动信息和错误日志,减小磁盘占用
|
||||
- safeline-mgt 服务、safeline-tengine 服务支持运行时日志输出范围设置,方便问题调试
|
||||
- 更新 compose.yaml 文件配置,移除非必要环境变量配置,规范环境变量名称,移除非必要卷配置
|
||||
- 增加新统计服务 safeline-luigi,为更精细的统计能力做准备
|
||||
- 美化 502/504 页面
|
||||
- 优化频率限制配置的英文翻译(感谢国际友人的提示)
|
||||
|
||||
## [3.16.1] - 2023-12-15
|
||||
|
||||
### 新增
|
||||
|
||||
- 右上角增加 “更多工具”,方便快速访问牧云主机助手、百川网站监测等常用运维管理工具
|
||||
|
||||
### 优化
|
||||
|
||||
- 登录时若验证码错误,不再自动清空内容,方便修改([#449](https://github.com/chaitin/SafeLine/issues/449))
|
||||
- 精简 docker 镜像文件,safeline-mgt-api 体积减小 90%
|
||||
- 获取站点的 Favicon 和标题时,增加浏览器 UserAgent,避免被上游服务拒绝
|
||||
- 数据统计页 4xx 和 5xx 错误率的默认显示方式从 “-%” 改为 “0%” ([#517](https://github.com/chaitin/SafeLine/issues/517))
|
||||
- 优化控制台和 502 、504 页面的一些样式细节
|
||||
- 未登录时,不显示任何前端页面内容,避免被报告安全问题
|
||||
|
||||
## [3.15.3] - 2023-12-08
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复 403 拦截页面没有展示拦截页面附加说明的问题
|
||||
|
||||
## [3.15.2] - 2023-12-07
|
||||
|
||||
### 新增
|
||||
|
||||
- 新增 502、504 页面。网站服务器异常、配置有误时,能给网站用户提供更清晰友好的说明
|
||||
- 拦截页面支持英文,根据客户端语言自动切换
|
||||
|
||||
### 优化
|
||||
|
||||
- 单个 IP 组内的 IP 数量,增加 1w 行的上限。避免更新配置时系统异常
|
||||
- 修复创建或修改站点时,端口占用检查没有生效的问题
|
||||
- 略微提高流量检测和配置修改时的执行效率
|
||||
|
||||
## [3.14.1] - 2023-11-30
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复日志服务 CPU 占用过高问题
|
||||
|
||||
## [3.14.0] - 2023-11-30
|
||||
|
||||
### 新增
|
||||
|
||||
- 增加黑白名单正则表达式校验,避免 “_url_” 这类错误正则
|
||||
- 事件列表固定表头 ([#443](https://github.com/chaitin/SafeLine/issues/443))
|
||||
|
||||
### 优化
|
||||
|
||||
- 移除 redis 依赖,减少运行容器数量
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复黑白名单 CIDR 格式校验提示文案未翻译的问题
|
||||
- 修复 safeline-tengine 容器提示缺少 MGT_API 的问题 ([#468](https://github.com/chaitin/SafeLine/issues/468))
|
||||
|
||||
## [3.13.2] - 2023-11-24
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复了 safeline-fvm-manager 容器的健康检查错误结果
|
||||
|
||||
## [3.13.1] - 2023-11-23
|
||||
|
||||
### 新增
|
||||
|
||||
- 人机验证的二次验证,从数字验证码改为旋转图片,网站用户体验更好
|
||||
|
||||
### 优化
|
||||
|
||||
- 修复 社区恶意 IP 情报 每日定时更新后,控制台上 “更新时间” 未相应更新的问题
|
||||
- 日志详情 “已拦截” “已放行” 图案改为英文,适配国际化
|
||||
- 域名不匹配时,返回的拦截页面补充更多提示
|
||||
- 优化一些界面细节
|
||||
|
||||
## [3.12.2] - 2023-11-17
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复重启 docker (包括雷池升级)后,站点通用配置和拦截页面附加说明没有被正确载入的问题 ([#438](https://github.com/chaitin/SafeLine/issues/438) [#446](https://github.com/chaitin/SafeLine/issues/446))
|
||||
|
||||
## [3.12.1] - 2023-11-16
|
||||
|
||||
### 新增
|
||||
|
||||
- 登录过程输入完 6 位验证码自动登录([#335](https://github.com/chaitin/SafeLine/issues/335))
|
||||
- 统计 PV 和 UV 用的 cookie 默认添加 HttpOnly 属性,在 HTTPS 下自动添加 Secure 属性
|
||||
|
||||
### 优化
|
||||
|
||||
- 修复证书在添加一段时间后,证书类型统一变成 “上传已有证书” ,编辑时也看不到证书内容的问题。(免费证书需要手动再切换到免费证书申请一下,后续才能自动续期。只影响列表管理,不影响网站上的证书)
|
||||
- 开启 “强制 HTTPS” 时,HSTS 删去 preload 参数,并改为只在 https 端口下返回 ([#407](https://github.com/chaitin/SafeLine/issues/407))
|
||||
- 修复添加、编辑站点有时出现 “Service abnormal” 异常的问题
|
||||
- 修复 “申请免费证书” 类型的证书,在证书列表上显示成 “上传已有证书” 的问题
|
||||
- 优化一些样式交互细节
|
||||
|
||||
### [3.11.1] - 2023-11-09
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复证书列表页面域名列显示不正确问题
|
||||
|
||||
## [3.11.0] - 2023-11-09
|
||||
|
||||
### 新增
|
||||
|
||||
- 站点详情新增站点的 favicon、标题和编辑按钮
|
||||
|
||||
### 优化
|
||||
|
||||
- 优化 “强制 HTTPS” 中 HSTS 的参数细节([#407](https://github.com/chaitin/SafeLine/issues/407))
|
||||
- 修复英文模式下事件列表文字错位问题
|
||||
- 修复添加、编辑站点有时出现 “Service abnormal” 异常的问题
|
||||
- 优化站点 “运行模式” 的展示和交互
|
||||
- 优化一些界面交互和提示文字
|
||||
|
||||
## [3.10.3] - 2023-11-06
|
||||
|
||||
- 修复部分证书无法编辑,提示 “密钥内容解析错误” 的问题
|
||||
- 修复升级或重启后,站点证书引用成历史证书的问题
|
||||
- 修复编辑证书有时必须填写私钥的问题
|
||||
|
||||
## [3.10.1] - 2023-11-03
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复无法修改 通用配置-其他-拦截页面附加说明 的问题
|
||||
|
||||
## [3.10.0] - 2023-11-02
|
||||
|
||||
### 新增
|
||||
|
||||
- 在证书管理创建证书时,支持直接粘贴证书与私钥内容([#77](https://github.com/chaitin/SafeLine/issues/77))
|
||||
|
||||
### 优化
|
||||
|
||||
- 人机验证的客户端文件从 138k 减小到 78k,提高加载速度
|
||||
- 人机验证 cookie 改为 httpOnly 模式,避免在 JavaScript 运行时泄露
|
||||
- 人机验证防止简单绕过 ([#405](https://github.com/chaitin/SafeLine/issues/405))
|
||||
- 修复站点详情中,资源 “今日请求” 的总和大于站点 “今日请求总量” 的问题([#410](https://github.com/chaitin/SafeLine/issues/410))
|
||||
|
||||
## [3.9.0] - 2023-10-26
|
||||
|
||||
### 优化
|
||||
|
||||
- 人机验证页面增加响应头 Cache-Control,向下游声明不希望被缓存,避免被 CDN 缓存导致不断重复验证([#402](https://github.com/chaitin/SafeLine/issues/402) )
|
||||
- 修复人机验证在 iframe 中会不断重复验证的问题([#397](https://github.com/chaitin/SafeLine/issues/397) )
|
||||
- 修复人机验证在 alook 浏览器中页面空白的问题([#393](https://github.com/chaitin/SafeLine/issues/393) )
|
||||
- 修复添加、编辑站点有时出现 “Service abnormal” 异常的问题
|
||||
- 修复申请免费证书时,无法填写多个域名的问题
|
||||
- 修复编辑站点时,域名无法设为空的问题
|
||||
- 升级过程增加安装方式检查,通过牧云助手安装的,需要通过牧云助手升级,避免故障
|
||||
|
||||
## [3.8.2] - 2023-10-19
|
||||
|
||||
### 新增
|
||||
|
||||
- “通用漏洞规则” 的攻击日志中,新增 “命中规则”,方便管理员了解具体的拦截原因:
|
||||
|
||||
### 优化
|
||||
|
||||
- 修复 acme 未记录好邮箱,导致无法自动续签的问题。**旧版本已申请的证书,升级后需要再次编辑补全一下邮箱地址,才能自动续签**
|
||||
- 修复雷池重启后,已通过人机验证的页面会一直反复进行人机验证的问题
|
||||
- 修复某个站点关闭 ssl 之后,还会错误地显示在证书管理的 “使用站点” 中的问题
|
||||
- 优化安卓手机的人机验证效果,现在不会总是弹出验证码识别了
|
||||
- 修复证书管理-编辑证书时,弹窗没有正常回填已有配置的问题
|
||||
- 优化 攻击事件->原始日志 默认的筛选条件([#288](https://github.com/chaitin/SafeLine/issues/288))
|
||||
- 优化一些 UI 交互细节
|
||||
|
||||
## [3.7.3] - 2023-10-16
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复获取上游服务器的 favicon 和标题失败时,可能导致站点管理无法配置站点的问题
|
||||
- 修复 IP 组中的网段解析错误,导致匹配结果不正确的问题
|
||||
|
||||
## [3.7.2] - 2023-10-13
|
||||
|
||||
### 优化
|
||||
|
||||
- 修复无法更新威胁情报 IP 的问题
|
||||
- 修复编辑人机验证配置时不回显的问题
|
||||
|
||||
## [3.7.1] - 2023-10-13
|
||||
|
||||
### 新增
|
||||
|
||||
- 人机验证增加 **二次验证码验证**,在自动验证失败时进行,减少误拦
|
||||
|
||||
### 优化
|
||||
|
||||
- 优化人机验证
|
||||
- 简化配置,不再区分交互、非交互
|
||||
- 区分站点,验证通过的结果只能在一个站点(按域名或 IP 区分)上生效了
|
||||
- 降低算力要求,解决部分移动端验证时间过长的问题
|
||||
- 配置站点时,“上游服务器” 的服务器地址部分支持填写主机名,例如 http://localhost:8080
|
||||
- 站点的运行模式为 “观察” 时,黑名单、限频、人机 改为**都不拦截**。其中黑名单会记录 “放行” 的日志;限频会持续计入统计,但限制结果不会对观察中的站点生效
|
||||
- 修复证书管理中,泛域名的证书显示 “域名不匹配” 问题([#368](https://github.com/chaitin/SafeLine/issues/368))
|
||||
- 更新检测引擎版本,降低误报
|
||||
- 优化若干提示文字和样式细节
|
||||
|
||||
## [3.6.4] - 2023-10-09
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复了多个域名申请免费证书失败的问题
|
||||
- 修复了有时候不能创建 HTTP 站点的问题
|
||||
- 修复证书管理中,“使用站点” 不全的问题
|
||||
- 修复证书管理中,泛域名证书的使用站点始终提示 “域名不匹配” 的问题
|
||||
|
||||
## [3.6.3] - 2023-10-09
|
||||
|
||||
### 新增
|
||||
|
||||
- 新增申请免费证书。只要域名已经指向雷池,就可以在界面上直接申请证书了
|
||||
- 证书管理新增 “使用站点”,并且会自动检查站点和证书的域名是否一致
|
||||
|
||||
### 优化
|
||||
|
||||
- 优化站点配置证书的流程,现在所有证书都在证书管理配置,方便统一查看
|
||||
- 雷池控制台证书的配置移动到了 “通用配置” -> “其他” 中,更符合直觉
|
||||
- 修复某些情况下采集不到站点 favicon 的问题
|
||||
- 修复采集站点标题的时候,会把英文大写转成小写的问题
|
||||
- 修复站点详情中,删除文件夹的操作不会生效的问题
|
||||
- 修复站点详情中,资源的 今日请求 / 近 30 日请求 始终为 0 的问题
|
||||
|
||||
## [3.5.1] - 2023-09-26
|
||||
|
||||
### 优化:
|
||||
|
||||
- 修复站点详情中,今日请求量一直为 0 的问题
|
||||
- 修复获取站点 favicon 时没有尝试默认路径,导致某些站点获取不到的问题
|
||||
- 修复小概率出现无法对站点进行任何操作的问题(不影响已配置站点的防护)
|
||||
|
||||
## [3.5.0] - 2023-09-21
|
||||
|
||||
### 新增
|
||||
|
||||
- 人机验证新增每个规则的 “今日验证情况”,方便判断规则配置的效果:
|
||||
|
||||
### 优化
|
||||
|
||||
- 站点列表新增 “资源数”,方便判断判断资源管理情况
|
||||
- 优化 攻击事件->原始日志 默认的筛选条件([#288](https://github.com/chaitin/SafeLine/issues/288))
|
||||
- 修复自动采集的站点 favicon 有时候显示不出来的问题([#316](https://github.com/chaitin/SafeLine/issues/316))
|
||||
- 修复自动采集的站点标题有时候显示成乱码的问题
|
||||
- 修复站点详情的 “今日请求总量” 有时候不显示最新值的问题
|
||||
- 优化一些界面样式交互细节
|
||||
|
||||
## [3.4.1] - 2023-09-15
|
||||
|
||||
### 优化
|
||||
|
||||
- 修复请求上游服务器的 title 和 icon 时间过长导致站点相关功能异常的问题
|
||||
- 修复站点列表中站点标题的优先显示顺序,先显示“备注”,如果没有“备注”再显示网页的“标题”
|
||||
|
||||
## [3.4.0] - 2023-09-14
|
||||
|
||||
### 新增
|
||||
|
||||
- “防护站点” 新增站点的标题和 Favicon,每天更新一次,管理起来更加清晰
|
||||
- 站点详情新增“采集设置”,支持设置不记录的路径前缀和类型
|
||||
|
||||
### 优化
|
||||
|
||||
- 限频后封禁的拦截页面改为 “请求频率过高,已被拦截”,与语义分析和黑名单的拦截页面区分开,方便管理员确认拦截原因
|
||||
- 修复有时候无法正常通过路径搜索日志的问题
|
||||
- 修复限频中,同时配置人机验证、直接封禁两类限制结果时,直接封禁有时候不会被触发的问题
|
||||
- 修复黑名单拦截的请求也会触发限频,导致限频日志中出现很多 “已限制请求数” 为 0 的记录的问题
|
||||
- 优化界面的一些样式交互
|
||||
|
||||
## [3.3.0] - 2023-09-07
|
||||
|
||||
### 新增
|
||||
|
||||
- 支持设置拦截页面附加说明([#192](https://github.com/chaitin/SafeLine/issues/192))
|
||||
- 频率限制新增 “人机验证” 的限制方式([#226](https://github.com/chaitin/SafeLine/issues/226))
|
||||
|
||||
### 优化
|
||||
|
||||
- 当网站域名不匹配的时候,返回 “网站不存在” ,提示更清晰([#58](https://github.com/chaitin/SafeLine/issues/58))
|
||||
- 修复 攻击事件->原始日志 的 “攻击地址” 中显示额外的转义符的问题
|
||||
- 修复站点详情中 “今日总请求量” 和站点列表的 “今日访问量” 不一致的问题([#279](https://github.com/chaitin/SafeLine/issues/279))
|
||||
- 频率限制后直接封禁的拦截状态码改为 429,和普通拦截 403 区分开,方便排查拦截原因
|
||||
- 加强后台登录安全性(感谢微信交流 20 群「千年之狐」提供的建议)
|
||||
- 优化安装/升级时 CPU ssse3 指令集的检查方式([#273](https://github.com/chaitin/SafeLine/issues/273))
|
||||
- 优化界面样式交互,修复一些已知问题
|
||||
|
||||
## [3.2.0] - 2023-08-31
|
||||
|
||||
### 新增
|
||||
|
||||
- 证书管理支持上传 PKCS1、PKCS8、ECC 私钥格式的证书([#257](https://github.com/chaitin/SafeLine/issues/257))
|
||||
- 站点详情新增近 30 天请求数,支持批量删除
|
||||
|
||||
### 优化
|
||||
|
||||
- 优化站点详情页面,提高加载速度、优化界面样式和逻辑
|
||||
- 限频的生效阈值由 “超过 xx 次” 改为 “达到 xx 次”([#245](https://github.com/chaitin/SafeLine/issues/245))
|
||||
- 修复频率限制所拦截的请求,没有被计入站点列表的 “今日访问/拦截量” 的问题
|
||||
- 修复证书管理的证书有时候无法正常删除的问题([#268](https://github.com/chaitin/SafeLine/issues/268))
|
||||
- 修复证书管理中,有时候一个证书内会解析出几个重复的域名的问题
|
||||
- 去掉对 docker 的 seccomp 特性的依赖([#255](https://github.com/chaitin/SafeLine/issues/255))
|
||||
- 优化大量界面样式、交互和操作提示细节
|
||||
|
||||
## [3.1.1] - 2023-08-28
|
||||
|
||||
### 优化
|
||||
|
||||
- 修复创建站点时直接上传 SSL 证书显示创建失败的问题
|
||||
|
||||
## [3.1.0] - 2023-08-25
|
||||
|
||||
### 新增
|
||||
|
||||
- 新增证书管理。自动判断域名与过期状态,配置站点时可以直接选择([#111](https://github.com/chaitin/SafeLine/issues/111)),还可以修改管理后台的证书([#201](https://github.com/chaitin/SafeLine/issues/201))
|
||||
- 新增系统信息
|
||||
|
||||
### 优化
|
||||
|
||||
- 修复站点详情全局只支持 250 个资源的问题。现在是每个站点各支持 250 个
|
||||
- 修复站点详情中,路径太长样式会错位的问题
|
||||
- 修复站点从维护切换成其他状态时,微信会缓存维护页面的问题([#221](https://github.com/chaitin/SafeLine/issues/221))
|
||||
- 修复手机和平板上不能输入动态口令的问题([#234](https://github.com/chaitin/SafeLine/issues/234))
|
||||
- 优化导航栏和若干 UI 交互细节
|
||||
|
||||
## [3.0.1] - 2023-08-18
|
||||
|
||||
- 更新底层语义分析引擎,加强基础防护能力
|
||||
- 修复站点详情中,不同域名的资源会重复记录问题
|
||||
- 修复攻击事件有小概率时间排序错误的问题
|
||||
- 修复关闭再打开频率限制时,配置不会重置到默认值的问题
|
||||
- 修复首次创建站点且配置 SSL 端口的情况下提示“端口被占用”的问题
|
||||
|
||||
## [3.0.0] - 2023-08-18
|
||||
|
||||
### 新增
|
||||
|
||||
- 新增站点详情,能自动从流量中记录网站资源,一览资源的存活、访问情况
|
||||
- PS. 考虑机器资源消耗问题,当前版本每个站点下最多记录 250 个资源
|
||||
- 站点支持输入多个域名、端口([#162](https://github.com/chaitin/safeline/issues/162))
|
||||
- 通用配置中新增 “站点通用配置”,支持一键开启:
|
||||
- 强制 HTTPS([#67](https://github.com/chaitin/safeline/issues/67))
|
||||
- 使用 HTTP/2([#161](https://github.com/chaitin/safeline/issues/161))
|
||||
- 监听 IPv6([#166](https://github.com/chaitin/safeline/issues/166))
|
||||
- 传递客户端连接的 Host 和协议,方便后续服务器处理
|
||||
|
||||
### 优化
|
||||
|
||||
- 优化限频配置的默认值
|
||||
- 增加 HTTP 497 错误重定向。当以 HTTP 协议访问 HTTPS 端口时,将重定向到 HTTPS([#186](https://github.com/chaitin/safeline/issues/186))
|
||||
- 默认拒绝 IP 和其他非指定域名的访问。如果需要通过 IP 访问站点,可以给站点添加一个 "\*" 域名([#58](https://github.com/chaitin/safeline/issues/58))
|
||||
- 优化若干 UI 交互细节和文字提示
|
||||
|
||||
## [2.6.0] - 2023-08-10
|
||||
|
||||
### 新增
|
||||
|
||||
- 新增高频攻击封禁,即多次攻击后自动封禁 IP ([#29](https://github.com/chaitin/safeline/issues/29))
|
||||
- 频率限制日志显示封禁 IP 的地理位置 ([#198](https://github.com/chaitin/safeline/issues/198))
|
||||
|
||||
### 优化
|
||||
|
||||
- 攻击检测的原始日志支持搜索端口 ([#193](https://github.com/chaitin/safeline/issues/193))
|
||||
- 修复编辑站点后,“维护模式” 会失效的问题
|
||||
- 修改默认占用的网段,避免跟腾讯云默认网段冲突 ([#40](https://github.com/chaitin/safeline/issues/40))
|
||||
- 优化安装脚本 ([#194](https://github.com/chaitin/safeline/issues/194)),优化界面一些 UI 交互、错误提示
|
||||
|
||||
## [2.5.0] - 2023-08-03
|
||||
|
||||
### 新增
|
||||
|
||||
- 请求频率限制([#29](https://github.com/chaitin/safeline/issues/29))
|
||||
|
||||
### 优化
|
||||
|
||||
- 支持筛选攻击检测日志的 ID([#74](https://github.com/chaitin/safeline/issues/74)),优化筛选的交互
|
||||
- 证书支持 .cer 格式([#181](https://github.com/chaitin/safeline/issues/181))
|
||||
- 优化人机校验页面,适配移动端([#184](https://github.com/chaitin/safeline/issues/184))
|
||||
- 界面增加一些配置提示:添加站点时 “域名” 的格式、黑白名单/人机验证中匹配条件的生效逻辑
|
||||
|
||||
## [2.4.0] - 2023-07-27
|
||||
|
||||
### 新增
|
||||
|
||||
- IP 组支持注释 [#143](https://github.com/chaitin/safeline/issues/143)
|
||||
|
||||
### 优化
|
||||
|
||||
- 优化编辑 IP 组和相关规则时的性能
|
||||
- 优化一些界面 UI 交互细节
|
||||
|
||||
## [2.3.2] - 2023-07-24
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复了攻击事件 - 原始日志中,请求报文没有格式化的问题
|
||||
- 优化了一些已知问题
|
||||
|
||||
## [2.3.1] - 2023-07-20
|
||||
|
||||
### 新增
|
||||
|
||||
- 检测日志升级为**攻击事件** ,自动聚合同一攻击 IP 短时间内的所有攻击日志,方便管理员进行监控和处置
|
||||
- 日志支持按时间([#102](https://github.com/chaitin/safeline/issues/102))、动作筛选
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复添加/编辑站点时,上传证书处未翻译中文的问题
|
||||
- 修复数据统计中,“访问来源地区” 小概率出现的部分地区显示不正确的问题
|
||||
|
||||
## [2.2.0] - 2023-07-14
|
||||
|
||||
### 新增
|
||||
|
||||
- IP 组中新增长亭社区恶意 IP 情报,内容来自社区版共享的攻击 IP,每日自动更新
|
||||
|
||||
### 优化
|
||||
|
||||
- 升级核心检测引擎,修复一些绕过和误报
|
||||
- 管理界面增加浏览器版本检查,如果版本过旧,会提示升级浏览器
|
||||
- 优化一些界面的 UI 交互细节
|
||||
- 修复一些中英文翻译的问题
|
||||
|
||||
## [2.1.2] - 2023-07-07
|
||||
|
||||
- 修复了日志详情中防护策略模块没有翻译的问题
|
||||
|
||||
## [2.1.1] - 2023-07-06
|
||||
|
||||
- 修复了防护策略模块没有翻译的问题
|
||||
|
||||
## [2.1.0] - 2023-07-06
|
||||
|
||||
### 新增
|
||||
|
||||
- 添加/编辑站点时,自动检查端口占用情况,避免保存后配置不生效
|
||||
- 支持自定义站点的 nginx conf,详情可见[官网文档](https://waf-ce.chaitin.cn/posts/faq_other#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%AB%99%E7%82%B9-nginx-conf)
|
||||
- [站点列表支持按域名、端口或访问量进行排序](https://github.com/chaitin/safeline/issues/14)
|
||||
- [绑定 TOTP 密钥时,支持直接复制密钥;登录时的 6 位动态密码输入框,支持粘贴](https://github.com/chaitin/safeline/issues/30)
|
||||
|
||||
### 优化
|
||||
|
||||
- [黑白名单和人机验证列表中,可以鼠标悬浮查看 “复合条件” 的具体内容](https://github.com/chaitin/safeline/issues/120)
|
||||
- 修复人机验证列表中,“源 IP 不属于 IP 组” 的规则,IP 组名称显示成了 id 的问题
|
||||
- [优化人机验证启用/禁用交互](https://github.com/chaitin/safeline/issues/130)
|
||||
- [优化描述文字](https://github.com/chaitin/safeline/issues/122)
|
||||
- 优化一些界面 UI 交互、提示文字
|
||||
- 修复一些已知问题
|
||||
|
||||
## [2.0.1] - 2023-06-30
|
||||
|
||||
- 调整了人机验证的策略,降低误拦的情况
|
||||
- 修复了人机验证启动/禁用规则不会自动刷新状态的问题
|
||||
- 修复其他一些已知问题
|
||||
|
||||
## [2.0.0] - 2023-06-29
|
||||
|
||||
### 新增
|
||||
|
||||
- 人机验证
|
||||
- 支持嵌入式部署,可以通过 [t1k 协议](https://github.com/chaitin/lua-resty-t1k) 直接把流量转发到雷池进行检测
|
||||
- 把日志详情中的源 IP 加入到 IP 组时,支持调整 IP 为任意 IP 或网段
|
||||
|
||||
### 优化
|
||||
|
||||
- 日志列表按照时间和 ID 排序,防止出现小范围的时间乱序
|
||||
- 转发流量时,自动设置请求头 X-Forwarded-Proto,适配更多代理场景
|
||||
- 优化界面 UI,修复其他一些已知问题
|
||||
|
||||
## [1.10.0] - 2023-06-21
|
||||
|
||||
### 新增
|
||||
|
||||
- 防护站点新增 “运行模式”,可以一键将站点设为 观察 或 维护 模式了
|
||||
|
||||
### 优化
|
||||
|
||||
- 修复了站点列表没有分页器的问题
|
||||
- 修复了窗口水平滚动时导航栏会错位的问题
|
||||
- 修复了黑白名单配置 “不属于 IP 组” 的条件时,列表显示组 ID,而未显示组名称的问题
|
||||
- 优化了界面的 UI 与交互
|
||||
|
||||
## [1.9.0] - 2023-06-16
|
||||
|
||||
### 新增
|
||||
|
||||
- 界面 UI 改造,信息层级更清晰
|
||||
- 黑白名单支持添加 源 IP - 不属于 IP 组 的条件
|
||||
|
||||
### 优化
|
||||
|
||||
- 检测日志的路由进一步完善
|
||||
- 数据统计页面更加紧凑,现在可以在 1920\*1080 的屏幕上完全显示了
|
||||
- 黑白名单的展示优化
|
||||
- 修复 通用配置-防护模块配置 中,“批量配置为” 按钮有时候不生效的问题
|
||||
- 修复一些已知问题
|
||||
|
||||
## [1.8.2] - 2023-06-12
|
||||
|
||||
- 修复了「30 天访问情况」和「30 天拦截情况」显示相同数据的问题
|
||||
|
||||
## [1.8.1] - 2023-06-09
|
||||
|
||||
- 修复了「全部请求」和「仅拦截」数据一样的问题
|
||||
|
||||
## [1.8.0] - 2023-06-09
|
||||
|
||||
### 新增
|
||||
|
||||
- 数据统计页面增加访问来源地区、流量统计,更好把控网站运营情况
|
||||
|
||||
### 优化
|
||||
|
||||
- 更新语义引擎版本,优化了一大批检测逻辑,降低误报
|
||||
- 优化了部分操作提示信息:
|
||||
- IP 组正在使用时,无法被删除的提示
|
||||
- 未创建 IP 组时,在黑白名单中无法选择属于 IP 组的提示
|
||||
- 添加站点时,域名格式错误的提示
|
||||
|
||||
## [1.7.1] - 2023-06-05
|
||||
|
||||
### 修复
|
||||
|
||||
- 部分情况下无法打开日志详情页面的问题
|
||||
- 部分情况下页面查询数量只有 10 条的问题
|
||||
|
||||
## [1.7.0] - 2023-06-01
|
||||
|
||||
### 新增
|
||||
|
||||
- 新增 “IP 组” 功能,可以快速配置大量 IP 的黑/白名单了
|
||||
- 防护策略增加 “仅观察” 配置
|
||||
- 防护策略增加 “批量配置为” 按钮,可以快速切换所有模块的防护策略
|
||||
|
||||
### 优化
|
||||
|
||||
- 自定义规则列表增加翻页
|
||||
- 优化规则生效顺序,现在会优先执行完所有白名单,再执行黑名单
|
||||
|
||||
## [1.6.0] - 2023-05-25
|
||||
|
||||
### 新增
|
||||
|
||||
- 自定义规则支持匹配 Header 和 Body
|
||||
- 检测日志支持按域名搜索
|
||||
- 支持命令行清理检测日志和统计信息
|
||||
|
||||
## [1.5.1] - 2023-05-18
|
||||
|
||||
- 修复了自定义规则切换白名单之后,无法创建/编辑的问题
|
||||
|
||||
## [1.5.0] - 2023-05-18
|
||||
|
||||
### 新增
|
||||
|
||||
- 支持 i18n
|
||||
- 数据统计新增 “今日请求错误情况”
|
||||
- 检测日志的筛选条件现在会显示在 URL,方便保存
|
||||
|
||||
### 优化
|
||||
|
||||
- 修复自定义规则的编辑表单,有时候会丢失编辑中数据的问题
|
||||
- 修复 Safari 浏览器上的一些显示问题
|
||||
- 修复 Payload 中存在非 Unicode 编码时,检测日志会入库失败的问题(不影响拦截)
|
||||
- 修复新增的 “HTTP 请求走私” 攻击类型会被错误地展示成 “未知” 攻击类型的问题
|
||||
|
||||
## [1.4.0] - 2023-05-12
|
||||
|
||||
### 新增
|
||||
|
||||
- 自定义规则支持匹配域名
|
||||
- 支持在一条自定义规则内,设置多个匹配条件
|
||||
- 站点列表新增 “今日访问 / 拦截量”
|
||||
|
||||
### 优化
|
||||
|
||||
- 优化交互和提示文案、修复已知问题
|
||||
|
||||
## [1.3.0] - 2023-05-05
|
||||
|
||||
### 新增
|
||||
|
||||
- 支持按照源 IP、攻击类型、URL 筛选检测日志
|
||||
|
||||
### 修复
|
||||
|
||||
- 修复 dashboard 在部分低版本浏览器下的兼容问题
|
||||
- 修复按源 IP 添加自定义规则时,添加不了 /8 和更大的网段的问题
|
||||
|
||||
## [1.2.0] - 2023-04-27
|
||||
|
||||
### 新增
|
||||
|
||||
- 新增了数据统计页面,可以直观的看到流量大小
|
||||
- 支持配置源 IP 提取方式,解决了源 IP 获取不对的问题
|
||||
- 支持自定义检测策略,可以动态调整检测引擎
|
||||
|
||||
## [1.1.0] - 2023-04-20
|
||||
|
||||
### 新增
|
||||
|
||||
- 支持根据 IP 和 URL 特征配置黑白名单
|
||||
- 默认开启高防模式
|
||||
|
||||
### 优化
|
||||
|
||||
- 支持在日志详情中展示响应报文
|
||||
- 服务器时间不准导致 TOTP 无法登录时增加了提示语
|
||||
- 修复了上游服务器填 HTTPS 时端口解析不正确的问题
|
||||
- 优化了 SSL 上传逻辑,体验更好
|
||||
|
||||
## [1.0.0] - 2023-04-13
|
||||
|
||||
- 站点配置
|
||||
|
||||
## [0.9.0] - 2023-03-20
|
||||
|
||||
- OTP 登录
|
||||
- 攻击检测日志
|
||||
- 默认防护策略
|
124
Dockerfile
Normal file
|
@ -0,0 +1,124 @@
|
|||
FROM golang:1.21 as go-builder
|
||||
|
||||
WORKDIR /work
|
||||
ENV GOPROXY=https://goproxy.cn,direct
|
||||
COPY backend/go.mod .
|
||||
COPY backend/go.sum .
|
||||
RUN go mod download
|
||||
COPY backend .
|
||||
RUN CGO_ENABLED=0 go build -a -v -ldflags="-w" -o server .
|
||||
|
||||
FROM node:20.5-alpine
|
||||
|
||||
RUN apk update
|
||||
RUN apk add nginx supervisor curl
|
||||
|
||||
RUN echo -e " \n\
|
||||
server { \n\
|
||||
listen 80; \n\
|
||||
\n\
|
||||
location /api/ { \n\
|
||||
proxy_pass http://localhost:8080; \n\
|
||||
} \n\
|
||||
location /docs { \n\
|
||||
proxy_pass http://localhost:3000; \n\
|
||||
} \n\
|
||||
location /blazehttp { \n\
|
||||
root /app/; \n\
|
||||
try_files \$uri =404; \n\
|
||||
} \n\
|
||||
location /release { \n\
|
||||
root /app/; \n\
|
||||
try_files \$uri =404; \n\
|
||||
} \n\
|
||||
location /sitemap.xml { \n\
|
||||
root /srv/website/public; \n\
|
||||
} \n\
|
||||
location /sitemap-0.xml { \n\
|
||||
root /srv/website/public; \n\
|
||||
} \n\
|
||||
location /robots.txt { \n\
|
||||
root /srv/website/public; \n\
|
||||
} \n\
|
||||
location /googlef97f8402f9139518.html { \n\
|
||||
root /srv/website/public; \n\
|
||||
} \n\
|
||||
location /BingSiteAuth.xml { \n\
|
||||
root /srv/website/public; \n\
|
||||
} \n\
|
||||
location / { \n\
|
||||
rewrite /posts/guide_introduction /docs/ permanent; \n\
|
||||
rewrite /posts/guide_install /docs/guide/install permanent; \n\
|
||||
rewrite /docs/上手指南/guide_install /docs/guide/install permanent; \n\
|
||||
rewrite /posts/guide_login /docs/guide/login permanent; \n\
|
||||
rewrite /docs/上手指南/guide_login /docs/guide/login permanent; \n\
|
||||
rewrite /posts/guide_config /docs/guide/config permanent; \n\
|
||||
rewrite /docs/上手指南/guide_config /docs/guide/config permanent; \n\
|
||||
rewrite /posts/guide_test /docs/guide/test permanent; \n\
|
||||
rewrite /docs/上手指南/guide_test /docs/guide/test permanent; \n\
|
||||
rewrite /posts/guide_upgrade /docs/guide/upgrade permanent; \n\
|
||||
rewrite /docs/上手指南/guide_upgrade /docs/guide/upgrade permanent; \n\
|
||||
rewrite /posts/faq_install /docs/faq/install permanent; \n\
|
||||
rewrite /docs/常见问题排查/faq_install /docs/faq/install permanent; \n\
|
||||
rewrite /posts/faq_login /docs/faq/login permanent; \n\
|
||||
rewrite /docs/常见问题排查/faq_login /docs/faq/login permanent; \n\
|
||||
rewrite /posts/faq_access /docs/guide/config permanent; \n\
|
||||
rewrite /docs/常见问题排查/faq_access /docs/guide/config permanent; \n\
|
||||
rewrite /posts/faq_config /docs/faq/config permanent; \n\
|
||||
rewrite /docs/常见问题排查/faq_config /docs/faq/config permanent; \n\
|
||||
rewrite /posts/faq_other /docs/faq/other permanent; \n\
|
||||
rewrite /docs/常见问题排查/faq_other /docs/faq/other permanent; \n\
|
||||
rewrite /posts/about_syntaxanalysis /docs/about/syntaxanalysis permanent; \n\
|
||||
rewrite /docs/关于雷池/about_syntaxanalysis /docs/about/syntaxanalysis permanent; \n\
|
||||
rewrite /posts/about_challenge /docs/about/challenge permanent; \n\
|
||||
rewrite /docs/关于雷池/about_challenge /docs/about/challenge permanent; \n\
|
||||
rewrite /posts/about_changelog /docs/about/changelog permanent; \n\
|
||||
rewrite /docs/关于雷池/about_changelog /docs/about/changelog permanent; \n\
|
||||
rewrite /posts/about_chaitin /docs/about/chaitin permanent; \n\
|
||||
rewrite /docs/关于雷池/about_chaitin /docs/about/chaitin permanent; \n\
|
||||
rewrite /docs/faq/access /docs/guide/config permanent; \n\
|
||||
rewrite /docs/faq/config /docs/guide/config permanent; \n\
|
||||
proxy_pass http://127.0.0.1:3001; \n\
|
||||
} \n\
|
||||
} \n\
|
||||
" > /etc/nginx/http.d/default.conf
|
||||
RUN sed -i 's/access_log/access_log off; #/' /etc/nginx/nginx.conf
|
||||
# RUN nginx -t
|
||||
|
||||
RUN mkdir /etc/supervisor.d
|
||||
RUN echo -e " \n\
|
||||
[program:doc] \n\
|
||||
command = npm run serve \n\
|
||||
directory = /srv/documents \n\
|
||||
\n\
|
||||
[program:front] \n\
|
||||
command = npm start \n\
|
||||
directory = /srv/website \n\
|
||||
\n\
|
||||
[program:server] \n\
|
||||
command = /srv/server \n\
|
||||
" > /etc/supervisor.d/safeline.ini
|
||||
|
||||
COPY --from=go-builder /work/server /srv/server
|
||||
|
||||
COPY documents /srv/documents
|
||||
WORKDIR /srv/documents
|
||||
RUN npm ci; npm run build
|
||||
# npm run serve
|
||||
|
||||
ENV TARGET=http://localhost:8080
|
||||
COPY website /srv/website
|
||||
WORKDIR /srv/website
|
||||
RUN npm ci; npm run build
|
||||
# npm start
|
||||
|
||||
COPY release /app/release
|
||||
# 需要提前准备好 blazehttp 的文件,5 个不通系统执行文件和 1 个 case 压缩包
|
||||
COPY blazehttp/build /app/blazehttp
|
||||
|
||||
WORKDIR /srv
|
||||
|
||||
# ENV GITHUB_TOKEN=$GITHUB_TOKEN
|
||||
# ENV HTTPS_PROXY=$HTTPS_PROXY
|
||||
|
||||
CMD supervisord; nginx -g 'daemon off;'
|
182
FAQ.md
Normal file
|
@ -0,0 +1,182 @@
|
|||
# FAQ
|
||||
|
||||
## docker compose or docker-compose?
|
||||
|
||||
tl;dr The `docker compose` (with a space), aka v2, is a newer project to migrate compose to Go. The original python project `docker-compose`, aka v1 has now been deprecated.
|
||||
|
||||
refers also: [https://stackoverflow.com/questions/66514436/difference-between-docker-compose-and-docker-compose](https://stackoverflow.com/a/66516826)
|
||||
|
||||
## Setup and Deploy
|
||||
|
||||
### What specs should I deploy SafeLine to protect my web services? / Minimum hardware specs requirements
|
||||
|
||||
1C1G is ok for running docker containers of SafeLine. But the specific hardware specs depends on the traffic characteristics your services, such as qps, network io and so on. For now, no detailed datasheet is provided for references.
|
||||
|
||||
### ERROR: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
|
||||
|
||||
As shown, you shall start docker first. Try `systemctl start docker`.
|
||||
|
||||
### docker not found, unable to deploy
|
||||
|
||||
As shown, you shall install `docker` first. Try `curl -fLsS https://get.docker.com/ | sh` or [Install Docker Engine](https://docs.docker.com/engine/install/)
|
||||
|
||||
### docker compose v2 not found, unable to deploy
|
||||
|
||||
As shown, you shall install `docker compose v2`. Try `[Install Docker Compose](https://docs.docker.com/compose/install/)`
|
||||
|
||||
### safeline-pg: Operation not permitted
|
||||
|
||||
`docker logs -f safeline-pg` with error `Operation not permitted`
|
||||
|
||||
Upgrade your docker engine and retry.
|
||||
|
||||
### safeline-tengine: Address already in use
|
||||
|
||||
`docker logs -f safeline-tengine` with error `Address already in use`
|
||||
|
||||
Port conflicts. Based on the port number in the error message, troubleshoot which service is occupying it and handle the conflict manually.
|
||||
|
||||
### How to customize safeline-ce installation path?
|
||||
|
||||
With the latest `compose.yaml`, you can manually modify the `SAFELINE_DIR` variable in the `.env` file after `setup.sh`.
|
||||
|
||||
### How to change the default port of SafeLine management, as for `:9443` is already in used by some other services?
|
||||
|
||||
With the latest `compose.yaml`, you can add `MGT_PORT` variable in `.env` file.
|
||||
|
||||
## Login
|
||||
|
||||
### TOTP login failed with correct code
|
||||
|
||||
TOTP is calculated and verified according to time. So check your server time.
|
||||
|
||||
# 常见问题
|
||||
|
||||
## docker compose 还是 docker-compose?
|
||||
|
||||
`docker compose`(带空格)是 V2 版本,Go 写的。`docker-compose` 是 V1 版本,Python 写的,已经不维护了。
|
||||
|
||||
我们推荐使用 V2 版本的 `docker compose`,V1 可能会有兼容性等问题。
|
||||
|
||||
[docker/compose](https://github.com/docker/compose/) 中提到:
|
||||
|
||||
> For a smooth transition from legacy docker-compose 1.xx, please consider installing [compose-switch](https://github.com/docker/compose-switch) to translate `docker-compose ...` commands into Compose V2's `docker compose ....` . Also check V2's `--compatibility` flag.
|
||||
|
||||
其他参考:[https://stackoverflow.com/questions/66514436/difference-between-docker-compose-and-docker-compose](https://stackoverflow.com/a/66516826)
|
||||
|
||||
## 安装部署
|
||||
|
||||
### 机器运行的最低配置
|
||||
|
||||
最低 1C1G 能运行,具体需要多少配置取决于你的业务流量特征,比如 QPS、网络吞吐等等,暂时没有详细的 datasheet 性能参考。
|
||||
|
||||
### 镜像下载缓慢甚至连接超时
|
||||
|
||||
这个是因为 docker hub 默认使用位于美西节点拉取镜像,可以自行配置国内镜像加速源
|
||||
|
||||
### ERROR: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
|
||||
|
||||
如描述,你需要启动 docker daemon 才能执行相关的命令。尝试 `systemctl start docker`
|
||||
|
||||
As shown, you shall start docker first. Try `systemctl start docker`.
|
||||
|
||||
### docker not found, unable to deploy
|
||||
|
||||
如描述,你需要安装 `docker`。尝试 `curl -fLsS https://get.docker.com/ | sh` 或者 [Install Docker Engine](https://docs.docker.com/engine/install/)
|
||||
|
||||
### docker compose v2 not found, unable to deploy
|
||||
|
||||
如描述,你需要安装 `docker compose v2`。尝试 `[Install Docker Compose](https://docs.docker.com/compose/install/)`
|
||||
|
||||
### safeline-tengine 出现 Address already in use
|
||||
|
||||
`docker logs -f safeline-tengine` 容器日志中看到 `Address already in use` 信息。
|
||||
|
||||
端口冲突,根据报错信息中的端口号,排查是哪个服务占用了,手动处理冲突。
|
||||
|
||||
### safeline-pg 出现 Operation not permitted
|
||||
|
||||
`docker logs -f safeline-pg` 容器日志中看到 `Operation not permitted` 报错
|
||||
|
||||
可能是您的 docker 版本过低,升级 docker 到最新版本尝试一下。
|
||||
|
||||
### 如何自定义 SafeLine 安装路径?
|
||||
|
||||
基于最新的 `compose.yaml`,你可以手动修改 `.env` 文件的 `SAFELINE_DIR` 变量。
|
||||
|
||||
### 如何修改 SafeLine 后台管理的默认端口?本机 `:9443` 已经被别的服务占用了
|
||||
|
||||
基于最新的 `compose.yaml`,你可以手动添加 `MGT_PORT` 变量到 `.env` 文件。
|
||||
|
||||
## 登录问题
|
||||
|
||||
### OTP 认证码登录失败
|
||||
|
||||
TOTP 是基于时间生成和校验的,请检查你的服务器时间是否同步。
|
||||
|
||||
## 站点配置问题
|
||||
|
||||
在没有 SafeLine 的时候,假设小明的域名 `xiaoming.com` 通过 DNS 解析到自己主机 `192.168.1.111`,上面在 `:8888` 端口监听了自己的服务(网站/博客/靶场)等等。
|
||||
|
||||
小明通过 `http://xiaoming.com:8888` 或者 `192.168.1.111:8888` 来访问自己的服务。
|
||||
|
||||
### 我该如何配置?/ 域名填什么?/ 端口怎么写?/ 上游服务器是什么?
|
||||
|
||||
目前社区版 SafeLine 支持的是反向代理的方式接入站点,也就是类似于一台 nginx 服务。这时候小明需要做的就是让流量先抵达 SafeLine,然后经过 SafeLine 检测之后,再转发给自己原先的业务。
|
||||
|
||||
小明只需要按照如下方式创建站点即可:
|
||||
- `xiaoming.com` 填入页面的「域名」
|
||||
- `:7777` 填入「端口」;或者别的任意非 `:8888`和 `:9443`(被 SafeLine 后台管理页面占用)端口
|
||||
- `http://192.168.1.111:8888` 填入「上游服务器」
|
||||
|
||||
创建之后,就可以通过 `http://xiaoming.com:7777` 或者 `192.168.1.111:7777` 访问自己的服务了,这时候请求到 `http://xiaoming.com:7777` 的流量都会被 SafeLine 检测。经过 SafeLine 过滤后,安全的流量会被透传到原先的 `:8888` 业务服务器(即上游服务器)。
|
||||
|
||||
**注:直接访问 `http://xiaoming.com:8888` 的流量,仍然不会被 SafeLine 检测,因为流量并没有经过 SafeLine,而是绕过 SafeLine 直接打到了上游服务器上**
|
||||
|
||||
**如果按照如上配置,还是无法成功访问到我的上游服务器,接着往下看,尝试逐项进行问题排查。**
|
||||
|
||||
## 配置完成之后,还是没有成功访问到上游服务器
|
||||
|
||||
下面例子都还按照上面小明的环境情况介绍。
|
||||
|
||||
#### 1. netstat/ss/lsof 查看端口占用情况
|
||||
|
||||
先确认下 `0.0.0.0:7777` 端口是否有服务在监听。SafeLine 使用 Tengine 来作为代理服务,所以正常来说,应该有一个 nginx 进程监听在 `:7777` 端口。如果没有的话,可能是 SafeLine 的问题,请通过社群或者 Github issue 提交反馈。
|
||||
|
||||
如果有的话,继续往下排查。
|
||||
|
||||
#### 2. 是否是被非 SafeLine 的 nginx 监听
|
||||
|
||||
基于第一步,已经能确认 `:7777` 是被某个 nginx 进程监听了,但是并不能确认是被 SafeLine 自己的 nginx 监听。排查是否自己原先有 nginx conf 中配置了 server 监听 `:7777`。如果有的话,手动解决冲突。要么修改自己原先的 nginx conf,要么修改 SafeLine 的站点配置。
|
||||
|
||||
也可以直接通过 `docker logs -f safeline-tengine` 确认 SafeLine 是否有 nginx 报错说端口冲突。
|
||||
|
||||
*常见的情况就是自己原先有一个服务监听在 `:80`,SafeLine 上配置了站点也监听 `:80` 端口,就产生了冲突。*
|
||||
|
||||
如果没有的话,继续往下排查。
|
||||
|
||||
#### 3. 是否被防火墙拦截
|
||||
|
||||
有操作系统本身的防火墙,还有可能是云服务商的防火墙。根据实际情况逐项排查,配置开放端口的 TCP 访问。
|
||||
|
||||
出现如下情况,可能就是被中间某防火墙拦截了:
|
||||
1. 在 `192.168.1.111` 上 curl -vv `127.0.0.1:7777` 能访问到业务,有 HTTP 返回码。
|
||||
2. 在本机 curl -vv `192.168.1.111:7777` 不通,没有 HTTP 响应;`telnet 192.168.1.111 7777` 返回 `Unable to connect to remote host: Connection refused`
|
||||
|
||||
#### 4. SafeLine 是否能访问到上游服务器
|
||||
|
||||
小明的情况是 SafeLine 和业务在同一台机器,一般不会有不同机器之间的网络问题,但是也建议在 SafeLine 部署的机器上测试一下。如果是两台机器的情况下,需要考虑是否互相之间能正常通信。
|
||||
|
||||
直接 `curl -H "Host: <SafeLine-IP>" -vv http://xiaoming.com:8888` 测一下是否能访问到。如果不行,需要自行排查为什么 SafeLine 的机器没法访问到。
|
||||
|
||||
注:这里需要 -H 指定 Host `Host: <SafeLine-IP>` 进行连通性测试。收到比较多的反馈,在 WAF 上直接配置上游服务器为 HTTPS 的域名,比如 `https://xiaoming.com`。实际场景是希望先测试 WAF 能力正常后再把域名解析切到 WAF 进行上线。这种本地测试的场景,需要修改本机 host,把 `xiaoming.com` 解析到 `SafeLine-IP`,否则可能会无法成功代理。因为 SafeLine 向上游服务器转发时,代理请求中的 Host 使用的是原始 HTTP 请求中的 Host,此时需要自行判断上游业务服务器能够正确处理该代理请求(例如上游业务服务器在 Host 没有匹配自己的站点名称时,是否能够处理)
|
||||
|
||||
#### 5. 其他情况
|
||||
|
||||
如果执行了 1-4:
|
||||
1. 确认有 nginx 进程监听了 SafeLine 机器的 `0.0.0.0:7777` 端口
|
||||
2. 确认 SafeLine tengine 无端口冲突报错
|
||||
3. 确认主机和云服务商的防火墙都没有限制 `:7777` 端口的 TCP 访问
|
||||
4. 确认在 SafeLine 上能访问到「上游服务器」
|
||||
|
||||
问题还是没有解决,可能是 SafeLine 产品的问题,请通过社群或者 Github issue 提交反馈。
|
915
LICENSE.md
|
@ -1,674 +1,241 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
# 软件许可协议
|
||||
|
||||
本软件许可协议(以下简称"本协议")是您与北京长亭科技有限公司(以下简称"长亭")订立的具有法律约束力的协议,约束您对长亭发布的雷池社区版软件(以下简称"雷池")的安装与使用。**请您在使用本软件前仔细阅读以下条款,特别是免除或者限制责任的条款。安装、使用本软件表示您同意并接受本协议的条款。如果您不同意本协议条款,您应当立即卸载并停止使用雷池。**
|
||||
|
||||
**【协议的有效期】** 本协议将持续有效,直至您卸载和删除您下载或控制的雷池社区版软件的所有副本。
|
||||
|
||||
**【协议的修改与更新】** 长亭将不时对本协议予以更新,更新内容一经正式发布即成为本协议不可分割的组成部分。**在更新内容发布后继续使用雷池即表示您同意新的条款;如果您不同意新的条款,您应当卸载并停止使用雷池。**
|
||||
|
||||
**【术语的翻译】** 如果长亭为您提供了这些条款的英文版本的翻译,您同意该翻译仅为您提供方便,并且这些条款的英文版本将同样约束您与长亭的关系。如果这些条款的中文版本与英文版本之间存在任何矛盾,以中文版本为准。
|
||||
|
||||
**【许可范围】**
|
||||
|
||||
1. 在遵守本协议条款的前提下,您有权在单一设备上安装、运行本软件。
|
||||
|
||||
2. 雷池社区版软件是许可给您的,而非出售给您的。在本协议有效期内,并且在您遵守本协议的前提下,长亭授予您非排他性,不可转让,不可分配,不可再许可,可撤销的许可。
|
||||
|
||||
**【知识产权声明】** 本软件的所有代码、镜像、文件其版权、商标等知识产权均属于北京长亭科技有限公司。
|
||||
|
||||
**【禁止事项】** 您不得、也不得促使、协助或授权他人对本软件进行以下行为:
|
||||
|
||||
1. 破解、逆向工程、反编译、反汇编、转换为其他编程语言等以尝试获取本软件的源代码或本软件所产生的内在数据文件;
|
||||
|
||||
2. 二次包装、修改、改编、复制、翻译、再许可或制作衍生作品;
|
||||
|
||||
3. 出租、出售、再许可、分发、传播、直接共享、商品化、转让本软件;
|
||||
|
||||
4. 解决或绕过本软件中的任何技术限制;
|
||||
|
||||
5. 修改或删除本软件上关于本软件的版权声明、商标或其他知识产权声明;
|
||||
|
||||
6. 以本软件为基础和主要技术能力输出物,提供商业化的云服务或网络服务;
|
||||
|
||||
7. 对本软件作出任何陈述或保证;
|
||||
|
||||
8. 将本软件与侵犯他人知识产权或违反法律法规的内容、行为结合。例如:(1)利用本软件发表、传送、传播、储存违反国家法律、危害国家安全、社会稳定、公序良俗的内容,或任何不当的、侮辱诽谤的、淫秽的、暴力的及任何违反国家法律法规政策的内容;(2)违法使用本软件,包括但不限于侵犯、挪用或以其他方式侵犯任何第三方的任何合法权利。
|
||||
|
||||
**【免责声明】**
|
||||
|
||||
**本软件是按照现有技术和条件所能达到的现状提供的,长亭不提供任何形式的保证,** 包括但不限于:
|
||||
|
||||
1. 对于因使用或无法使用本软件而造成的任何直接、间接、附带、特殊或重大损害、利润损失或业务中断,长亭不承担任何责任,即使长亭已被告知相关损害;
|
||||
|
||||
2. 长亭无组织本软件的交流社区的义务与责任,不承担因技术交流导致某一方故障而产生的经济损失以及相关责任;
|
||||
|
||||
3. 长亭不对本软件的无故障、适用性、可用性、准确性、质量满意度等做任何形式的保证;
|
||||
|
||||
4. 长亭不保证该本软件可以满足您的要求,也不保证其操作不会中断或没有错误,或者将纠正缺陷;
|
||||
|
||||
5. 长亭对本软件提供的任何信息或建议均不构成任何担保;
|
||||
|
||||
6. 用户因使用本软件违反国家法律法规的,长亭不承担任何责任。
|
||||
|
||||
**【软件的获取】** 您可直接从长亭官方认证的渠道获取本软件。如果您从非长亭官方认证的第三方获取本软件或与本软件名称相同的安装程序,长亭无法保证该软件能够正常使用,并对因此给您造成的损失不承担责任。
|
||||
|
||||
**【软件的更新】** 为了完善用户体验,增强雷池社区版软件的功能及性能,长亭将会不断努力开发新的功能,并为您不定期提供软件更新。新版本发布后,旧版本的软件可能无法使用。长亭不保证旧版雷池社区版软件的稳定性和可使用性,请您随时核对并下载最新版本。
|
||||
|
||||
**【信息收集】** 在本软件安装和使用的过程中,长亭将收集部分数据和信息,如本软件的版本、语言、IP地址等,但长亭不会收集个人身份信息、个人生物识别信息等足以识别出特定自然人的信息,长亭仅将收集的信息用于确认您使用的雷池版本情况和雷池功能板块的使用频率,从而改善和优化软件功能。
|
||||
|
||||
**【数据安全保证】** 长亭在使用过程中不会收集、传输、存储其安装载体中的具体数据,您需要自行负责您的数据安全与备份。您理解并同意长亭无法提供找回丢失数据等服务。
|
||||
|
||||
**【权利保留】** 本软件的版权归长亭所有,除本协议明确授权外,所有其他权利均由长亭保留。未经长亭明确授权,您不得行使本协议未明确授权的其他权利。如超出授权使用,长亭保留追究法律责任的权利。
|
||||
|
||||
**【责任范围】** 在法律允许的最大范围内,在任何情况下,长亭均不对任何直接的,附带的,特殊的,间接的或后果性的损失或利润损失,数据损失,商誉损失,业务中断或任何其他形式的损失负责,对由您的使用或无法使用雷池社区版软件引起或与之相关的其他损害或损失概不负责。
|
||||
|
||||
**【法律适用与争议解决】** 本协议受中华人民共和国大陆地区(不含港澳台地区)法律管辖,并按之解释。因本协议引起的或与本协议有关的任何争议应优先通过协商解决。如协商无果,任何一方可将争议提交长亭所在地人民法院通过诉讼方式解决。
|
||||
|
||||
**【条款可分离】** 如本协议的任何条款被视作无效或无法执行,则上述条款可被分离,其余部分则仍具有法律效力。
|
||||
|
||||
**【专业版】** 雷池商业/企业版本(非社区版)的权利受单独条款的约束。
|
||||
|
||||
### The license agreement
|
||||
|
||||
This software license agreement (hereinafter referred to as \"the
|
||||
agreement\") is a legally binding agreement between you and Beijing
|
||||
Chaitin Technology Co., Ltd (hereinafter referred to as \"Chaitin\"),
|
||||
which governs your installation and use of the Leichi Community Edition
|
||||
software (hereinafter referred to as \"Leichi\") released by Chaitin.
|
||||
**Please read the following terms carefully before using this software,
|
||||
especially the terms disclaiming or limiting liability. Installing and
|
||||
using this software indicates your agreement and acceptance of the terms
|
||||
of this agreement. If you do not agree to the terms of this agreement,
|
||||
you should immediately uninstall and stop using Leichi.**
|
||||
|
||||
**\[Validity of the Agreement\]** This Agreement will remain in effect
|
||||
until you uninstall and delete all copies of the Leichi Community
|
||||
Edition software you downloaded or controlled.
|
||||
|
||||
**\[Modification and update of the agreement\]** Chaitin will update
|
||||
this agreement from time to time, and the updated content will become an
|
||||
integral part of this agreement once it is officially released.
|
||||
**Continuing to use Leichi after the updated content is released means
|
||||
that you agree to the new terms; if you do not agree to the new terms,
|
||||
you should uninstall and stop using Leichi.**
|
||||
|
||||
**\[Translation of Terms\]** If Chaitin provides you with a translation
|
||||
of the English version of these Terms, you agree that the translation is
|
||||
only for your convenience, and the English version of these Terms will
|
||||
also govern your relationship with Chaitin. If there is any conflict
|
||||
between the Chinese version and the English version of these Terms, the
|
||||
Chinese version shall prevail.
|
||||
|
||||
**\[Permission Scope\]**
|
||||
|
||||
1. Subject to the terms of this agreement, you have the right to
|
||||
install and run this software on a single device.
|
||||
|
||||
2. Leichi Community Edition software is licensed to you, not sold to you.
|
||||
During the term of this Agreement and on the premise that you comply
|
||||
with this Agreement, Chaitin grants you a non-exclusive,
|
||||
non-transferable, non-assignable, non-sublicensable, revocable license.
|
||||
|
||||
**\[Intellectual Property Statement\]** The copyright, trademark and
|
||||
other intellectual property rights of all codes, images and files of
|
||||
this software belong to Beijing Chaitin Technology Co., Ltd.
|
||||
|
||||
**\[Prohibited Behavior\]** You may not, nor may you prompt, assist or
|
||||
authorize others to perform the following actions on this software:
|
||||
|
||||
1. Crack, reverse engineer, decompile, disassemble, convert to other
|
||||
programming languages, etc. in an attempt to obtain the source code of
|
||||
the software or the inherent data files generated by the software;
|
||||
|
||||
2. Repackage, modify, adapt, copy, translate, sublicense or create
|
||||
derivative works;
|
||||
|
||||
3. Rent, sell, sublicense, distribute, disseminate, directly share,
|
||||
commercialize, and transfer this software;
|
||||
|
||||
4. Solve or bypass any technical limitations in the software;
|
||||
|
||||
5. Modify or delete the copyright statement, trademark or other
|
||||
intellectual property statement regarding this software on the software;
|
||||
|
||||
6. Provide commercial cloud services or network services based on this
|
||||
software and the main technical capability output;
|
||||
|
||||
7. Make any representation or warranty regarding the Software;
|
||||
|
||||
8. Combine this software with content or behavior that infringes on the
|
||||
intellectual property rights of others or violates laws and regulations.
|
||||
For example: (1) Use this software to publish, transmit, disseminate,
|
||||
and store content that violates national laws, endangers national
|
||||
security, social stability, public order and good morals, or any
|
||||
inappropriate, insulting, defamatory, obscene, violent, or anything that
|
||||
violates national laws and regulations The content of the policy; (2)
|
||||
Illegal use of this software, including but not limited to infringement,
|
||||
misappropriation or other infringement of any legal rights of any third
|
||||
party.
|
||||
|
||||
**\[Disclaimer\]**
|
||||
|
||||
**This software is provided according to the status quo that the
|
||||
existing technology and conditions can achieve. Chaitin does not provide
|
||||
any form of guarantee,** including but not limited to:
|
||||
|
||||
1. Chaitin does not assume any responsibility for any direct, indirect,
|
||||
incidental, special or significant damages, loss of profits or business
|
||||
interruption caused by the use or inability to use this software, even
|
||||
if Chaitin has been informed of the relevant damages;
|
||||
|
||||
2. Chaitin has no obligation or responsibility to organize a
|
||||
communication community for this software, and does not assume any
|
||||
economic losses or related responsibilities arising from the failure of
|
||||
any party due to technical exchanges;
|
||||
|
||||
3. Chaitin does not make any form of guarantee regarding the
|
||||
fault-freeness, applicability, availability, accuracy, quality
|
||||
satisfaction, etc. of this software;
|
||||
|
||||
4. Chaitin does not guarantee that the software can meet your
|
||||
requirements, nor does it guarantee that its operation will be
|
||||
uninterrupted or error-free, or that defects will be corrected;
|
||||
|
||||
5. Any information or suggestions provided by Chaitin does not
|
||||
constitute any guarantee for this software;
|
||||
|
||||
6. Chaitin does not assume any responsibility if the user violates
|
||||
national laws and regulations by using this software.
|
||||
|
||||
**\[Acquisition of software\]** You can obtain this software directly
|
||||
from Chaitin's official certified channels. If you obtain this software
|
||||
or an installation program with the same name as this software from a
|
||||
third party that is not officially certified by Chaitin, Chaitin cannot
|
||||
guarantee that the software can be used normally and is not responsible
|
||||
for any losses caused to you.
|
||||
|
||||
**\[Software Updates\]** In order to improve the user experience and
|
||||
enhance the functions and performance of the Leichi Community Edition
|
||||
software, Chaitin will continue to work hard to develop new features and
|
||||
provide you with software updates from time to time. After a new version
|
||||
is released, older versions of the software may become unusable. Chaitin
|
||||
does not guarantee the stability and usability of the old version of the
|
||||
Leichi Community Edition software. Please check and download the latest
|
||||
version at any time.
|
||||
|
||||
**\[Information Collection\]** During the installation and use of this
|
||||
software, Chaitin will collect some data and information, such as the
|
||||
version of the software, language, IP address, etc., but Chaitin will
|
||||
not collect personal identity information, personal biometric
|
||||
information, etc. that are sufficient to identify To obtain the
|
||||
information of specific natural persons, Chaitin will only use the
|
||||
collected information to confirm the version of Leichi you are using and
|
||||
the frequency of use of the Leichi function section, so as to improve
|
||||
and optimize the software functions.
|
||||
|
||||
**\[Data Security Guarantee\]** Chaitin will not collect, transmit, or
|
||||
store specific data in its installation carrier during use. You are
|
||||
responsible for the security and backup of your data. You understand and
|
||||
agree that Chaitin cannot provide services such as retrieval of lost
|
||||
data.
|
||||
|
||||
**\[Rights reserved\]** The copyright of this software belongs to
|
||||
Chaitin. Except as expressly authorized by this agreement, all other
|
||||
rights are reserved by Chaitin. Without express authorization from
|
||||
Chaitin, you may not exercise other rights not expressly authorized by
|
||||
this Agreement. If the use exceeds the authorized use, Chaitin reserves
|
||||
the right to pursue legal liability.
|
||||
|
||||
**\[Scope of Liability\]** To the maximum extent permitted by law, under
|
||||
no circumstances shall Chaitin be liable for any direct, incidental,
|
||||
special, indirect or consequential losses or loss of profits, loss of
|
||||
data, loss of goodwill, business interruption or any other form of loss,
|
||||
and is not responsible for other damages or losses arising out of or
|
||||
related to your use of or inability to use the Leichi Community Edition
|
||||
software.
|
||||
|
||||
**\[Law Application and Dispute Resolution\]** This agreement shall be
|
||||
governed by and construed in accordance with the laws of the mainland of
|
||||
the People\'s Republic of China (excluding Hong Kong, Macao and Taiwan).
|
||||
Any disputes arising out of or in connection with this Agreement shall
|
||||
be resolved first through negotiation. If the negotiation fails, either
|
||||
party may submit the dispute to the People\'s Court where Chaitin is
|
||||
located for settlement through litigation.
|
||||
|
||||
**\[Terms can be severed\]** If any term of this agreement is deemed to
|
||||
be invalid or unenforceable, the above terms can be severed and the
|
||||
remaining parts will still have legal effect.
|
||||
|
||||
**\[Professional Edition\]** The rights of the Leichi
|
||||
commercial/enterprise version (non-community version) are subject to
|
||||
separate terms.
|
||||
|
|
221
README.md
|
@ -1,128 +1,123 @@
|
|||
<p align="center">
|
||||
<img src="/images/banner.png" width="400" />
|
||||
<img src="https://raw.githubusercontent.com/chaitin/SafeLine/main/documents/static/images/403.svg" width="120">
|
||||
</p>
|
||||
<h1 align="center">雷池 - 广受好评的社区 WAF</h1>
|
||||
<br>
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/SafeLine-BEST_WAF-blue">
|
||||
<img src="https://img.shields.io/github/release/chaitin/safeline.svg?color=blue" />
|
||||
<img src="https://img.shields.io/github/release-date/chaitin/safeline.svg?color=blue&label=update" />
|
||||
<img src="https://img.shields.io/docker/v/chaitin/safeline-mgt-api?color=blue">
|
||||
<img src="https://img.shields.io/github/stars/chaitin/safeline?style=social">
|
||||
</p>
|
||||
|
||||
<h4 align="center">
|
||||
SafeLine - Make your web apps secure
|
||||
</h4>
|
||||
|
||||
<p align="center">
|
||||
<a target="_blank" href="https://waf.chaitin.com/">🏠 Website</a> |
|
||||
<a target="_blank" href="https://docs.waf.chaitin.com/">📖 Docs</a> |
|
||||
<a target="_blank" href="https://demo.waf.chaitin.com:9443/">🔍 Live Demo</a> |
|
||||
<a target="_blank" href="https://discord.gg/SVnZGzHFvn">🙋♂️ Discord</a> |
|
||||
<a target="_blank" href="/README_CN.md">中文版</a>
|
||||
<a href="https://waf-ce.chaitin.cn/">官方网站</a> |
|
||||
<a href="https://demo.waf-ce.chaitin.cn:9443/dashboard">在线 Demo</a> |
|
||||
<a href="https://waf-ce.chaitin.cn/posts/guide_introduction">技术文档</a> |
|
||||
<a href="README_EN.md">For English</a>
|
||||
</p>
|
||||
|
||||
## 👋 INTRODUCTION
|
||||
一款足够简单、足够好用、足够强的免费 WAF。基于业界领先的语义引擎检测技术,作为反向代理接入,保护你的网站不受黑客攻击。
|
||||
|
||||
SafeLine is a self-hosted **`WAF(Web Application Firewall)`** to protect your web apps from attacks and exploits.
|
||||
- **累计安装**超过 60000 台
|
||||
- **保护网站**超过 500,000 个
|
||||
- 每天**处理 HTTP 请求**超过 20,000,000,000 次
|
||||
- 每天**拦截攻击**超过 10,000,000 次
|
||||
|
||||
A web application firewall helps protect web apps by filtering and monitoring HTTP traffic between a web application and the Internet. It typically protects web apps from attacks such as `SQL injection`, `XSS`, `code injection`, `os command injection`, `CRLF injection`, `ldap injection`, `xpath injection`, `RCE`, `XXE`, `SSRF`, `path traversal`, `backdoor`, `bruteforce`, `http-flood`, `bot abused`, among others.
|
||||
核心检测能力由智能语义分析算法驱动,专为社区而生,不让黑客越雷池半步。
|
||||
|
||||
#### 💡 How It Works
|
||||
<img src="https://raw.githubusercontent.com/chaitin/SafeLine/main/documents/static/images/album/0.png" />
|
||||
|
||||
<img src="/images/how-it-works.png" width="800" />
|
||||
|
||||
By deploying a WAF in front of a web application, a shield is placed between the web application and the Internet. While a proxy server protects a client machine’s identity by using an intermediary, a WAF is a type of reverse-proxy, protecting the server from exposure by having clients pass through the WAF before reaching the server.
|
||||
|
||||
A WAF protects your web apps by filtering, monitoring, and blocking any malicious HTTP/S traffic traveling to the web application, and prevents any unauthorized data from leaving the app. It does this by adhering to a set of policies that help determine what traffic is malicious and what traffic is safe. Just as a proxy server acts as an intermediary to protect the identity of a client, a WAF operates in similar fashion but acting as an reverse proxy intermediary that protects the web app server from a potentially malicious client.
|
||||
|
||||
its core capabilities include:
|
||||
|
||||
- Defenses for web attacks
|
||||
- Proactive bot abused defense
|
||||
- HTML & JS code encryption
|
||||
- IP-based rate limiting
|
||||
- Web Access Control List
|
||||
|
||||
#### ⚡️ Screenshots
|
||||
|
||||
| <img src="./images/screenshot-1.png" width=370 /> | <img src="./images/screenshot-2.png" width=370 /> |
|
||||
| ------------------------------------------------- | ------------------------------------------------- |
|
||||
| <img src="./images/screenshot-3.png" width=370 /> | <img src="./images/screenshot-4.png" width=370 /> |
|
||||
|
||||
Get [Live Demo](https://demo.waf.chaitin.com:9443/)
|
||||
|
||||
## 🔥 FEATURES
|
||||
|
||||
List of the main features as follows:
|
||||
|
||||
- **`Block Web Attacks`**
|
||||
- It defenses for all of web attacks, such as `SQL injection`, `XSS`, `code injection`, `os command injection`, `CRLF injection`, `XXE`, `SSRF`, `path traversal` and so on.
|
||||
- **`Rate Limiting`**
|
||||
- Defend your web apps against `DoS attacks`, `bruteforce attempts`, `traffic surges`, and other types of abuse by throttling traffic that exceeds defined limits.
|
||||
- **`Anti-Bot Challenge`**
|
||||
- Anti-Bot challenges to protect your website from `bot attacks`, humen users will be allowed, crawlers and bots will be blocked.
|
||||
- **`Authentication Challenge`**
|
||||
- When authentication challenge turned on, visitors need to enter the password, otherwise they will be blocked.
|
||||
- **`Dynamic Protection`**
|
||||
- When dynamic protection turned on, html and js codes in your web server will be dynamically encrypted by each time you visit.
|
||||
|
||||
#### 🧩 Showcases
|
||||
|
||||
| | Legitimate User | Malicious User |
|
||||
| ----------------------------- | --------------------------------------------------- | ---------------------------------------------------------------- |
|
||||
| **`Block Web Attacks`** | <img src="./images/skeleton.png" width=270 /> | <img src="./images/blocked-for-attack-detected.png" width=270 /> |
|
||||
| **`Rate Limiting`** | <img src="./images/skeleton.png" width=270 /> | <img src="./images/blocked-for-access-too-fast.png" width=270 /> |
|
||||
| **`Anti-Bot Challenge`** | <img src="./images/captcha-1.gif" width=270 /> | <img src="./images/captcha-2.gif" width=270 /> |
|
||||
| **`Auth Challenge`** | <img src="./images/auth-1.gif" width=270 /> | <img src="./images/auth-2.gif" width=270 /> |
|
||||
| **`HTML Dynamic Protection`** | <img src="./images/dynamic-html-1.png" width=270 /> | <img src="./images/dynamic-html-2.png" width=270 /> |
|
||||
| **`JS Dynamic Protection`** | <img src="./images/dynamic-js-1.png" width=270 /> | <img src="./images/dynamic-js-2.png" width=270 /> |
|
||||
|
||||
## 🚀 Quickstart
|
||||
|
||||
> [!WARNING]
|
||||
> 中国大陆用户安装国际版可能会导致无法连接云服务,请查看 [中文版安装文档](https://docs.waf-ce.chaitin.cn/zh/%E4%B8%8A%E6%89%8B%E6%8C%87%E5%8D%97/%E5%AE%89%E8%A3%85%E9%9B%B7%E6%B1%A0)
|
||||
|
||||
#### 📦 Installing
|
||||
|
||||
Information on how to install SafeLine can be found in the [Install Guide](https://docs.waf.chaitin.com/en/tutorials/install)
|
||||
|
||||
#### ⚙️ Protecting Web Apps
|
||||
|
||||
to see [Configuration](https://docs.waf.chaitin.com/en/tutorials/Configuration)
|
||||
|
||||
## 📋 More Informations
|
||||
|
||||
#### Effect Evaluation
|
||||
|
||||
| Metric | ModSecurity, Level 1 | CloudFlare, Free | SafeLine, Balance | SafeLine, Strict |
|
||||
| ----------------- | -------------------- | -------------------- | ---------------------- | --------------------- |
|
||||
| Total Samples | 33669 | 33669 | 33669 | 33669 |
|
||||
| **Detection** | 69.74% | 10.70% | 71.65% | **76.17%** |
|
||||
| **False Positive**| 17.58% | 0.07% | **0.07%** | 0.22% |
|
||||
| **Accuracy** | 82.20% | 98.40% | **99.45%** | 99.38% |
|
||||
|
||||
|
||||
#### Is SafeLine Production-Ready?
|
||||
|
||||
Yes, SafeLine is production-ready.
|
||||
|
||||
- Over 180,000 installations worldwide
|
||||
- Protecting over 1,000,000 Websites
|
||||
- Handling over 30,000,000,000 HTTP Requests Daily
|
||||
|
||||
#### 🙋♂️ Community
|
||||
|
||||
Join our [Discord](https://discord.gg/SVnZGzHFvn) to get community support, the core team members are identified by the STAFF role in Discord.
|
||||
|
||||
- channel [#feedback](https://discord.com/channels/1243085666485534830/1243120292822253598): for new features discussion.
|
||||
- channel [#FAQ](https://discord.com/channels/1243085666485534830/1263761679619981413): for FAQ.
|
||||
- channel [#general](https://discord.com/channels/1243085666485534830/1243115843919806486): for any other questions.
|
||||
|
||||
Several contact options exist for our community, the primary one being Discord. These are in addition to GitHub issues for creating a new issue.
|
||||
|
||||
<p align="left">
|
||||
<a target="_blank" href="https://discord.gg/SVnZGzHFvn"><img src="https://img.shields.io/badge/Discord-5865F2?style=flat&logo=discord&logoColor=white"></a>
|
||||
<a target="_blank" href="https://x.com/safeline_waf"><img src="https://img.shields.io/badge/X.com-000000?style=flat&logo=x&logoColor=white"></a>
|
||||
<a target="_blank" href="/images/wechat.png"><img src="https://img.shields.io/badge/WeChat-07C160?style=flat&logo=wechat&logoColor=white"></a>
|
||||
<h4 align="center">相关源码仓库</h4>
|
||||
<p align="center">
|
||||
<a href="https://github.com/chaitin/yanshi">语义分析自动机引擎</a> |
|
||||
<a href="https://github.com/chaitin/safeline-open-platform">流量分析插件</a> |
|
||||
<a href="https://github.com/chaitin/lua-resty-t1k">T1K 协议</a> |
|
||||
<a href="https://github.com/chaitin/blazehttp">测试工具</a>
|
||||
</p>
|
||||
|
||||
#### 💪 PRO Edition
|
||||
## 相关特性
|
||||
|
||||
Coming soon!
|
||||
#### 便捷性
|
||||
|
||||
#### 📝 License
|
||||
采用容器化部署,一条命令即可完成安装,0 成本上手。安全配置开箱即用,无需人工维护,可实现安全躺平式管理。
|
||||
|
||||
See [LICENSE](/LICENSE.md) for details.
|
||||
#### 安全性
|
||||
|
||||
首创业内领先的智能语义分析算法,精准检测、低误报、难绕过。语义分析算法无规则,面对未知特征的 0day 攻击不再手足无措。
|
||||
|
||||
#### 高性能
|
||||
|
||||
无规则引擎,线性安全检测算法,平均请求检测延迟在 1 毫秒级别。并发能力强,单核轻松检测 2000+ TPS,只要硬件足够强,可支撑的流量规模无上限。
|
||||
|
||||
#### 高可用
|
||||
|
||||
流量处理引擎基于 Nginx 开发,性能与稳定性均可得到保障。内置完善的健康检查机制,服务可用性高达 99.99%。
|
||||
|
||||
## 🚀 安装
|
||||
|
||||
### 配置需求
|
||||
|
||||
- 操作系统:Linux
|
||||
- 指令架构:x86_64
|
||||
- 软件依赖:Docker 20.10.6 版本以上
|
||||
- 软件依赖:Docker Compose 2.0.0 版本以上
|
||||
- 最小化环境:1 核 CPU / 1 GB 内存 / 10 GB 磁盘
|
||||
|
||||
|
||||
### 一键安装
|
||||
|
||||
```
|
||||
bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)"
|
||||
```
|
||||
|
||||
> 更多安装方式请参考 <a href="https://waf-ce.chaitin.cn/posts/guide_install">安装雷池</a>
|
||||
|
||||
## 🕹️ 快速使用
|
||||
|
||||
### 登录
|
||||
|
||||
浏览器打开后台管理页面 `https://<waf-ip>:9443`。根据界面提示,使用 **支持 TOTP 的认证软件** 扫描二维码,然后输入动态口令登录:
|
||||
|
||||

|
||||
|
||||
### 配置防护站点
|
||||
|
||||
雷池以反向代理方式接入,优先于网站服务器接收流量,对流量中的攻击行为进行检测和清洗,将清洗过后的流量转发给网站服务器。
|
||||
|
||||

|
||||
|
||||
<font color=grey>💡 TIPS: 添加后,执行 `curl -H "Host: <域名>" http://<WAF IP>:<端口>` 应能获取到业务网站的响应。</font>
|
||||
|
||||
### 测试效果
|
||||
|
||||
使用以下方式尝试模拟黑客攻击,看看雷池的防护效果如何
|
||||
|
||||
- 浏览器访问 `http://<IP或域名>:<端口>/?id=1%20AND%201=1`
|
||||
- 浏览器访问 `http://<IP或域名>:<端口>/?a=<script>alert(1)</script>`
|
||||
|
||||

|
||||
|
||||
> 如果你需要进行深度测试,请参考 <a href="https://waf-ce.chaitin.cn/posts/guide_test">测试防护效果</a>
|
||||
|
||||
### FAQ
|
||||
|
||||
- [安装问题](https://waf-ce.chaitin.cn/posts/faq_install)
|
||||
- [登录问题](https://waf-ce.chaitin.cn/posts/faq_login)
|
||||
- [网站无法访问](https://waf-ce.chaitin.cn/posts/faq_access)
|
||||
- [配置问题](https://waf-ce.chaitin.cn/posts/faq_config)
|
||||
- [其他问题](https://waf-ce.chaitin.cn/posts/faq_other)
|
||||
|
||||
## 🏘️ 联系我们
|
||||
|
||||
1. 可以通过 GitHub Issue 直接进行 Bug 反馈和功能建议
|
||||
2. 可以扫描下方二维码加入雷池社区版用户讨论群
|
||||
|
||||
<img src="https://raw.githubusercontent.com/chaitin/SafeLine/main/documents/static/images/wechat-230825.png" width="30%" />
|
||||
|
||||
## Star History <a name="star-history"></a>
|
||||
|
||||
<a href="https://github.com/chaitin/safeline/stargazers">
|
||||
<img width="500" alt="Star History Chart" src="https://api.star-history.com/svg?repos=chaitin/safeline&type=Date">
|
||||
</a>
|
||||
|
|
115
README_CN.md
|
@ -1,115 +0,0 @@
|
|||
<p align="center">
|
||||
<img src="/images/banner.png" width="400" />
|
||||
</p>
|
||||
|
||||
<h4 align="center">
|
||||
SafeLine - 雷池 - 不让黑客越过半步
|
||||
</h4>
|
||||
|
||||
<p align="center">
|
||||
<a target="_blank" href="https://waf-ce.chaitin.cn/">🏠 官网</a> |
|
||||
<a target="_blank" href="https://docs.waf-ce.chaitin.cn/">📖 文档</a> |
|
||||
<a target="_blank" href="https://demo.waf-ce.chaitin.cn:9443/">🔍 演示环境</a> |
|
||||
<a target="_blank" href="/images/wechat.png">🙋♂️ 社区微信群</a> |
|
||||
<a target="_blank" href="https://github.com/chaitin/SafeLine">国际版</a>
|
||||
</p>
|
||||
|
||||
## 👋 项目介绍
|
||||
|
||||
SafeLine,中文名 "雷池",是一款简单好用, 效果突出的 **`Web 应用防火墙(WAF)`**,可以保护 Web 服务不受黑客攻击。
|
||||
|
||||
雷池通过过滤和监控 Web 应用与互联网之间的 HTTP 流量来保护 Web 服务。可以保护 Web 服务免受 `SQL 注入`、`XSS`、 `代码注入`、`命令注入`、`CRLF 注入`、`ldap 注入`、`xpath 注入`、`RCE`、`XXE`、`SSRF`、`路径遍历`、`后门`、`暴力破解`、`CC`、`爬虫` 等攻击。
|
||||
|
||||
#### 💡 工作原理
|
||||
|
||||
<img src="/images/how-it-works.png" width="800" />
|
||||
|
||||
雷池通过阻断流向 Web 服务的恶意 HTTP 流量来保护 Web 服务。雷池作为反向代理接入网络,通过在 Web 服务前部署雷池,可在 Web 服务和互联网之间设置一道屏障。
|
||||
|
||||
雷池的核心功能如下:
|
||||
|
||||
- 防护 Web 攻击
|
||||
- 防爬虫, 防扫描
|
||||
- 前端代码动态加密
|
||||
- 基于源 IP 的访问速率限制
|
||||
- HTTP 访问控制
|
||||
|
||||
#### ⚡️ 项目截图
|
||||
|
||||
| <img src="./images/screenshot-1.png" width=370 /> | <img src="./images/screenshot-2.png" width=370 /> |
|
||||
| ------------------------------------------------- | ------------------------------------------------- |
|
||||
| <img src="./images/screenshot-3.png" width=370 /> | <img src="./images/screenshot-4.png" width=370 /> |
|
||||
|
||||
查看 [演示环境](https://demo.waf-ce.chaitin.cn:9443/)
|
||||
|
||||
## 🔥 核心能力
|
||||
|
||||
对于你的网站而言, 雷池可以实现如下效果:
|
||||
|
||||
- **`阻断 Web 攻击`**
|
||||
- 可以防御所有的 Web 攻击,例如 `SQL 注入`、`XSS`、`代码注入`、`操作系统命令注入`、`CRLF 注入`、`XXE`、`SSRF`、`路径遍历` 等等。
|
||||
- **`限制访问频率`**
|
||||
- 限制用户的访问速率,让 Web 服务免遭 `CC 攻击`、`暴力破解`、`流量激增` 和其他类型的滥用。
|
||||
- **`人机验证`**
|
||||
- 互联网上有来自真人用户的流量,但更多的是由爬虫, 漏洞扫描器, 蠕虫病毒, 漏洞利用程序等自动化程序发起的流量,开启雷池的人机验证功能后真人用户会被放行,恶意爬虫将会被阻断。
|
||||
- **`身份认证`**
|
||||
- 雷池的 "身份认证" 功能可以很好的解决 "未授权访问" 漏洞,当用户访问您的网站时,需要输入您配置的用户名和密码信息,不持有认证信息的用户将被拒之门外。
|
||||
- **`动态防护`**
|
||||
- 在用户浏览到的网页内容不变的情况下,将网页赋予动态特性,对 HTML 和 JavaScript 代码进行动态加密,确保每次访问时这些代码都以随机且独特的形态呈现。
|
||||
|
||||
#### 🧩 核心能力展示
|
||||
|
||||
| | Legitimate User | Malicious User |
|
||||
| ----------------------------- | --------------------------------------------------- | ---------------------------------------------------------------- |
|
||||
| **`阻断 Web 攻击`** | <img src="./images/skeleton.png" width=270 /> | <img src="./images/blocked-for-attack-detected.png" width=270 /> |
|
||||
| **`限制访问频率`** | <img src="./images/skeleton.png" width=270 /> | <img src="./images/blocked-for-access-too-fast.png" width=270 /> |
|
||||
| **`人机验证`** | <img src="./images/captcha-1.gif" width=270 /> | <img src="./images/captcha-2.gif" width=270 /> |
|
||||
| **`身份认证`** | <img src="./images/auth-1.gif" width=270 /> | <img src="./images/auth-2.gif" width=270 /> |
|
||||
| **`HTML 动态防护`** | <img src="./images/dynamic-html-1.png" width=270 /> | <img src="./images/dynamic-html-2.png" width=270 /> |
|
||||
| **`JS 动态防护`** | <img src="./images/dynamic-js-1.png" width=270 /> | <img src="./images/dynamic-js-2.png" width=270 /> |
|
||||
|
||||
## 🚀 上手指南
|
||||
|
||||
#### 📦 安装
|
||||
|
||||
查看 [安装雷池](https://docs.waf-ce.chaitin.cn/zh/%E4%B8%8A%E6%89%8B%E6%8C%87%E5%8D%97/%E5%AE%89%E8%A3%85%E9%9B%B7%E6%B1%A0)
|
||||
|
||||
#### ⚙️ 配置防护站点
|
||||
|
||||
查看 [快速配置](https://docs.waf-ce.chaitin.cn/zh/%E4%B8%8A%E6%89%8B%E6%8C%87%E5%8D%97/%E5%BF%AB%E9%80%9F%E9%85%8D%E7%BD%AE)
|
||||
|
||||
## 📋 更多信息
|
||||
|
||||
#### 防护效果测试
|
||||
|
||||
| Metric | ModSecurity, Level 1 | CloudFlare | 雷池, 平衡 | 雷池, 严格 |
|
||||
| ----------------- | -------------------- | -------------------- | ---------------------- | --------------------- |
|
||||
| 样本数量 | 33669 | 33669 | 33669 | 33669 |
|
||||
| **检出率** | 69.74% | 10.70% | 71.65% | **76.17%** |
|
||||
| **误报率** | 17.58% | 0.07% | **0.07%** | 0.22% |
|
||||
| **准确率** | 82.20% | 98.40% | **99.45%** | 99.38% |
|
||||
|
||||
|
||||
#### 雷池可以投入生产使用吗
|
||||
|
||||
是的,已经有不少用户将雷池投入生产使用,截至目前
|
||||
|
||||
- 全球累计装机量已超过 18 万台
|
||||
- 防护的网站数量超过 100 万个
|
||||
- 每天清洗 HTTP 请求超过 300 亿次
|
||||
|
||||
#### 🙋♂️ 用户社区
|
||||
|
||||
欢迎加入雷池 [社区微信群](/images/wechat.png) 进行技术交流。
|
||||
|
||||
也可以加入雷池 [Discord](https://discord.gg/SVnZGzHFvn) 来获取更多社区支持。
|
||||
|
||||
<p align="left">
|
||||
<a target="_blank" href="/images/wechat.png"><img src="https://img.shields.io/badge/WeChat-07C160?style=flat&logo=wechat&logoColor=white"></a>
|
||||
<a target="_blank" href="https://discord.gg/SVnZGzHFvn"><img src="https://img.shields.io/badge/Discord-5865F2?style=flat&logo=discord&logoColor=white"></a>
|
||||
<a target="_blank" href="https://x.com/safeline_waf"><img src="https://img.shields.io/badge/X.com-000000?style=flat&logo=x&logoColor=white"></a>
|
||||
</p>
|
||||
|
||||
#### 💪 专业版
|
||||
|
||||
查看 [社区版 vs 专业版](https://waf-ce.chaitin.cn/version)
|
112
README_EN.md
Normal file
|
@ -0,0 +1,112 @@
|
|||
<p align="center">
|
||||
<img src="https://ctstack-oss.oss-cn-beijing.aliyuncs.com/veinmind/safeline-assets/safeline_logo.png" width="120">
|
||||
</p>
|
||||
<h1 align="center">SafeLine Community Edition</h1>
|
||||
<h3 align="center">Keep hackers at bay</h3>
|
||||
<br>
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/SafeLine-BEST_WAF-blue">
|
||||
<img src="https://img.shields.io/github/release/chaitin/safeline.svg?color=blue" />
|
||||
<img src="https://img.shields.io/github/release-date/chaitin/safeline.svg?color=blue&label=update" />
|
||||
<img src="https://img.shields.io/docker/v/chaitin/safeline-mgt-api?color=blue">
|
||||
<img src="https://img.shields.io/github/stars/chaitin/safeline?style=social">
|
||||
</p>
|
||||
|
||||
<p align="center"> <a href="https://waf-ce.chaitin.cn/">Official Website</a> </p>
|
||||
<p align="center"> English | <a href="README_CN.md">中文文档</a> </p>
|
||||
|
||||
A simple and easy to use WAF tool. Built on [Chaitin Technology](https://www.chaitin.cn/en/)'s ace 🤖️Intelligent Semantic Analysis algorithm🤖️, designed for the community.
|
||||
|
||||
## ✨ Demo
|
||||
|
||||
### 🔥🔥🔥 Online Demo: https://demo.waf-ce.chaitin.cn:9443/
|
||||
|
||||
There is a simple http server, listened on `http://127.0.0.1:8889`, can be used as for testing.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 🚀 Installation
|
||||
|
||||
### 1. Make sure [Docker](https://docs.docker.com/engine/install/) and [Compose V2](https://docs.docker.com/compose/install/) are installed correctly on the machine
|
||||
```shell
|
||||
docker info # >= 20.10.6
|
||||
docker compose version # >= 2.0.0
|
||||
```
|
||||
|
||||
### 2. Setup and deploy
|
||||
|
||||
```shell
|
||||
mkdir -p safeline && cd safeline
|
||||
# setup
|
||||
curl -kfLsS https://waf-ce.chaitin.cn/release/latest/setup.sh | bash
|
||||
|
||||
# launch
|
||||
sudo docker compose up -d
|
||||
```
|
||||
|
||||
#### Upgrade
|
||||
|
||||
**WARN: SafeLine will be restarted and your traffic will be unavailable for a short period of time. You may need to choose a proper time for upgration.**
|
||||
|
||||
```shell
|
||||
curl -kfLsS https://waf-ce.chaitin.cn/release/latest/upgrade.sh | bash
|
||||
|
||||
# delete the old used image layers if necessary.
|
||||
docker rmi $(docker images | grep "safeline" | grep "none" | awk '{print $3}')
|
||||
```
|
||||
|
||||
## 🕹️ Quick Start
|
||||
|
||||
### 1. Login
|
||||
|
||||
Open admin page `https://<waf-ip>:9443` and scan qrcode with any authenticator Apps that support TOTP, enter the code to login.
|
||||
|
||||

|
||||
|
||||
### 2. Create website
|
||||
|
||||

|
||||
|
||||
<font color=grey>💡 TIPS: After creating website,execute `curl -H "Host: <Domain>" http://<WAF IP>:<Port>` to check if you can get correct response from web server.</font>
|
||||
|
||||
### 3. Deploy your website to SafeLine
|
||||
|
||||
- If your website is hosted by DNS, just modify your DNS record to WAF
|
||||
- If your website is behind any reverse-proxy like nginx, you can modify your nginx conf and set upstream to WAF
|
||||
|
||||
### 4. Protected!👌
|
||||
|
||||
Try these:
|
||||
|
||||
- `http://<IP or Domain>:<Port>/webshell.php`
|
||||
- `http://<IP or Domain>:<Port>/?id=1%20AND%201=1`
|
||||
- `http://<IP or Domain>:<Port>/?a=<script>alert(1)</script>`
|
||||
|
||||
## 📖 FAQ
|
||||
|
||||
Please refer to our [FAQ](FAQ.md) first if you have any questions.
|
||||
|
||||
For examples:
|
||||
- [docker compose or docker-compose?](FAQ.md#docker-compose-or-docker-compose)
|
||||
- [website configurations](FAQ.md#站点配置问题)
|
||||
- [website not working / not correctly response](FAQ.md#配置完成之后还是没有成功访问到上游服务器)
|
||||
|
||||
## 🏘️ Contact Us
|
||||
|
||||
1. You can make bug feedback and feature suggestions directly through GitHub Issues.
|
||||
2. By scanning the QR code below (use wechat or qq), you can join the discussion group of SafeLine users for detailed discussions.
|
||||
|
||||
<img src="https://raw.githubusercontent.com/chaitin/SafeLine/main/documents/static/images/wechat-230825.png" width="30%" />
|
||||
|
||||
## ✨ CTStack
|
||||
<img src="https://ctstack-oss.oss-cn-beijing.aliyuncs.com/CT%20Stack-2.png" width="30%" />
|
||||
|
||||
SafeLine has already joined [CTStack](https://stack.chaitin.com/tool/detail?id=717) community.
|
||||
|
||||
## Star History <a name="star-history"></a>
|
||||
|
||||
<a href="https://github.com/chaitin/safeline/stargazers">
|
||||
<img width="500" alt="Star History Chart" src="https://api.star-history.com/svg?repos=chaitin/safeline&type=Date">
|
||||
</a>
|
1
backend/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
server
|
335
backend/docs/docs.go
Normal file
|
@ -0,0 +1,335 @@
|
|||
// Package docs Code generated by swaggo/swag. DO NOT EDIT
|
||||
package docs
|
||||
|
||||
import "github.com/swaggo/swag"
|
||||
|
||||
const docTemplate = `{
|
||||
"schemes": {{ marshal .Schemes }},
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"description": "{{escape .Description}}",
|
||||
"title": "{{.Title}}",
|
||||
"contact": {},
|
||||
"version": "{{.Version}}"
|
||||
},
|
||||
"host": "{{.Host}}",
|
||||
"basePath": "{{.BasePath}}",
|
||||
"paths": {
|
||||
"/exist": {
|
||||
"post": {
|
||||
"description": "get ip if id exist",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Safeline"
|
||||
],
|
||||
"summary": "get ip if id exist",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "body",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.ExistReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/discussions": {
|
||||
"get": {
|
||||
"description": "get discussions from GitHub",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"GitHub"
|
||||
],
|
||||
"summary": "get discussions",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "search by",
|
||||
"name": "q",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/service.Discussion"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/info": {
|
||||
"get": {
|
||||
"description": "get repo info from GitHub",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"GitHub"
|
||||
],
|
||||
"summary": "get repo info",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/service.Repo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/issues": {
|
||||
"get": {
|
||||
"description": "get issues from GitHub",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"GitHub"
|
||||
],
|
||||
"summary": "get issues",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "search by",
|
||||
"name": "q",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/service.Issue"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/safeline/count": {
|
||||
"get": {
|
||||
"description": "get installer count",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Safeline"
|
||||
],
|
||||
"summary": "get installer count",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/service.InstallerCount"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"handler.ExistReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"token": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"service.Category": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"emoji": {
|
||||
"type": "string"
|
||||
},
|
||||
"emoji_html": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"service.Discussion": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"author": {
|
||||
"$ref": "#/definitions/service.User"
|
||||
},
|
||||
"category": {
|
||||
"$ref": "#/definitions/service.Category"
|
||||
},
|
||||
"comment_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"comment_users": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/service.User"
|
||||
}
|
||||
},
|
||||
"created_at": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"is_answered": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/service.Label"
|
||||
}
|
||||
},
|
||||
"thumbs_up": {
|
||||
"type": "integer"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"upvote_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"service.InstallerCount": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"total": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"service.Issue": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"author": {
|
||||
"$ref": "#/definitions/service.User"
|
||||
},
|
||||
"comment_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/service.Label"
|
||||
}
|
||||
},
|
||||
"thumbs_up": {
|
||||
"type": "integer"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"service.Label": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"color": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"service.Repo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"star_count": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"service.User": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"avatar_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"login": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||
var SwaggerInfo = &swag.Spec{
|
||||
Version: "",
|
||||
Host: "",
|
||||
BasePath: "",
|
||||
Schemes: []string{},
|
||||
Title: "",
|
||||
Description: "",
|
||||
InfoInstanceName: "swagger",
|
||||
SwaggerTemplate: docTemplate,
|
||||
LeftDelim: "{{",
|
||||
RightDelim: "}}",
|
||||
}
|
||||
|
||||
func init() {
|
||||
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
|
||||
}
|
306
backend/docs/swagger.json
Normal file
|
@ -0,0 +1,306 @@
|
|||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"contact": {}
|
||||
},
|
||||
"paths": {
|
||||
"/exist": {
|
||||
"post": {
|
||||
"description": "get ip if id exist",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Safeline"
|
||||
],
|
||||
"summary": "get ip if id exist",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "body",
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.ExistReq"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/discussions": {
|
||||
"get": {
|
||||
"description": "get discussions from GitHub",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"GitHub"
|
||||
],
|
||||
"summary": "get discussions",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "search by",
|
||||
"name": "q",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/service.Discussion"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/info": {
|
||||
"get": {
|
||||
"description": "get repo info from GitHub",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"GitHub"
|
||||
],
|
||||
"summary": "get repo info",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/service.Repo"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/repos/issues": {
|
||||
"get": {
|
||||
"description": "get issues from GitHub",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"GitHub"
|
||||
],
|
||||
"summary": "get issues",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "search by",
|
||||
"name": "q",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/service.Issue"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/safeline/count": {
|
||||
"get": {
|
||||
"description": "get installer count",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Safeline"
|
||||
],
|
||||
"summary": "get installer count",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/service.InstallerCount"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"handler.ExistReq": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"token": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"service.Category": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"emoji": {
|
||||
"type": "string"
|
||||
},
|
||||
"emoji_html": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"service.Discussion": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"author": {
|
||||
"$ref": "#/definitions/service.User"
|
||||
},
|
||||
"category": {
|
||||
"$ref": "#/definitions/service.Category"
|
||||
},
|
||||
"comment_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"comment_users": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/service.User"
|
||||
}
|
||||
},
|
||||
"created_at": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"is_answered": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/service.Label"
|
||||
}
|
||||
},
|
||||
"thumbs_up": {
|
||||
"type": "integer"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"upvote_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"service.InstallerCount": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"total": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"service.Issue": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"author": {
|
||||
"$ref": "#/definitions/service.User"
|
||||
},
|
||||
"comment_count": {
|
||||
"type": "integer"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "integer"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/service.Label"
|
||||
}
|
||||
},
|
||||
"thumbs_up": {
|
||||
"type": "integer"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"service.Label": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"color": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"service.Repo": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"star_count": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"service.User": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"avatar_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"login": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
197
backend/docs/swagger.yaml
Normal file
|
@ -0,0 +1,197 @@
|
|||
definitions:
|
||||
handler.ExistReq:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
token:
|
||||
type: string
|
||||
type: object
|
||||
service.Category:
|
||||
properties:
|
||||
emoji:
|
||||
type: string
|
||||
emoji_html:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
type: object
|
||||
service.Discussion:
|
||||
properties:
|
||||
author:
|
||||
$ref: '#/definitions/service.User'
|
||||
category:
|
||||
$ref: '#/definitions/service.Category'
|
||||
comment_count:
|
||||
type: integer
|
||||
comment_users:
|
||||
items:
|
||||
$ref: '#/definitions/service.User'
|
||||
type: array
|
||||
created_at:
|
||||
type: integer
|
||||
id:
|
||||
type: string
|
||||
is_answered:
|
||||
type: boolean
|
||||
labels:
|
||||
items:
|
||||
$ref: '#/definitions/service.Label'
|
||||
type: array
|
||||
thumbs_up:
|
||||
type: integer
|
||||
title:
|
||||
type: string
|
||||
upvote_count:
|
||||
type: integer
|
||||
url:
|
||||
type: string
|
||||
type: object
|
||||
service.InstallerCount:
|
||||
properties:
|
||||
total:
|
||||
type: integer
|
||||
type: object
|
||||
service.Issue:
|
||||
properties:
|
||||
author:
|
||||
$ref: '#/definitions/service.User'
|
||||
comment_count:
|
||||
type: integer
|
||||
created_at:
|
||||
type: integer
|
||||
id:
|
||||
type: string
|
||||
labels:
|
||||
items:
|
||||
$ref: '#/definitions/service.Label'
|
||||
type: array
|
||||
thumbs_up:
|
||||
type: integer
|
||||
title:
|
||||
type: string
|
||||
url:
|
||||
type: string
|
||||
type: object
|
||||
service.Label:
|
||||
properties:
|
||||
color:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
type: object
|
||||
service.Repo:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
star_count:
|
||||
type: integer
|
||||
type: object
|
||||
service.User:
|
||||
properties:
|
||||
avatar_url:
|
||||
type: string
|
||||
login:
|
||||
type: string
|
||||
type: object
|
||||
info:
|
||||
contact: {}
|
||||
paths:
|
||||
/exist:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: get ip if id exist
|
||||
parameters:
|
||||
- description: body
|
||||
in: body
|
||||
name: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/handler.ExistReq'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
type: string
|
||||
summary: get ip if id exist
|
||||
tags:
|
||||
- Safeline
|
||||
/repos/discussions:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: get discussions from GitHub
|
||||
parameters:
|
||||
- description: search by
|
||||
in: query
|
||||
name: q
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/service.Discussion'
|
||||
type: array
|
||||
summary: get discussions
|
||||
tags:
|
||||
- GitHub
|
||||
/repos/info:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: get repo info from GitHub
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/service.Repo'
|
||||
summary: get repo info
|
||||
tags:
|
||||
- GitHub
|
||||
/repos/issues:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: get issues from GitHub
|
||||
parameters:
|
||||
- description: search by
|
||||
in: query
|
||||
name: q
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/service.Issue'
|
||||
type: array
|
||||
summary: get issues
|
||||
tags:
|
||||
- GitHub
|
||||
/safeline/count:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: get installer count
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/service.InstallerCount'
|
||||
summary: get installer count
|
||||
tags:
|
||||
- Safeline
|
||||
swagger: "2.0"
|
65
backend/go.mod
Normal file
|
@ -0,0 +1,65 @@
|
|||
module github.com/chaitin/SafeLine
|
||||
|
||||
go 1.21.3
|
||||
|
||||
require (
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/shurcooL/githubv4 v0.0.0-20230704064427-599ae7bbf278
|
||||
github.com/spf13/viper v1.17.0
|
||||
github.com/swaggo/files v1.0.1
|
||||
github.com/swaggo/gin-swagger v1.6.0
|
||||
github.com/swaggo/swag v1.16.2
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/bytedance/sonic v1.10.2 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
||||
github.com/chenzhuoyu/iasm v0.9.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.20.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/spec v0.20.9 // indirect
|
||||
github.com/go-openapi/swag v0.22.4 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.16.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.3.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.10.0 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
golang.org/x/arch v0.6.0 // indirect
|
||||
golang.org/x/crypto v0.15.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
|
||||
golang.org/x/net v0.18.0 // indirect
|
||||
golang.org/x/oauth2 v0.14.0 // indirect
|
||||
golang.org/x/sys v0.14.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.15.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
629
backend/go.sum
Normal file
|
@ -0,0 +1,629 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
|
||||
github.com/bytedance/sonic v1.10.2 h1:GQebETVBxYB7JGWJtLBi07OVzWwt+8dWA00gEVW2ZFE=
|
||||
github.com/bytedance/sonic v1.10.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
|
||||
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||
github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
|
||||
github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
|
||||
github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ=
|
||||
github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA=
|
||||
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
|
||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
||||
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||
github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8=
|
||||
github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
|
||||
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.16.0 h1:x+plE831WK4vaKHO/jpgUGsvLKIqRRkz6M78GuJAfGE=
|
||||
github.com/go-playground/validator/v10 v10.16.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ=
|
||||
github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
||||
github.com/shurcooL/githubv4 v0.0.0-20230704064427-599ae7bbf278 h1:kdEGVAV4sO46DPtb8k793jiecUEhaX9ixoIBt41HEGU=
|
||||
github.com/shurcooL/githubv4 v0.0.0-20230704064427-599ae7bbf278/go.mod h1:zqMwyHmnN/eDOZOdiTohqIUKUrTFX62PNlu7IJdu0q8=
|
||||
github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466 h1:17JxqqJY66GmZVHkmAsGEkcIu0oCe3AM420QDgGwZx0=
|
||||
github.com/shurcooL/graphql v0.0.0-20230722043721-ed46e5a46466/go.mod h1:9dIRpgIY7hVhoqfe0/FcYp0bpInZaT7dc3BYOprrIUE=
|
||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||
github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY=
|
||||
github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
|
||||
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
|
||||
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI=
|
||||
github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
||||
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
||||
github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M=
|
||||
github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo=
|
||||
github.com/swaggo/swag v1.16.2 h1:28Pp+8DkQoV+HLzLx8RGJZXNGKbFqnuvSbAAtoxiY04=
|
||||
github.com/swaggo/swag v1.16.2/go.mod h1:6YzXnDcpr0767iOejs318CwYkCQqyGer6BizOg03f+E=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
|
||||
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.6.0 h1:S0JTfE48HbRj80+4tbvZDYsJ3tGv6BUU3XxyZ7CirAc=
|
||||
golang.org/x/arch v0.6.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
|
||||
golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
|
||||
golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
||||
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
|
||||
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0=
|
||||
golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=
|
||||
golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
79
backend/internal/handler/github.go
Normal file
|
@ -0,0 +1,79 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/chaitin/SafeLine/internal/service"
|
||||
)
|
||||
|
||||
// GitHubHandler provides HTTP handlers for GitHub operations.
|
||||
type GitHubHandler struct {
|
||||
gitHubService *service.GitHubService
|
||||
}
|
||||
|
||||
// NewGitHubHandler creates a new instance of GitHubHandler.
|
||||
func NewGitHubHandler(gitHubService *service.GitHubService) *GitHubHandler {
|
||||
return &GitHubHandler{
|
||||
gitHubService: gitHubService,
|
||||
}
|
||||
}
|
||||
|
||||
// GetIssues handles GET requests for fetching GitHub issues.
|
||||
// @Summary get issues
|
||||
// @Description get issues from GitHub
|
||||
// @Tags GitHub
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param q query string false "search by"
|
||||
// @Success 200 {array} service.Issue
|
||||
// @Router /repos/issues [get]
|
||||
func (h *GitHubHandler) GetIssues(c *gin.Context) {
|
||||
filter := c.Query("q")
|
||||
|
||||
issues, err := h.gitHubService.GetIssues(c, filter)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, issues)
|
||||
}
|
||||
|
||||
// GetDiscussions handles GET requests for fetching GitHub discussions.
|
||||
// @Summary get discussions
|
||||
// @Description get discussions from GitHub
|
||||
// @Tags GitHub
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param q query string false "search by"
|
||||
// @Success 200 {array} service.Discussion
|
||||
// @Router /repos/discussions [get]
|
||||
func (h *GitHubHandler) GetDiscussions(c *gin.Context) {
|
||||
filter := c.Query("q")
|
||||
|
||||
discussions, err := h.gitHubService.GetDiscussions(c, filter)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, discussions)
|
||||
}
|
||||
|
||||
// GetRepo handles GET requests for fetching GitHub repo info.
|
||||
// @Summary get repo info
|
||||
// @Description get repo info from GitHub
|
||||
// @Tags GitHub
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} service.Repo
|
||||
// @Router /repos/info [get]
|
||||
func (h *GitHubHandler) GetRepo(c *gin.Context) {
|
||||
repo, err := h.gitHubService.GetRepo(c)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, repo)
|
||||
}
|
64
backend/internal/handler/safeline.go
Normal file
|
@ -0,0 +1,64 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/chaitin/SafeLine/internal/service"
|
||||
)
|
||||
|
||||
type SafelineHandler struct {
|
||||
safelineService *service.SafelineService
|
||||
}
|
||||
|
||||
func NewSafelineHandler(safelineService *service.SafelineService) *SafelineHandler {
|
||||
return &SafelineHandler{
|
||||
safelineService: safelineService,
|
||||
}
|
||||
}
|
||||
|
||||
// GetInstallerCount
|
||||
// @Summary get installer count
|
||||
// @Description get installer count
|
||||
// @Tags Safeline
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Success 200 {object} service.InstallerCount
|
||||
// @Router /safeline/count [get]
|
||||
func (h *SafelineHandler) GetInstallerCount(c *gin.Context) {
|
||||
count, err := h.safelineService.GetInstallerCount(c)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(200, count)
|
||||
}
|
||||
|
||||
type ExistReq struct {
|
||||
Id string `json:"id"`
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// Exist return ip if id exist
|
||||
// @Summary get ip if id exist
|
||||
// @Description get ip if id exist
|
||||
// @Tags Safeline
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param body body ExistReq true "body"
|
||||
// @Success 200 {object} string
|
||||
// @Router /exist [post]
|
||||
func (h *SafelineHandler) Exist(c *gin.Context) {
|
||||
req := &ExistReq{}
|
||||
if err := c.ShouldBindJSON(req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
ip, err := h.safelineService.GetExist(c, req.Id, req.Token)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
c.JSON(200, gin.H{"ip": ip})
|
||||
}
|
507
backend/internal/service/github.go
Normal file
|
@ -0,0 +1,507 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"net/http"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/shurcooL/githubv4"
|
||||
)
|
||||
|
||||
type LabelName = string
|
||||
|
||||
const (
|
||||
LabelNameEnhancement LabelName = "enhancement"
|
||||
LabelNameInProgress LabelName = "in progress"
|
||||
LabelNameReleased LabelName = "released"
|
||||
)
|
||||
|
||||
type RoadmapLabelName = string
|
||||
|
||||
const (
|
||||
RoadmapLabelNameInConsideration RoadmapLabelName = "in_consideration"
|
||||
RoadmapLabelNameInProgress RoadmapLabelName = "in_progress"
|
||||
RoadmapLabelNameReleased RoadmapLabelName = "released"
|
||||
)
|
||||
|
||||
type Label struct {
|
||||
Name string `json:"name"`
|
||||
Color string `json:"color"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
Login string `json:"login"`
|
||||
AvatarUrl string `json:"avatar_url"`
|
||||
}
|
||||
|
||||
type IssueState = string
|
||||
|
||||
const (
|
||||
IssueStateOpened IssueState = "OPEN"
|
||||
IssueStateClosed IssueState = "CLOSED"
|
||||
)
|
||||
|
||||
// Issue represents a GitHub issue with minimal fields.
|
||||
type Issue struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Body string `json:"-"`
|
||||
State IssueState `json:"state"`
|
||||
Url string `json:"url"`
|
||||
Labels []Label `json:"labels"`
|
||||
CommentCount int `json:"comment_count"`
|
||||
ThumbsUpCount int `json:"thumbs_up"`
|
||||
Author User `json:"author"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
UpdatedAt int64 `json:"updated_at"`
|
||||
}
|
||||
|
||||
func (i Issue) InConsideration() bool {
|
||||
if i.State != IssueStateOpened {
|
||||
return false
|
||||
}
|
||||
if !slices.Contains(i.LabelNames(), LabelNameEnhancement) {
|
||||
return false
|
||||
}
|
||||
if slices.Contains(i.LabelNames(), LabelNameInProgress) {
|
||||
return false
|
||||
}
|
||||
if slices.Contains(i.LabelNames(), LabelNameReleased) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (i Issue) InProgress() bool {
|
||||
return i.State == IssueStateOpened && slices.Contains(i.LabelNames(), LabelNameInProgress)
|
||||
}
|
||||
|
||||
func (i Issue) Released() bool {
|
||||
return slices.Contains(i.LabelNames(), LabelNameReleased)
|
||||
}
|
||||
|
||||
func (i Issue) LabelNames() []string {
|
||||
var names []string
|
||||
for _, v := range i.Labels {
|
||||
names = append(names, v.Name)
|
||||
}
|
||||
return names
|
||||
}
|
||||
|
||||
// Discussion represents a GitHub discussion.
|
||||
type Discussion struct {
|
||||
ID string `json:"id"`
|
||||
Url string `json:"url"`
|
||||
Title string `json:"title"`
|
||||
BodyText string `json:"-"`
|
||||
Labels []Label `json:"labels"`
|
||||
ThumbsUpCount int `json:"thumbs_up"`
|
||||
CommentCount int `json:"comment_count"`
|
||||
UpvoteCount int `json:"upvote_count"`
|
||||
Author User `json:"author"`
|
||||
CommentUsers []User `json:"comment_users"`
|
||||
CreatedAt int64 `json:"created_at"`
|
||||
IsAnswered bool `json:"is_answered"`
|
||||
Category Category `json:"category"`
|
||||
}
|
||||
|
||||
type Category struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Emoji string `json:"emoji"`
|
||||
EmojiHTML string `json:"emoji_html" graphql:"emojiHTML"`
|
||||
}
|
||||
|
||||
type Repo struct {
|
||||
ID string `json:"id"`
|
||||
StarCount int `json:"star_count"`
|
||||
}
|
||||
|
||||
type GitHubAPI interface {
|
||||
Query(ctx context.Context, q interface{}, variables map[string]interface{}) error
|
||||
}
|
||||
|
||||
// GitHubService provides methods to interact with the GitHub API.
|
||||
type GitHubService struct {
|
||||
token string
|
||||
cache sync.Map
|
||||
cacheTTL time.Duration
|
||||
owner string
|
||||
repo string
|
||||
}
|
||||
|
||||
type GithubConfig struct {
|
||||
Token string
|
||||
Owner string
|
||||
Repo string
|
||||
CacheTTL time.Duration
|
||||
}
|
||||
|
||||
// headerTransport is custom Transport used to add header information to the request
|
||||
type headerTransport struct {
|
||||
transport *http.Transport
|
||||
headers map[string]string
|
||||
}
|
||||
|
||||
// RoundTrip implements the http.RoundTripper interface
|
||||
func (h *headerTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
for key, value := range h.headers {
|
||||
req.Header.Add(key, value)
|
||||
}
|
||||
return h.transport.RoundTrip(req)
|
||||
}
|
||||
|
||||
// NewGitHubService creates a new instance of GitHubService with authorized client.
|
||||
func NewGitHubService(cfg *GithubConfig) *GitHubService {
|
||||
s := &GitHubService{
|
||||
token: cfg.Token,
|
||||
cache: sync.Map{},
|
||||
cacheTTL: cfg.CacheTTL,
|
||||
owner: cfg.Owner,
|
||||
repo: cfg.Repo,
|
||||
}
|
||||
go s.loop()
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *GitHubService) loop() {
|
||||
s.refreshCache()
|
||||
|
||||
t := time.NewTicker(s.cacheTTL * time.Minute)
|
||||
defer t.Stop()
|
||||
for range t.C {
|
||||
s.refreshCache()
|
||||
}
|
||||
}
|
||||
|
||||
func (s *GitHubService) client(proxy bool) GitHubAPI {
|
||||
httpClient := &http.Client{
|
||||
Transport: &headerTransport{
|
||||
transport: &http.Transport{},
|
||||
headers: map[string]string{"Authorization": "Bearer " + s.token},
|
||||
},
|
||||
}
|
||||
|
||||
if proxy {
|
||||
httpClient.Transport.(*headerTransport).transport = &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
}
|
||||
}
|
||||
|
||||
return githubv4.NewClient(httpClient)
|
||||
}
|
||||
|
||||
func (s *GitHubService) request(ctx context.Context, q interface{}, variables map[string]interface{}) (err error) {
|
||||
err = s.client(true).Query(ctx, q, variables)
|
||||
if err != nil {
|
||||
log.Printf("request using proxy fails and falls back to non-proxy mode: %#v", err)
|
||||
err = s.client(false).Query(ctx, q, variables)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *GitHubService) refreshCache() {
|
||||
issues, err := s.fetchIssues(context.Background(), nil)
|
||||
if err != nil {
|
||||
log.Printf("failed to fetch issues %v", err)
|
||||
return
|
||||
}
|
||||
s.cache.Store("issues", issues)
|
||||
|
||||
discussions, err := s.fetchDiscussions(context.Background(), nil)
|
||||
if err != nil {
|
||||
log.Printf("failed to fetch discussions %v", err)
|
||||
return
|
||||
}
|
||||
s.cache.Store("discussions", discussions)
|
||||
|
||||
repo, err := s.fetchRepo(context.Background())
|
||||
if err != nil {
|
||||
log.Printf("failed to fetch repo %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
s.cache.Store("repo", repo)
|
||||
}
|
||||
|
||||
// GetIssues tries to get the issues from cache; if not available, fetches from GitHub API.
|
||||
func (s *GitHubService) GetIssues(ctx context.Context, filter string) (map[string][]*Issue, error) {
|
||||
cachedIssues, found := s.cache.Load("issues")
|
||||
if found {
|
||||
return s.filterIssues(cachedIssues.([]*Issue), filter)
|
||||
}
|
||||
|
||||
issues, err := s.fetchIssues(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.filterIssues(issues, filter)
|
||||
}
|
||||
|
||||
func (s *GitHubService) filterIssues(issues []*Issue, filter string) (map[string][]*Issue, error) {
|
||||
filteredIssues := issues
|
||||
if filter != "" {
|
||||
filteredIssues = make([]*Issue, 0)
|
||||
for _, issue := range issues {
|
||||
if strings.Contains(issue.Title, filter) || strings.Contains(issue.Body, filter) {
|
||||
filteredIssues = append(filteredIssues, issue)
|
||||
}
|
||||
}
|
||||
}
|
||||
out := make(map[string][]*Issue)
|
||||
for _, issue := range filteredIssues {
|
||||
if issue.InConsideration() {
|
||||
out[RoadmapLabelNameInConsideration] = append(out[RoadmapLabelNameInConsideration], issue)
|
||||
}
|
||||
if issue.InProgress() {
|
||||
out[RoadmapLabelNameInProgress] = append(out[RoadmapLabelNameInProgress], issue)
|
||||
}
|
||||
if issue.Released() {
|
||||
out[RoadmapLabelNameReleased] = append(out[RoadmapLabelNameReleased], issue)
|
||||
}
|
||||
}
|
||||
sort.Slice(out[RoadmapLabelNameInConsideration], func(i, j int) bool {
|
||||
return out[RoadmapLabelNameInConsideration][i].ThumbsUpCount > out[RoadmapLabelNameInConsideration][j].ThumbsUpCount
|
||||
})
|
||||
sort.Slice(out[RoadmapLabelNameInProgress], func(i, j int) bool {
|
||||
return out[RoadmapLabelNameInProgress][i].ThumbsUpCount > out[RoadmapLabelNameInProgress][j].ThumbsUpCount
|
||||
})
|
||||
sort.Slice(out[RoadmapLabelNameReleased], func(i, j int) bool {
|
||||
return out[RoadmapLabelNameReleased][i].UpdatedAt > out[RoadmapLabelNameReleased][j].UpdatedAt
|
||||
})
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetRepositoryIssues queries GitHub for issues of a repository.
|
||||
func (s *GitHubService) fetchIssues(ctx context.Context, afterCursor *githubv4.String) ([]*Issue, error) {
|
||||
var query struct {
|
||||
Repository struct {
|
||||
Issues struct {
|
||||
Nodes []struct {
|
||||
ID string
|
||||
Title string
|
||||
Body string
|
||||
Url string
|
||||
State string
|
||||
CreatedAt githubv4.DateTime
|
||||
UpdatedAt githubv4.DateTime
|
||||
Author User
|
||||
Labels struct {
|
||||
Nodes []struct {
|
||||
Color string
|
||||
Name string
|
||||
}
|
||||
} `graphql:"labels(first: 10)"`
|
||||
Comments struct {
|
||||
TotalCount int
|
||||
}
|
||||
Reactions struct {
|
||||
TotalCount int
|
||||
} `graphql:"reactions(content: THUMBS_UP)"`
|
||||
}
|
||||
PageInfo struct {
|
||||
EndCursor githubv4.String
|
||||
HasNextPage bool
|
||||
}
|
||||
} `graphql:"issues(first: 100, after: $afterCursor, orderBy: {field: UPDATED_AT, direction: DESC})"`
|
||||
} `graphql:"repository(owner: $owner, name: $name)"`
|
||||
}
|
||||
variables := map[string]interface{}{
|
||||
"owner": githubv4.String(s.owner),
|
||||
"name": githubv4.String(s.repo),
|
||||
"afterCursor": afterCursor,
|
||||
}
|
||||
|
||||
err := s.request(ctx, &query, variables)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
issues := make([]*Issue, 0)
|
||||
for _, node := range query.Repository.Issues.Nodes {
|
||||
issue := &Issue{
|
||||
ID: node.ID,
|
||||
Title: node.Title,
|
||||
Body: node.Body,
|
||||
Url: node.Url,
|
||||
State: node.State,
|
||||
CreatedAt: node.CreatedAt.Unix(),
|
||||
UpdatedAt: node.UpdatedAt.Unix(),
|
||||
Author: node.Author,
|
||||
CommentCount: node.Comments.TotalCount,
|
||||
ThumbsUpCount: node.Reactions.TotalCount,
|
||||
}
|
||||
issue.Labels = make([]Label, len(node.Labels.Nodes))
|
||||
for i, label := range node.Labels.Nodes {
|
||||
issue.Labels[i] = Label{Name: label.Name, Color: label.Color}
|
||||
}
|
||||
issues = append(issues, issue)
|
||||
}
|
||||
|
||||
if query.Repository.Issues.PageInfo.HasNextPage {
|
||||
moreIssues, err := s.fetchIssues(ctx, &query.Repository.Issues.PageInfo.EndCursor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
issues = append(issues, moreIssues...)
|
||||
}
|
||||
|
||||
return issues, nil
|
||||
}
|
||||
|
||||
// GetDiscussions tries to get the discussions from cache; if not available, fetches from GitHub API.
|
||||
func (s *GitHubService) GetDiscussions(ctx context.Context, filter string) ([]*Discussion, error) {
|
||||
if cachedData, found := s.cache.Load("discussions"); found {
|
||||
return s.filterDiscussions(cachedData.([]*Discussion), filter)
|
||||
}
|
||||
|
||||
discussions, err := s.fetchDiscussions(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s.filterDiscussions(discussions, filter)
|
||||
}
|
||||
|
||||
func (s *GitHubService) filterDiscussions(discussions []*Discussion, filter string) ([]*Discussion, error) {
|
||||
if filter != "" {
|
||||
filteredDiscussions := make([]*Discussion, 0)
|
||||
for _, discussion := range discussions {
|
||||
if strings.Contains(discussion.Title, filter) || strings.Contains(discussion.BodyText, filter) {
|
||||
filteredDiscussions = append(filteredDiscussions, discussion)
|
||||
}
|
||||
}
|
||||
return filteredDiscussions, nil
|
||||
}
|
||||
return discussions, nil
|
||||
}
|
||||
|
||||
// fetchDiscussionsFromGitHub queries GitHub for discussions of a repository.
|
||||
func (s *GitHubService) fetchDiscussions(ctx context.Context, afterCursor *githubv4.String) ([]*Discussion, error) {
|
||||
var query struct {
|
||||
Repository struct {
|
||||
Discussions struct {
|
||||
Nodes []struct {
|
||||
ID string
|
||||
Url string
|
||||
UpvoteCount int
|
||||
Title string
|
||||
BodyText string
|
||||
Author User
|
||||
CreatedAt githubv4.DateTime
|
||||
IsAnswered bool
|
||||
Labels struct {
|
||||
Nodes []struct {
|
||||
Color string
|
||||
Name string
|
||||
}
|
||||
} `graphql:"labels(first: 10)"`
|
||||
Reactions struct {
|
||||
TotalCount int
|
||||
} `graphql:"reactions(content: THUMBS_UP)"`
|
||||
Comments struct {
|
||||
Nodes []struct {
|
||||
Author User
|
||||
}
|
||||
} `graphql:"comments(first: 10)"`
|
||||
Category Category
|
||||
}
|
||||
PageInfo struct {
|
||||
EndCursor githubv4.String
|
||||
HasNextPage bool
|
||||
}
|
||||
} `graphql:"discussions(first: 100, after: $afterCursor, orderBy: {field: CREATED_AT, direction: DESC})"`
|
||||
} `graphql:"repository(owner: $owner, name: $name)"`
|
||||
}
|
||||
variables := map[string]interface{}{
|
||||
"owner": githubv4.String(s.owner),
|
||||
"name": githubv4.String(s.repo),
|
||||
"afterCursor": afterCursor,
|
||||
}
|
||||
|
||||
err := s.request(ctx, &query, variables)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
discussions := make([]*Discussion, 0)
|
||||
for _, node := range query.Repository.Discussions.Nodes {
|
||||
discussion := &Discussion{
|
||||
ID: node.ID,
|
||||
Url: node.Url,
|
||||
Title: node.Title,
|
||||
BodyText: node.BodyText,
|
||||
}
|
||||
discussion.Labels = make([]Label, len(node.Labels.Nodes))
|
||||
for i, label := range node.Labels.Nodes {
|
||||
discussion.Labels[i] = Label{Name: label.Name, Color: label.Color}
|
||||
}
|
||||
exist := make(map[string]struct{})
|
||||
discussion.CommentUsers = make([]User, 0, len(node.Comments.Nodes))
|
||||
discussion.CommentUsers = append(discussion.CommentUsers, node.Author)
|
||||
exist[node.Author.Login] = struct{}{}
|
||||
for _, comment := range node.Comments.Nodes {
|
||||
if _, ok := exist[comment.Author.Login]; ok {
|
||||
continue
|
||||
}
|
||||
exist[comment.Author.Login] = struct{}{}
|
||||
discussion.CommentUsers = append(discussion.CommentUsers, comment.Author)
|
||||
}
|
||||
discussion.ThumbsUpCount = node.Reactions.TotalCount
|
||||
discussion.CommentCount = len(node.Comments.Nodes)
|
||||
discussion.UpvoteCount = node.UpvoteCount
|
||||
discussion.Author = node.Author
|
||||
discussion.CreatedAt = node.CreatedAt.Unix()
|
||||
discussion.IsAnswered = node.IsAnswered
|
||||
discussion.Category = node.Category
|
||||
discussions = append(discussions, discussion)
|
||||
}
|
||||
|
||||
if query.Repository.Discussions.PageInfo.HasNextPage {
|
||||
moreDiscussions, err := s.fetchDiscussions(ctx, &query.Repository.Discussions.PageInfo.EndCursor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
discussions = append(discussions, moreDiscussions...)
|
||||
}
|
||||
|
||||
return discussions, nil
|
||||
}
|
||||
|
||||
func (s *GitHubService) GetRepo(ctx context.Context) (*Repo, error) {
|
||||
if cachedData, found := s.cache.Load("repo"); found {
|
||||
return cachedData.(*Repo), nil
|
||||
}
|
||||
|
||||
repo, err := s.fetchRepo(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s.cache.Store("repo", repo)
|
||||
|
||||
return repo, nil
|
||||
}
|
||||
|
||||
func (s *GitHubService) fetchRepo(ctx context.Context) (*Repo, error) {
|
||||
var query struct {
|
||||
Repository struct {
|
||||
ID string
|
||||
StargazerCount int
|
||||
} `graphql:"repository(owner: $owner, name: $name)"`
|
||||
}
|
||||
variables := map[string]interface{}{
|
||||
"owner": githubv4.String(s.owner),
|
||||
"name": githubv4.String(s.repo),
|
||||
}
|
||||
err := s.request(ctx, &query, variables)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Repo{ID: query.Repository.ID, StarCount: query.Repository.StargazerCount}, nil
|
||||
}
|
83
backend/internal/service/safeline.go
Normal file
|
@ -0,0 +1,83 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var cacheCount InstallerCount
|
||||
|
||||
type InstallerCount struct {
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
type SafelineService struct {
|
||||
client *http.Client
|
||||
APIHost string
|
||||
}
|
||||
|
||||
func NewSafelineService(host string) *SafelineService {
|
||||
return &SafelineService{
|
||||
APIHost: host,
|
||||
client: &http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SafelineService) GetInstallerCount(ctx context.Context) (InstallerCount, error) {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, s.APIHost+"/api/v1/public/safeline/count", nil)
|
||||
if err != nil {
|
||||
return cacheCount, err
|
||||
}
|
||||
res, err := s.client.Do(req)
|
||||
if err != nil {
|
||||
return cacheCount, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
var r map[string]interface{}
|
||||
if err := json.NewDecoder(res.Body).Decode(&r); err != nil {
|
||||
return cacheCount, err
|
||||
}
|
||||
if r["code"].(float64) != 0 {
|
||||
return cacheCount, nil
|
||||
}
|
||||
cacheCount = InstallerCount{
|
||||
Total: int(r["data"].(map[string]interface{})["total"].(float64)),
|
||||
}
|
||||
return cacheCount, nil
|
||||
}
|
||||
|
||||
// GetExist return ip if id exist
|
||||
func (s *SafelineService) GetExist(ctx context.Context, id string, token string) (string, error) {
|
||||
body := fmt.Sprintf(`{"id":"%s", "token": "%s"}`, id, token)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, s.APIHost+"/api/v1/public/safeline/exist", strings.NewReader(body))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
res, err := s.client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
raw, _ := io.ReadAll(res.Body)
|
||||
return "", errors.New(string(raw))
|
||||
}
|
||||
var r map[string]interface{}
|
||||
if err := json.NewDecoder(res.Body).Decode(&r); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if r["code"].(float64) != 0 {
|
||||
return "", nil
|
||||
}
|
||||
return r["data"].(map[string]interface{})["ip"].(string), nil
|
||||
}
|
65
backend/main.go
Normal file
|
@ -0,0 +1,65 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/spf13/viper"
|
||||
swaggerfiles "github.com/swaggo/files"
|
||||
ginSwagger "github.com/swaggo/gin-swagger"
|
||||
|
||||
"github.com/chaitin/SafeLine/docs"
|
||||
"github.com/chaitin/SafeLine/internal/handler"
|
||||
"github.com/chaitin/SafeLine/internal/service"
|
||||
)
|
||||
|
||||
func main() {
|
||||
viper.AutomaticEnv()
|
||||
|
||||
viper.SetDefault("GITHUB_CACHE_TTL", 10) // cache timeout in minutes
|
||||
viper.SetDefault("LISTEN_ADDR", ":8080") // api server addr
|
||||
|
||||
githubToken := viper.GetString("GITHUB_TOKEN")
|
||||
if githubToken == "" {
|
||||
log.Fatal("GITHUB_TOKEN must be set")
|
||||
}
|
||||
|
||||
telemetryHost := viper.GetString("TELEMETRY_HOST")
|
||||
if telemetryHost == "" {
|
||||
log.Fatal("TELEMETRY_HOST must be set")
|
||||
}
|
||||
|
||||
listenAddr := viper.GetString("LISTEN_ADDR")
|
||||
|
||||
r := gin.Default()
|
||||
|
||||
// Initialize the GitHubService.
|
||||
gitHubService := service.NewGitHubService(&service.GithubConfig{
|
||||
Token: githubToken,
|
||||
Owner: "chaitin",
|
||||
Repo: "SafeLine",
|
||||
CacheTTL: viper.GetDuration("GITHUB_CACHE_TTL"),
|
||||
})
|
||||
|
||||
// Create a new instance of GitHubHandler.
|
||||
gitHubHandler := handler.NewGitHubHandler(gitHubService)
|
||||
|
||||
v1 := r.Group("/api")
|
||||
v1.GET("/repos/issues", gitHubHandler.GetIssues)
|
||||
v1.GET("/repos/discussions", gitHubHandler.GetDiscussions)
|
||||
v1.GET("/repos/info", gitHubHandler.GetRepo)
|
||||
|
||||
// Initialize the SafelineService.
|
||||
safelineService := service.NewSafelineService(telemetryHost)
|
||||
safelineHandler := handler.NewSafelineHandler(safelineService)
|
||||
v1.GET("/safeline/count", safelineHandler.GetInstallerCount)
|
||||
v1.POST("/exist", safelineHandler.Exist)
|
||||
|
||||
docs.SwaggerInfo.BasePath = v1.BasePath()
|
||||
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
|
||||
|
||||
// Start the Gin server on the specified port.
|
||||
if err := r.Run(listenAddr); err != nil {
|
||||
log.Fatalf("Error starting server: %v", err)
|
||||
}
|
||||
}
|
|
@ -1 +1 @@
|
|||
Subproject commit afc88a94d03db1cd52156c34c3c9c58053c9f658
|
||||
Subproject commit 23e8b59cd20d475f9590e497ecb87542e25d828e
|
161
blockpage/502.html
Normal file
162
blockpage/504.html
Normal file
331
blockpage/denied.html
Normal file
|
@ -0,0 +1,331 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title>请求存在威胁,已被拦截</title>
|
||||
<link
|
||||
rel="shortcut icon"
|
||||
href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAC8VBMVEUAAAAqKipISEgnJydDQkIDAwMcHBw8PDw8PDwWFhYVFRUqKionJycLCws+Pz8ICAgmJiYICAhHR0cNDQ0QEBApKSksLCwbGxs9PT1HR0cjIyNDQ0MwMDA5OTlHR0cHBwdGRkYyMjIVFRUODg5AQEAYGBgxMTEDAwNJSUkfHx8lJSVBQUELCwsHBwdHR0cwMDAcHBxAQEALCws6OzsDAwMyMjL///89Pj79/v0DAgInt3UnuncoKCgFBAQICQk2NzcWFxYPDw9FRUUlvHhBQUE6PTsLCgtGSEY5OTohISESEhIuLy4slnoyl3grlHM+o21htI0rk3dIqXRCpnEzMzMwoFlgsJNEqWwroFMxMTH2+vg4oWQonUwkJiUeHR02mXxPrHotlnQrlW8ynWqEwqZnuolitoY9nX84oGs9o2o/p2Y6pmEtLCz5/Pvf7+g7nngpkHVLrXA5pGg2o10jm0xLS0selUkLAADu9fKx1sJnt5BMpoZLqXgwmnIzoGE4QT3C3dBSqYpYsINIpn1AoHtBpHc2nHU6o3AnrG4qqGw0PjkQGxYIEA5ksZZdtYFSq4FDoYBZs3xTsHc0lWEqnFo2glkvFSsaHBvn8+7b6+K43Mx5vaFasIhHooVVr344m20smmQaWEZEMT8xST642san0rtxuZhZrI4+oXIbmGEAjlRFTEg3MDgwOTRasZNvvI49sn4iuXQor3EdqGkkfGYipWEsm18npE4tV0Q5SUFDOkBFKj05IDQnAR0KFBF0v5cniG80jF0dmlUAlTiwzrqezrdpt5cns3MvoWksmmkyf1g6dFQvdVMCl1AwbVA9ZE4oZUoxY0EVAAHX5t3S5t3L39Kix66Sx6yWwKVNqIFIsHcpjm8yl24VmlosiUoAjkaBvZuBtZBZo3osk2IwpFohalMvekwvckE/LToZSTg2KDQwIC0UMyceLSUOKiFWsI92rY1IrX4rhVoAkiwiABZxr4Ihw3xfqnMmgGAMmkcAjgBUQVAtAAAANnRSTlMABP4G/v0bGjcoNyEKyEbs4NPMvEMR/fz78uzYzcG7bmxsbEsq/PT05sy4rKuVk5OTfn3v202D2tR1AAAI+UlEQVRYw7SSP2uDQBjGeyqc0OIgFBKk4pChEAiEDkIcAv7B+wqd+xk635p0Le7FjtrFqf5ZMiVoiN8ihHyAzH3vbEmTJk069IeeD+/r85x33sU/Il7jjgx08LX4dzNWjJ6uareApuo9Q8HnhyCElZ7afmQIABdttadghM6xi5eGDm5hD8jQjUsRnZ7dUAXBF+DmRFHzFHhRNU58BbpSdF+wfcm3OVEeBHnEJS8Kvq5coV/8uN+2GXUmRWz6MEoSP+RSymreavcxOurvdG1Jkmw7rJ6zPAzzsB5Z1qgOmc6eqxC60O52jiSIsgpvuIx8Np1UVTAbWAO4ZkFVTaaznPcgQZXFw34N7A2ZlGwcy3EGHAfkJpEyaDQR2qEEJGtuy/zEzdIH8ANgZ1gPaeZ+dVuuJqOf678B/xayqoOgLOcvL/OyDIJ6RaC4TbjZ3weEu2bL80xCKIycVVHE8XA8juO4KFZNzfMoITC2zC5Gu/+/b3oAWaRrSqnHoGlK38eOM35nyuNQuk4XhCmzv3MekHJHAFosR4u3++ETg5DXMrFgD5LyddiUhvdvi9GyoAS4U9D3BXxwRT4hiYRhGGcJ+gvRpQ6hBy8eunRqCBM8SKc5CObgjuNCB2dAHYUcEV0WkU5jB5fJ2cEM2oO6ECjuJmqHlkhb3ENBErWLkBRFQd6KiPa07/fNuMQ+Mwzf9877/Ob53tGj2mKxHalakw8nu7lcbvfoWrSCH/6jVbw+wqWTh6S1GmkXF1G3/tUhBgwWpGIuHAaC1dQSxZ3WAtg1wbK1I4otkxX84XCuiNsNA/8CjOlw5b5bRwTTApLpP6lF5K9373G7buxNH2CwOODau6u73eFIpCFCN9Y3TdrWJDYikbDbXb/bwwZDHzCktzgcDrrkrruBgBDVSiWZrFS+alJ3VWQHP7SVaDBY9EMaYM4I25ICAd6CKEqW5drn7e2Pmx6PZxM9vny4qKVrUKZQA4qglMBinNNGOAufRwGwW/D7fc4VZ/J9IZvN5rOJRDYPix9c0m73+fyCQCEIRKAhxKw6xkEdDVLaYL8RkFuSOuV8ECkTPD/MZPAixnYkacUJDIRoKzRJ07pBDBg3kiCle0Nh+3pKKuej8y6XiwgknpvNqw0i4HIF5qMxVkqtq4ibroI8xnEMMJBTJMmv9e3sfixDEPNwn141XwSq+XIehQ0UMoUy20es8STYDOoIyCme7rX9mr/sCWI/4fr9p8FQMJamcOhSETG2zEmA8PvbPRoAeAiTM/wUT36/FdQEEseysaiKOH16bAgyxciPz2cEKuURAGe4VWiwzUwCYExnNvN4BHEmpIZI7Z8F8CcDeV+TYeJx5rh5FX0NCH1SSN5s1o0BYGTCbDaTvYO4LEOn12Zf2eLY1K8NNXT0/PjCG4cXjzBLIpZCALvTGzrokWCbGAHAMALwfDrExOUahPA67curLMcWtNEFL3/amDjTOIR1ocOltpYRIM3zCDAMgNFpM4hMg9PG1BDCtmRfTrHcfgLOQQQ2LpfsNi/DHD+dErEOt6oBUIB306MY8JfJ8glJJAzDOLEgRHQqCDoaHbp1Wjp4mFMwgczgwBxcnNVRajq0wl5aRwX/ewhJiDLTssP6F9ZzF5FglRUqxLVSMgw7BUm1dOi4z/epu72n+eR7fj7PO++LmkywAIDgMhuA+MQhh+toVV29jm/E0+XyqtkgcF/Xb7tX1wOAQBxADwCNwBLCDv3iI59LuT1f58izj1cTaZutklB5HxFxCtphBoDgdoieRQTSRJY16fZOw5zgAoB/abW6eU4hJ75crsQ3mjZe5Y9ckHHK8bFiMLsELny6pzOxLG3ixALLsrrS7j+A4+Nl71wBwWC4axrJRB1keDW57RIETrECIQCwW9JBtjBBB4kCzsK5oGvbl+Rf0pBc5RWrIvy6Gw1xhedVHxC5MEFYlfAZBdBB+rAoIUPphAKSfCbpwAuPd3NWqzWXr42G+DfJsd32B0EgiJMSEkiLdJ+10oxkYn+kckE/AajfMXL7z918CoRUoXe5RAlGD83hD+YI4r4vsZBp6TZOz8YkWDgNvgNgk3uFWqpWS+UL2Ge6Gt/SqsoPEOE/r6wkxWanKUCzEIOF1/oQUHUMTBt/3hdSHYLotowDxBdbpsr7kCNYfzXBwIIGctKE2HxMkvode8Df9vLVjGPUulahkIKFZ6wWtXCQqIrJtj9g7+gkCSK0gNbcDMMwscZFKASEMys+JTyj1j0XCj0PHmioxJOYdUIeCl00YpDMzEFMM0wx8zj3ZXfIDoRXjBRtTbSOIDyj19C0FSOitx2A3i33GQaSKc0QMKZlqIW6uwNEIOr0imJxtM/DlayIouh1RiHHpToMoLRjI8D4JI4rTOPNLbuHiIgYSe9DjEJ4R1WMZAdyXHlrMCsQTI7//3HVrqCY5ccbWbZY9EAcOrORYpV0k0xAogj5YdQe0rstsnzzuMyQ+1q0cGRBM0U+2dp8kFEWvf7zWvTQCwS6uUTDw/2aXa+3yKiHzS1ye0rz/g/C39rLl7dBIA7DaxaaUCCEQDUCUQOG1CCOBHOCXJtgapuqWRx6Gr5CBapuCk0w+wwT1YgmDfsKe48jpQtJm4m9Cclx93ue+6fO0qM4jvKsPGyRQYHT/P76/Nj1+B54P1ZmOa/VLfCjQPXjCIFhe+BVveLIT3PHV/828BgEj8I48tV7ATbhopMbLmd2WwQUp9P7cZyenS8D7942MN5EhNA8u1YsSdMkSViv4Ph+g1/0seqa5TRCNBn877wuDBpRSussK8+DYrOHAjgTeFNmWU0pyowFbmBisIShqIOubZhwbIALmjVtF9SF4C3BT9aghZSGYViTIC+rlN0lrco8IDUGUaEN808NsosCXgRF0JVtVTVIVbVlFwDnQ/hcecKPd+HrJERIWBQBDwC4kKIIeSSi+/NHTxbVMQmRJIkQOACBHhpDt+mos8ePrrltYEIUc1YELU6j27Dns9nTZ59sayvuQAQvCXql2fLriD9chePBcR/QnjPO/jyqYtmeaax1ZG2Ynm0p6stfoy4VeYHIyhLwv+UH4kmftbvi1LgAAAAASUVORK5CYII="
|
||||
/>
|
||||
<style>
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.container {
|
||||
text-align: center;
|
||||
word-break: keep-all;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: white;
|
||||
font-size: 14px;
|
||||
min-height: 480px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.logo {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.intercepted {
|
||||
margin-top: 3.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 20px;
|
||||
line-height: 1.6;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.intercepted-tips {
|
||||
margin: 8px 0;
|
||||
font-size: 14px;
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
.intercepted-item {
|
||||
margin: 8px 0;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: absolute;
|
||||
bottom: 32px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
.footer-waflink {
|
||||
color: #27b876;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<table class="content">
|
||||
<tr>
|
||||
<td>
|
||||
<div class="logo">
|
||||
<svg
|
||||
width="200px"
|
||||
height="200px"
|
||||
viewBox="0 0 396 407"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient
|
||||
x1="50%"
|
||||
y1="0%"
|
||||
x2="50%"
|
||||
y2="100%"
|
||||
id="linearGradient-1"
|
||||
>
|
||||
<stop stop-color="#4B4B4B" offset="0%"></stop>
|
||||
<stop stop-color="#000000" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<filter
|
||||
x="-3.0%"
|
||||
y="-2.8%"
|
||||
width="106.1%"
|
||||
height="105.6%"
|
||||
filterUnits="objectBoundingBox"
|
||||
id="filter-2"
|
||||
>
|
||||
<feGaussianBlur
|
||||
stdDeviation="3"
|
||||
in="SourceGraphic"
|
||||
></feGaussianBlur>
|
||||
</filter>
|
||||
<linearGradient
|
||||
x1="50%"
|
||||
y1="0%"
|
||||
x2="50%"
|
||||
y2="100%"
|
||||
id="linearGradient-3"
|
||||
>
|
||||
<stop
|
||||
stop-color="#24BC43"
|
||||
stop-opacity="0.8"
|
||||
offset="0%"
|
||||
></stop>
|
||||
<stop
|
||||
stop-color="#3ACBAB"
|
||||
stop-opacity="0.7"
|
||||
offset="100%"
|
||||
></stop>
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M110.049657,49.667649 C110.049657,49.667649 81.1358702,46.2263115 76.8,26.7636364 C72.4880848,46.2263115 43.5503431,49.667649 43.5503431,49.667649 C14.2053649,53.3001718 0,36.4567369 0,36.4567369 C13.941859,65.8036979 38.4,64.7712967 38.4,64.7712967 L115.2,64.7712967 C115.2,64.7712967 139.634186,65.8036979 153.6,36.4567369 C153.6,36.4567369 139.394635,53.3192904 110.049657,49.667649 Z"
|
||||
id="path-4"
|
||||
></path>
|
||||
<filter
|
||||
x="-16.9%"
|
||||
y="-57.9%"
|
||||
width="133.9%"
|
||||
height="236.8%"
|
||||
filterUnits="objectBoundingBox"
|
||||
id="filter-5"
|
||||
>
|
||||
<feOffset
|
||||
dx="0"
|
||||
dy="4"
|
||||
in="SourceAlpha"
|
||||
result="shadowOffsetOuter1"
|
||||
></feOffset>
|
||||
<feGaussianBlur
|
||||
stdDeviation="8"
|
||||
in="shadowOffsetOuter1"
|
||||
result="shadowBlurOuter1"
|
||||
></feGaussianBlur>
|
||||
<feColorMatrix
|
||||
values="0 0 0 0 0 0 0 0 0 0.490319293 0 0 0 0 0.292243323 0 0 0 1 0"
|
||||
type="matrix"
|
||||
in="shadowBlurOuter1"
|
||||
></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g
|
||||
stroke="none"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
>
|
||||
<g transform="translate(49.000000, 38.000000)">
|
||||
<path
|
||||
d="M292.40836,59.04 C290.927217,51.9634286 285.002646,46.6971429 277.761503,46.368 C222.13636,44.8868571 176.385503,16.5805714 157.953503,3.08571429 C152.358074,-1.02857143 144.95236,-1.02857143 139.356931,3.08571429 C120.431217,16.5805714 75.1740742,44.8868571 19.5489314,46.368 C12.4723599,46.6971429 6.21864565,51.9634286 4.90207422,59.04 C-3.98478292,103.474286 -19.2899258,254.057143 148.902074,324 C316.60036,253.892571 300.966074,103.474286 292.40836,59.04 Z"
|
||||
fill="url(#linearGradient-1)"
|
||||
fill-rule="nonzero"
|
||||
></path>
|
||||
<path
|
||||
d="M292.40836,59.04 C290.927217,51.9634286 285.002646,46.6971429 277.761503,46.368 C222.13636,44.8868571 176.385503,16.5805714 157.953503,3.08571429 C152.358074,-1.02857143 144.95236,-1.02857143 139.356931,3.08571429 C120.431217,16.5805714 75.1740742,44.8868571 19.5489314,46.368 C12.4723599,46.6971429 6.21864565,51.9634286 4.90207422,59.04 C-3.98478292,103.474286 -19.2899258,254.057143 148.902074,324 C316.60036,253.892571 300.966074,103.474286 292.40836,59.04 Z"
|
||||
fill="url(#linearGradient-1)"
|
||||
fill-rule="nonzero"
|
||||
filter="url(#filter-2)"
|
||||
></path>
|
||||
<path
|
||||
d="M149,261.4 C205.553958,261.4 251.4,215.553958 251.4,159 C251.4,131.275004 240.381593,106.123494 222.484813,87.6855068 C209.900749,96.0964568 185.81512,106.024178 175.564259,100.853688 C166.334879,96.1984273 157.476591,88.4505652 148.989396,77.610101 C142.047769,88.5334102 134.670586,95.5517221 126.857848,98.6650367 C120.689419,101.123107 98.2592604,102.915695 75.4419467,87.761039 C57.5883513,106.192154 46.6,131.312844 46.6,159 C46.6,215.553958 92.4460416,261.4 149,261.4 Z"
|
||||
fill="url(#linearGradient-3)"
|
||||
></path>
|
||||
<g
|
||||
transform="translate(91.771423, 102.101722)"
|
||||
fill="#FFFFFF"
|
||||
>
|
||||
<polygon
|
||||
transform="translate(57.217971, 95.920999) rotate(-180.000000) translate(-57.217971, -95.920999) "
|
||||
points="56.6651511 64.9496372 -7.57241738e-17 97.1108413 50.6084036 126.892361 68.8016729 117.264704 34.3433228 97.1108413 56.6651511 84.5503086 96.9001091 107.376711 96.9001091 114.88399 114.435942 125.435553 114.435942 97.1108413"
|
||||
></polygon>
|
||||
<polygon
|
||||
transform="translate(57.217971, 30.971362) rotate(-360.000000) translate(-57.217971, -30.971362) "
|
||||
points="56.6651511 2.84217094e-14 -7.57241738e-17 32.1612041 50.6084036 61.9427239 68.8016729 52.3150668 34.3433228 32.1612041 56.6651511 19.6006714 96.9001091 42.4270741 96.9001091 49.9343528 114.435942 60.4859155 114.435942 32.1612041"
|
||||
></polygon>
|
||||
<polygon
|
||||
opacity="0.40499442"
|
||||
transform="translate(57.217971, 95.920999) rotate(-180.000000) translate(-57.217971, -95.920999) "
|
||||
points="56.6651511 64.9496372 -7.57241738e-17 97.1108413 50.6084036 126.892361 68.8016729 117.264704 34.3433228 97.1108413 56.6651511 84.5503086 96.9001091 107.376711 96.9001091 114.88399 114.435942 125.435553 114.435942 97.1108413"
|
||||
></polygon>
|
||||
<polygon
|
||||
opacity="0.40499442"
|
||||
transform="translate(57.217971, 30.971362) rotate(-360.000000) translate(-57.217971, -30.971362) "
|
||||
points="56.6651511 4.8316906e-13 -7.57241738e-17 32.1612041 50.6084036 61.9427239 68.8016729 52.3150668 34.3433228 32.1612041 56.6651511 19.6006714 96.9001091 42.4270741 96.9001091 49.9343528 114.435942 60.4859155 114.435942 32.1612041"
|
||||
></polygon>
|
||||
</g>
|
||||
<g
|
||||
transform="translate(72.200000, 45.222222)"
|
||||
fill-rule="nonzero"
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d="M96.7632666,18.0061837 C96.7632666,18.0061837 79.3862969,15.2966085 76.7907961,0 C74.1952953,15.2966085 56.8183256,18.0061837 56.8183256,18.0061837 C39.1836466,20.8694936 30.6424242,7.60987058 30.6424242,7.60987058 C39.0363842,30.6893013 53.7258141,29.862977 53.7258141,29.862977 L99.8741859,29.862977 C99.8741859,29.862977 114.563616,30.6700845 122.957576,7.60987058 C122.957576,7.60987058 114.416353,20.8694936 96.7816744,18.0061837 L96.7632666,18.0061837 Z"
|
||||
fill="#27B876"
|
||||
></path>
|
||||
<g>
|
||||
<use
|
||||
fill="black"
|
||||
fill-opacity="1"
|
||||
filter="url(#filter-5)"
|
||||
xlink:href="#path-4"
|
||||
></use>
|
||||
<use fill="#27B876" xlink:href="#path-4"></use>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="intercepted" id="block-title">
|
||||
请求存在威胁,已被拦截
|
||||
</div>
|
||||
<div class="intercepted-tips" id="intercepted-tips"></div>
|
||||
<div class="intercepted-item" id="EventID"></div>
|
||||
<div class="intercepted-item" id="TYPE"></div>
|
||||
<div class="intercepted-item">
|
||||
<span id="time">拦截时间</span>: <span id="now"></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="footer">
|
||||
<span id="powered-by">安全检测能力由</span>
|
||||
<a class="footer-waflink" href="https://waf-ce.chaitin.cn">
|
||||
<span id="waf-title">长亭雷池 WAF</span>
|
||||
</a>
|
||||
<span id="powered-by-tail">驱动</span>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// 显示当前时间
|
||||
function timestring() {
|
||||
var d = new Date();
|
||||
function p(d) {
|
||||
return d < 10 ? "0" + d : d;
|
||||
}
|
||||
return (
|
||||
d.getFullYear() +
|
||||
"-" +
|
||||
p(d.getMonth() + 1) +
|
||||
"-" +
|
||||
p(d.getDate()) +
|
||||
" " +
|
||||
p(d.getHours()) +
|
||||
":" +
|
||||
p(d.getMinutes())
|
||||
);
|
||||
}
|
||||
document.getElementById("now").innerText = timestring();
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// 这段代码是从源文件上直接抄下来的,原封不动的复制下来的
|
||||
window.onload = function () {
|
||||
var nodes = document.getElementsByTagName("body")[0].childNodes;
|
||||
var fit2inserts = null;
|
||||
for (var i = 0; i < nodes.length; i++) {
|
||||
if (
|
||||
nodes[i].nodeType == 8 &&
|
||||
nodes[i].data.trimLeft().startsWith("event_id")
|
||||
) {
|
||||
fit2inserts = nodes[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 以后引擎按此约定插入新参数:
|
||||
* event_id: ****** type: A anymore: ****
|
||||
*/
|
||||
|
||||
try {
|
||||
var inserts =
|
||||
document.getElementsByTagName("html")[0].nextSibling || fit2inserts;
|
||||
var insertsData = inserts && (inserts.data || "");
|
||||
var incertDataList = insertsData.split(" ");
|
||||
var getVal = function (key) {
|
||||
return incertDataList[incertDataList.indexOf(key + ":") + 1];
|
||||
};
|
||||
var event_id = getVal("event_id");
|
||||
var type = getVal("TYPE");
|
||||
// var anymore = getVal('anymore') // 新增参数示例
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
if (event_id) {
|
||||
document.getElementById("EventID").innerText = "ID: " + event_id;
|
||||
}
|
||||
if (type) {
|
||||
document.getElementById("TYPE").innerText = "TYPE: " + type;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<script>
|
||||
function R(id, text) {
|
||||
var el = document.getElementById(id);
|
||||
if (el) el.innerText = text;
|
||||
}
|
||||
if (!navigator.language.startsWith("zh")) {
|
||||
document.title = "Request has been denied";
|
||||
|
||||
R("block-title", "Threat has been detected, request denied");
|
||||
R("time", "Denied at");
|
||||
R("waf-title", "Safeline WAF");
|
||||
R("powered-by", "Powered by");
|
||||
R("powered-by-tail", "");
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
282
blockpage/limited.html
Normal file
|
@ -0,0 +1,282 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title>访问频率过高,本次请求已被拦截</title>
|
||||
<link
|
||||
rel="shortcut icon"
|
||||
href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAC8VBMVEUAAAAqKipISEgnJydDQkIDAwMcHBw8PDw8PDwWFhYVFRUqKionJycLCws+Pz8ICAgmJiYICAhHR0cNDQ0QEBApKSksLCwbGxs9PT1HR0cjIyNDQ0MwMDA5OTlHR0cHBwdGRkYyMjIVFRUODg5AQEAYGBgxMTEDAwNJSUkfHx8lJSVBQUELCwsHBwdHR0cwMDAcHBxAQEALCws6OzsDAwMyMjL///89Pj79/v0DAgInt3UnuncoKCgFBAQICQk2NzcWFxYPDw9FRUUlvHhBQUE6PTsLCgtGSEY5OTohISESEhIuLy4slnoyl3grlHM+o21htI0rk3dIqXRCpnEzMzMwoFlgsJNEqWwroFMxMTH2+vg4oWQonUwkJiUeHR02mXxPrHotlnQrlW8ynWqEwqZnuolitoY9nX84oGs9o2o/p2Y6pmEtLCz5/Pvf7+g7nngpkHVLrXA5pGg2o10jm0xLS0selUkLAADu9fKx1sJnt5BMpoZLqXgwmnIzoGE4QT3C3dBSqYpYsINIpn1AoHtBpHc2nHU6o3AnrG4qqGw0PjkQGxYIEA5ksZZdtYFSq4FDoYBZs3xTsHc0lWEqnFo2glkvFSsaHBvn8+7b6+K43Mx5vaFasIhHooVVr344m20smmQaWEZEMT8xST642san0rtxuZhZrI4+oXIbmGEAjlRFTEg3MDgwOTRasZNvvI49sn4iuXQor3EdqGkkfGYipWEsm18npE4tV0Q5SUFDOkBFKj05IDQnAR0KFBF0v5cniG80jF0dmlUAlTiwzrqezrdpt5cns3MvoWksmmkyf1g6dFQvdVMCl1AwbVA9ZE4oZUoxY0EVAAHX5t3S5t3L39Kix66Sx6yWwKVNqIFIsHcpjm8yl24VmlosiUoAjkaBvZuBtZBZo3osk2IwpFohalMvekwvckE/LToZSTg2KDQwIC0UMyceLSUOKiFWsI92rY1IrX4rhVoAkiwiABZxr4Ihw3xfqnMmgGAMmkcAjgBUQVAtAAAANnRSTlMABP4G/v0bGjcoNyEKyEbs4NPMvEMR/fz78uzYzcG7bmxsbEsq/PT05sy4rKuVk5OTfn3v202D2tR1AAAI+UlEQVRYw7SSP2uDQBjGeyqc0OIgFBKk4pChEAiEDkIcAv7B+wqd+xk635p0Le7FjtrFqf5ZMiVoiN8ihHyAzH3vbEmTJk069IeeD+/r85x33sU/Il7jjgx08LX4dzNWjJ6uareApuo9Q8HnhyCElZ7afmQIABdttadghM6xi5eGDm5hD8jQjUsRnZ7dUAXBF+DmRFHzFHhRNU58BbpSdF+wfcm3OVEeBHnEJS8Kvq5coV/8uN+2GXUmRWz6MEoSP+RSymreavcxOurvdG1Jkmw7rJ6zPAzzsB5Z1qgOmc6eqxC60O52jiSIsgpvuIx8Np1UVTAbWAO4ZkFVTaaznPcgQZXFw34N7A2ZlGwcy3EGHAfkJpEyaDQR2qEEJGtuy/zEzdIH8ANgZ1gPaeZ+dVuuJqOf678B/xayqoOgLOcvL/OyDIJ6RaC4TbjZ3weEu2bL80xCKIycVVHE8XA8juO4KFZNzfMoITC2zC5Gu/+/b3oAWaRrSqnHoGlK38eOM35nyuNQuk4XhCmzv3MekHJHAFosR4u3++ETg5DXMrFgD5LyddiUhvdvi9GyoAS4U9D3BXxwRT4hiYRhGGcJ+gvRpQ6hBy8eunRqCBM8SKc5CObgjuNCB2dAHYUcEV0WkU5jB5fJ2cEM2oO6ECjuJmqHlkhb3ENBErWLkBRFQd6KiPa07/fNuMQ+Mwzf9877/Ob53tGj2mKxHalakw8nu7lcbvfoWrSCH/6jVbw+wqWTh6S1GmkXF1G3/tUhBgwWpGIuHAaC1dQSxZ3WAtg1wbK1I4otkxX84XCuiNsNA/8CjOlw5b5bRwTTApLpP6lF5K9373G7buxNH2CwOODau6u73eFIpCFCN9Y3TdrWJDYikbDbXb/bwwZDHzCktzgcDrrkrruBgBDVSiWZrFS+alJ3VWQHP7SVaDBY9EMaYM4I25ICAd6CKEqW5drn7e2Pmx6PZxM9vny4qKVrUKZQA4qglMBinNNGOAufRwGwW/D7fc4VZ/J9IZvN5rOJRDYPix9c0m73+fyCQCEIRKAhxKw6xkEdDVLaYL8RkFuSOuV8ECkTPD/MZPAixnYkacUJDIRoKzRJ07pBDBg3kiCle0Nh+3pKKuej8y6XiwgknpvNqw0i4HIF5qMxVkqtq4ibroI8xnEMMJBTJMmv9e3sfixDEPNwn141XwSq+XIehQ0UMoUy20es8STYDOoIyCme7rX9mr/sCWI/4fr9p8FQMJamcOhSETG2zEmA8PvbPRoAeAiTM/wUT36/FdQEEseysaiKOH16bAgyxciPz2cEKuURAGe4VWiwzUwCYExnNvN4BHEmpIZI7Z8F8CcDeV+TYeJx5rh5FX0NCH1SSN5s1o0BYGTCbDaTvYO4LEOn12Zf2eLY1K8NNXT0/PjCG4cXjzBLIpZCALvTGzrokWCbGAHAMALwfDrExOUahPA67curLMcWtNEFL3/amDjTOIR1ocOltpYRIM3zCDAMgNFpM4hMg9PG1BDCtmRfTrHcfgLOQQQ2LpfsNi/DHD+dErEOt6oBUIB306MY8JfJ8glJJAzDOLEgRHQqCDoaHbp1Wjp4mFMwgczgwBxcnNVRajq0wl5aRwX/ewhJiDLTssP6F9ZzF5FglRUqxLVSMgw7BUm1dOi4z/epu72n+eR7fj7PO++LmkywAIDgMhuA+MQhh+toVV29jm/E0+XyqtkgcF/Xb7tX1wOAQBxADwCNwBLCDv3iI59LuT1f58izj1cTaZutklB5HxFxCtphBoDgdoieRQTSRJY16fZOw5zgAoB/abW6eU4hJ75crsQ3mjZe5Y9ckHHK8bFiMLsELny6pzOxLG3ixALLsrrS7j+A4+Nl71wBwWC4axrJRB1keDW57RIETrECIQCwW9JBtjBBB4kCzsK5oGvbl+Rf0pBc5RWrIvy6Gw1xhedVHxC5MEFYlfAZBdBB+rAoIUPphAKSfCbpwAuPd3NWqzWXr42G+DfJsd32B0EgiJMSEkiLdJ+10oxkYn+kckE/AajfMXL7z918CoRUoXe5RAlGD83hD+YI4r4vsZBp6TZOz8YkWDgNvgNgk3uFWqpWS+UL2Ge6Gt/SqsoPEOE/r6wkxWanKUCzEIOF1/oQUHUMTBt/3hdSHYLotowDxBdbpsr7kCNYfzXBwIIGctKE2HxMkvode8Df9vLVjGPUulahkIKFZ6wWtXCQqIrJtj9g7+gkCSK0gNbcDMMwscZFKASEMys+JTyj1j0XCj0PHmioxJOYdUIeCl00YpDMzEFMM0wx8zj3ZXfIDoRXjBRtTbSOIDyj19C0FSOitx2A3i33GQaSKc0QMKZlqIW6uwNEIOr0imJxtM/DlayIouh1RiHHpToMoLRjI8D4JI4rTOPNLbuHiIgYSe9DjEJ4R1WMZAdyXHlrMCsQTI7//3HVrqCY5ccbWbZY9EAcOrORYpV0k0xAogj5YdQe0rstsnzzuMyQ+1q0cGRBM0U+2dp8kFEWvf7zWvTQCwS6uUTDw/2aXa+3yKiHzS1ye0rz/g/C39rLl7dBIA7DaxaaUCCEQDUCUQOG1CCOBHOCXJtgapuqWRx6Gr5CBapuCk0w+wwT1YgmDfsKe48jpQtJm4m9Cclx93ue+6fO0qM4jvKsPGyRQYHT/P76/Nj1+B54P1ZmOa/VLfCjQPXjCIFhe+BVveLIT3PHV/828BgEj8I48tV7ATbhopMbLmd2WwQUp9P7cZyenS8D7942MN5EhNA8u1YsSdMkSViv4Ph+g1/0seqa5TRCNBn877wuDBpRSussK8+DYrOHAjgTeFNmWU0pyowFbmBisIShqIOubZhwbIALmjVtF9SF4C3BT9aghZSGYViTIC+rlN0lrco8IDUGUaEN808NsosCXgRF0JVtVTVIVbVlFwDnQ/hcecKPd+HrJERIWBQBDwC4kKIIeSSi+/NHTxbVMQmRJIkQOACBHhpDt+mos8ePrrltYEIUc1YELU6j27Dns9nTZ59sayvuQAQvCXql2fLriD9chePBcR/QnjPO/jyqYtmeaax1ZG2Ynm0p6stfoy4VeYHIyhLwv+UH4kmftbvi1LgAAAAASUVORK5CYII="
|
||||
/>
|
||||
<style>
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.container {
|
||||
text-align: center;
|
||||
word-break: keep-all;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: white;
|
||||
font-size: 14px;
|
||||
min-height: 450px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.logo {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.intercepted {
|
||||
margin-top: 3.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 20px;
|
||||
line-height: 1.6;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.intercepted-tips {
|
||||
margin: 8px 0;
|
||||
font-size: 14px;
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
.intercepted-item {
|
||||
margin: 8px 0;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: absolute;
|
||||
bottom: 32px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
.footer-waflink {
|
||||
color: #27b876;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<table class="content">
|
||||
<tr>
|
||||
<td>
|
||||
<div class="logo">
|
||||
<svg
|
||||
width="200px"
|
||||
height="200px"
|
||||
viewBox="0 0 396 407"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient
|
||||
x1="50%"
|
||||
y1="0%"
|
||||
x2="50%"
|
||||
y2="100%"
|
||||
id="linearGradient-1"
|
||||
>
|
||||
<stop stop-color="#4B4B4B" offset="0%"></stop>
|
||||
<stop stop-color="#000000" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<filter
|
||||
x="-3.0%"
|
||||
y="-2.8%"
|
||||
width="106.1%"
|
||||
height="105.6%"
|
||||
filterUnits="objectBoundingBox"
|
||||
id="filter-2"
|
||||
>
|
||||
<feGaussianBlur
|
||||
stdDeviation="3"
|
||||
in="SourceGraphic"
|
||||
></feGaussianBlur>
|
||||
</filter>
|
||||
<linearGradient
|
||||
x1="50%"
|
||||
y1="0%"
|
||||
x2="50%"
|
||||
y2="100%"
|
||||
id="linearGradient-3"
|
||||
>
|
||||
<stop
|
||||
stop-color="#24BC43"
|
||||
stop-opacity="0.8"
|
||||
offset="0%"
|
||||
></stop>
|
||||
<stop
|
||||
stop-color="#3ACBAB"
|
||||
stop-opacity="0.7"
|
||||
offset="100%"
|
||||
></stop>
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M110.049657,49.667649 C110.049657,49.667649 81.1358702,46.2263115 76.8,26.7636364 C72.4880848,46.2263115 43.5503431,49.667649 43.5503431,49.667649 C14.2053649,53.3001718 0,36.4567369 0,36.4567369 C13.941859,65.8036979 38.4,64.7712967 38.4,64.7712967 L115.2,64.7712967 C115.2,64.7712967 139.634186,65.8036979 153.6,36.4567369 C153.6,36.4567369 139.394635,53.3192904 110.049657,49.667649 Z"
|
||||
id="path-4"
|
||||
></path>
|
||||
<filter
|
||||
x="-16.9%"
|
||||
y="-57.9%"
|
||||
width="133.9%"
|
||||
height="236.8%"
|
||||
filterUnits="objectBoundingBox"
|
||||
id="filter-5"
|
||||
>
|
||||
<feOffset
|
||||
dx="0"
|
||||
dy="4"
|
||||
in="SourceAlpha"
|
||||
result="shadowOffsetOuter1"
|
||||
></feOffset>
|
||||
<feGaussianBlur
|
||||
stdDeviation="8"
|
||||
in="shadowOffsetOuter1"
|
||||
result="shadowBlurOuter1"
|
||||
></feGaussianBlur>
|
||||
<feColorMatrix
|
||||
values="0 0 0 0 0 0 0 0 0 0.490319293 0 0 0 0 0.292243323 0 0 0 1 0"
|
||||
type="matrix"
|
||||
in="shadowBlurOuter1"
|
||||
></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g
|
||||
stroke="none"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
>
|
||||
<g transform="translate(49.000000, 38.000000)">
|
||||
<path
|
||||
d="M292.40836,59.04 C290.927217,51.9634286 285.002646,46.6971429 277.761503,46.368 C222.13636,44.8868571 176.385503,16.5805714 157.953503,3.08571429 C152.358074,-1.02857143 144.95236,-1.02857143 139.356931,3.08571429 C120.431217,16.5805714 75.1740742,44.8868571 19.5489314,46.368 C12.4723599,46.6971429 6.21864565,51.9634286 4.90207422,59.04 C-3.98478292,103.474286 -19.2899258,254.057143 148.902074,324 C316.60036,253.892571 300.966074,103.474286 292.40836,59.04 Z"
|
||||
fill="url(#linearGradient-1)"
|
||||
fill-rule="nonzero"
|
||||
></path>
|
||||
<path
|
||||
d="M292.40836,59.04 C290.927217,51.9634286 285.002646,46.6971429 277.761503,46.368 C222.13636,44.8868571 176.385503,16.5805714 157.953503,3.08571429 C152.358074,-1.02857143 144.95236,-1.02857143 139.356931,3.08571429 C120.431217,16.5805714 75.1740742,44.8868571 19.5489314,46.368 C12.4723599,46.6971429 6.21864565,51.9634286 4.90207422,59.04 C-3.98478292,103.474286 -19.2899258,254.057143 148.902074,324 C316.60036,253.892571 300.966074,103.474286 292.40836,59.04 Z"
|
||||
fill="url(#linearGradient-1)"
|
||||
fill-rule="nonzero"
|
||||
filter="url(#filter-2)"
|
||||
></path>
|
||||
<path
|
||||
d="M149,261.4 C205.553958,261.4 251.4,215.553958 251.4,159 C251.4,131.275004 240.381593,106.123494 222.484813,87.6855068 C209.900749,96.0964568 185.81512,106.024178 175.564259,100.853688 C166.334879,96.1984273 157.476591,88.4505652 148.989396,77.610101 C142.047769,88.5334102 134.670586,95.5517221 126.857848,98.6650367 C120.689419,101.123107 98.2592604,102.915695 75.4419467,87.761039 C57.5883513,106.192154 46.6,131.312844 46.6,159 C46.6,215.553958 92.4460416,261.4 149,261.4 Z"
|
||||
fill="url(#linearGradient-3)"
|
||||
></path>
|
||||
<g
|
||||
transform="translate(91.771423, 102.101722)"
|
||||
fill="#FFFFFF"
|
||||
>
|
||||
<polygon
|
||||
transform="translate(57.217971, 95.920999) rotate(-180.000000) translate(-57.217971, -95.920999) "
|
||||
points="56.6651511 64.9496372 -7.57241738e-17 97.1108413 50.6084036 126.892361 68.8016729 117.264704 34.3433228 97.1108413 56.6651511 84.5503086 96.9001091 107.376711 96.9001091 114.88399 114.435942 125.435553 114.435942 97.1108413"
|
||||
></polygon>
|
||||
<polygon
|
||||
transform="translate(57.217971, 30.971362) rotate(-360.000000) translate(-57.217971, -30.971362) "
|
||||
points="56.6651511 2.84217094e-14 -7.57241738e-17 32.1612041 50.6084036 61.9427239 68.8016729 52.3150668 34.3433228 32.1612041 56.6651511 19.6006714 96.9001091 42.4270741 96.9001091 49.9343528 114.435942 60.4859155 114.435942 32.1612041"
|
||||
></polygon>
|
||||
<polygon
|
||||
opacity="0.40499442"
|
||||
transform="translate(57.217971, 95.920999) rotate(-180.000000) translate(-57.217971, -95.920999) "
|
||||
points="56.6651511 64.9496372 -7.57241738e-17 97.1108413 50.6084036 126.892361 68.8016729 117.264704 34.3433228 97.1108413 56.6651511 84.5503086 96.9001091 107.376711 96.9001091 114.88399 114.435942 125.435553 114.435942 97.1108413"
|
||||
></polygon>
|
||||
<polygon
|
||||
opacity="0.40499442"
|
||||
transform="translate(57.217971, 30.971362) rotate(-360.000000) translate(-57.217971, -30.971362) "
|
||||
points="56.6651511 4.8316906e-13 -7.57241738e-17 32.1612041 50.6084036 61.9427239 68.8016729 52.3150668 34.3433228 32.1612041 56.6651511 19.6006714 96.9001091 42.4270741 96.9001091 49.9343528 114.435942 60.4859155 114.435942 32.1612041"
|
||||
></polygon>
|
||||
</g>
|
||||
<g
|
||||
transform="translate(72.200000, 45.222222)"
|
||||
fill-rule="nonzero"
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d="M96.7632666,18.0061837 C96.7632666,18.0061837 79.3862969,15.2966085 76.7907961,0 C74.1952953,15.2966085 56.8183256,18.0061837 56.8183256,18.0061837 C39.1836466,20.8694936 30.6424242,7.60987058 30.6424242,7.60987058 C39.0363842,30.6893013 53.7258141,29.862977 53.7258141,29.862977 L99.8741859,29.862977 C99.8741859,29.862977 114.563616,30.6700845 122.957576,7.60987058 C122.957576,7.60987058 114.416353,20.8694936 96.7816744,18.0061837 L96.7632666,18.0061837 Z"
|
||||
fill="#27B876"
|
||||
></path>
|
||||
<g>
|
||||
<use
|
||||
fill="black"
|
||||
fill-opacity="1"
|
||||
filter="url(#filter-5)"
|
||||
xlink:href="#path-4"
|
||||
></use>
|
||||
<use fill="#27B876" xlink:href="#path-4"></use>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<div id="intercepted" class="intercepted">
|
||||
请求频率过高,存在威胁,已被拦截
|
||||
</div>
|
||||
<div class="intercepted-tips" id="intercepted-tips"></div>
|
||||
<div class="intercepted-item">
|
||||
<span id="intercepted-at">拦截时间</span>: <span id="now"></span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div id="footer" class="footer">
|
||||
安全检测能力由
|
||||
<a class="footer-waflink" href="https://waf-ce.chaitin.cn"
|
||||
>长亭雷池 WAF</a
|
||||
>
|
||||
驱动
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// 显示当前时间
|
||||
function timestring() {
|
||||
var d = new Date();
|
||||
function p(d) {
|
||||
return d < 10 ? "0" + d : d;
|
||||
}
|
||||
return (
|
||||
d.getFullYear() +
|
||||
"-" +
|
||||
p(d.getMonth() + 1) +
|
||||
"-" +
|
||||
p(d.getDate()) +
|
||||
" " +
|
||||
p(d.getHours()) +
|
||||
":" +
|
||||
p(d.getMinutes())
|
||||
);
|
||||
}
|
||||
document.getElementById("now").innerText = timestring();
|
||||
</script>
|
||||
|
||||
<script>
|
||||
if (navigator.language.startsWith("en")) {
|
||||
document.title = "Requested too frequently";
|
||||
|
||||
document.getElementById("intercepted").innerText =
|
||||
"Requested too frequently, please try again later";
|
||||
document.getElementById("intercepted-at").innerText = "Intercepted at";
|
||||
document.getElementById("footer").style.display = "none";
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
212
blockpage/maintaining.html
Normal file
|
@ -0,0 +1,212 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title>网站维护中</title>
|
||||
<style>
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.container {
|
||||
text-align: center;
|
||||
word-break: keep-all;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: white;
|
||||
font-size: 14px;
|
||||
min-height: 450px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.logo {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.intercepted {
|
||||
margin-top: 3.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 20px;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.intercepted-item {
|
||||
margin: 8px 0;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: absolute;
|
||||
bottom: 32px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
.footer-waflink {
|
||||
color: #27b876;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<table class="content">
|
||||
<tr>
|
||||
<td>
|
||||
<div class="logo">
|
||||
<svg
|
||||
width="300px"
|
||||
height="112px"
|
||||
viewBox="0 0 300 112"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<title>编组 65</title>
|
||||
<defs>
|
||||
<linearGradient
|
||||
x1="50%"
|
||||
y1="0%"
|
||||
x2="50%"
|
||||
y2="100%"
|
||||
id="linearGradient-1"
|
||||
>
|
||||
<stop
|
||||
stop-color="#0FC6C2"
|
||||
stop-opacity="0.1"
|
||||
offset="0%"
|
||||
></stop>
|
||||
<stop
|
||||
stop-color="#0FC6C2"
|
||||
stop-opacity="0"
|
||||
offset="100%"
|
||||
></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
x1="50%"
|
||||
y1="0%"
|
||||
x2="50%"
|
||||
y2="100%"
|
||||
id="linearGradient-2"
|
||||
>
|
||||
<stop stop-color="#A9D6D3" offset="0%"></stop>
|
||||
<stop stop-color="#8EC6C4" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
x1="17.048305%"
|
||||
y1="8.1635079%"
|
||||
x2="76.1348779%"
|
||||
y2="89.9397366%"
|
||||
id="linearGradient-3"
|
||||
>
|
||||
<stop stop-color="#ECF7F7" offset="0%"></stop>
|
||||
<stop stop-color="#CEEFEE" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g
|
||||
id="问脉"
|
||||
stroke="none"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
>
|
||||
<g id="编组-65" transform="translate(0.000000, 0.656106)">
|
||||
<path
|
||||
d="M158.105468,46.4305012 C230.638275,48.8882768 280.048484,89.2493521 291.411562,97.5896283 C298.986948,103.149812 301.288867,107.707461 298.317319,111.262574 L0,111.262574 C57.0484407,66.4026752 109.750263,44.7919842 158.105468,46.4305012 Z"
|
||||
id="路径-14备份"
|
||||
fill="url(#linearGradient-1)"
|
||||
opacity="0.6"
|
||||
></path>
|
||||
<path
|
||||
d="M133.744707,59.2516792 C128.220216,62.212914 142.271748,72.3438938 152.603912,72.3438938 C162.936076,72.3438938 170.384509,66.1002168 166.415224,63.7091176 C162.445939,61.3180184 139.269199,56.2904444 133.744707,59.2516792 Z"
|
||||
id="路径-23备份"
|
||||
fill="#CEEEED"
|
||||
></path>
|
||||
<g
|
||||
id="维护备份"
|
||||
transform="translate(125.841376, 4.000000)"
|
||||
fill="url(#linearGradient-2)"
|
||||
fill-rule="nonzero"
|
||||
>
|
||||
<path
|
||||
d="M53.4407915,17.8309532 C49.850381,20.6412105 45.048111,20.2807339 42.738148,17.0275722 C40.428185,13.7744105 41.4704292,8.83897736 45.0608397,6.02872002 L48.4302392,3.3908402 C50.2893442,1.93421992 49.6588911,0.00928311389 46.813125,0.241953931 C43.8131226,0.486558233 40.8354442,1.6843377 38.3140089,3.66074708 C34.2763868,6.82838427 31.8308675,11.6191742 31.8089552,16.4041942 L3.55036904,38.5271177 C-0.0421309333,41.3487126 -1.07876034,46.2575577 1.22851314,49.522012 C2.33804924,51.0840803 4.09016048,52.0468265 6.09769574,52.1975197 C8.105231,52.3482129 10.2029338,51.6744483 11.9272901,50.3251027 L40.1897428,28.2024695 C43.7454976,29.2914901 47.8019094,28.7846954 51.4034487,26.8014661 C55.004988,24.8182368 57.8332485,21.5339069 59.2220045,17.7221341 C60.2487908,14.9244912 58.6731626,13.7367433 56.810191,15.1930733 L53.4407915,17.8309532 Z M5.56827104,46.1206895 C4.79626286,45.0334702 5.14228458,43.3949223 6.34222301,42.4557247 C7.541301,41.5714856 9.09674694,41.7145817 9.85296424,42.7787018 C10.6091815,43.842822 10.2920189,45.4421908 9.13710773,46.3885799 C7.9371693,47.3277774 6.34027921,47.2079088 5.56827104,46.1206895 Z M13.7446583,12.4428814 L20.5888502,22.087378 L24.9316389,18.6903037 L18.087447,9.04580702 L16.9394989,5.05163029 L11.6667257,0 L7.32393706,3.39707438 L10.4272492,10.147387 L13.7446583,12.4428814 Z M38.1657743,33.2576704 C37.8311845,33.2325548 37.4815663,33.3450613 37.1943929,33.5702592 L30.6813074,38.6699737 C30.0831963,39.1405877 29.9105495,39.9581375 30.2943314,40.5024561 L40.1788997,54.4239027 C41.7237519,56.5943835 44.9213986,56.8344109 47.3165731,54.9596835 C49.7156141,53.0852463 50.4093292,49.8002347 48.8653128,47.6257961 L38.976878,33.7040592 C38.7922954,33.4434496 38.5003642,33.282786 38.1657743,33.2576704 Z"
|
||||
id="形状"
|
||||
></path>
|
||||
</g>
|
||||
<g
|
||||
id="维护备份-2"
|
||||
transform="translate(123.841376, 0.000000)"
|
||||
fill="url(#linearGradient-3)"
|
||||
fill-rule="nonzero"
|
||||
>
|
||||
<path
|
||||
d="M53.4407915,17.8309532 C49.850381,20.6412105 45.048111,20.2807339 42.738148,17.0275722 C40.428185,13.7744105 41.4704292,8.83897736 45.0608397,6.02872002 L48.4302392,3.3908402 C50.2893442,1.93421992 49.6588911,0.00928311389 46.813125,0.241953931 C43.8131226,0.486558233 40.8354442,1.6843377 38.3140089,3.66074708 C34.2763868,6.82838427 31.8308675,11.6191742 31.8089552,16.4041942 L3.55036904,38.5271177 C-0.0421309333,41.3487126 -1.07876034,46.2575577 1.22851314,49.522012 C2.33804924,51.0840803 4.09016048,52.0468265 6.09769574,52.1975197 C8.105231,52.3482129 10.2029338,51.6744483 11.9272901,50.3251027 L40.1897428,28.2024695 C43.7454976,29.2914901 47.8019094,28.7846954 51.4034487,26.8014661 C55.004988,24.8182368 57.8332485,21.5339069 59.2220045,17.7221341 C60.2487908,14.9244912 58.6731626,13.7367433 56.810191,15.1930733 L53.4407915,17.8309532 Z M5.56827104,46.1206895 C4.79626286,45.0334702 5.14228458,43.3949223 6.34222301,42.4557247 C7.541301,41.5714856 9.09674694,41.7145817 9.85296424,42.7787018 C10.6091815,43.842822 10.2920189,45.4421908 9.13710773,46.3885799 C7.9371693,47.3277774 6.34027921,47.2079088 5.56827104,46.1206895 Z M13.7446583,12.4428814 L20.5888502,22.087378 L24.9316389,18.6903037 L18.087447,9.04580702 L16.9394989,5.05163029 L11.6667257,0 L7.32393706,3.39707438 L10.4272492,10.147387 L13.7446583,12.4428814 Z M38.1657743,33.2576704 C37.8311845,33.2325548 37.4815663,33.3450613 37.1943929,33.5702592 L30.6813074,38.6699737 C30.0831963,39.1405877 29.9105495,39.9581375 30.2943314,40.5024561 L40.1788997,54.4239027 C41.7237519,56.5943835 44.9213986,56.8344109 47.3165731,54.9596835 C49.7156141,53.0852463 50.4093292,49.8002347 48.8653128,47.6257961 L38.976878,33.7040592 C38.7922954,33.4434496 38.5003642,33.282786 38.1657743,33.2576704 Z"
|
||||
id="形状"
|
||||
></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="intercepted" id="intercepted">
|
||||
网站维护中,暂时无法访问
|
||||
</div>
|
||||
<div class="intercepted-item"><span id="now"></span></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="footer" id="footer">
|
||||
安全检测能力由
|
||||
<a class="footer-waflink" href="https://waf-ce.chaitin.cn"
|
||||
>长亭雷池 WAF</a
|
||||
>
|
||||
驱动
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// 显示当前时间
|
||||
function timestring() {
|
||||
var d = new Date();
|
||||
function p(d) {
|
||||
return d < 10 ? "0" + d : d;
|
||||
}
|
||||
return (
|
||||
d.getFullYear() +
|
||||
"-" +
|
||||
p(d.getMonth() + 1) +
|
||||
"-" +
|
||||
p(d.getDate()) +
|
||||
" " +
|
||||
p(d.getHours()) +
|
||||
":" +
|
||||
p(d.getMinutes())
|
||||
);
|
||||
}
|
||||
document.getElementById("now").innerText = timestring();
|
||||
</script>
|
||||
<script>
|
||||
if (navigator.language.startsWith("en")) {
|
||||
document.title = "Site is Maintaining";
|
||||
|
||||
document.getElementById("intercepted").innerText =
|
||||
"The site is on maintaining, please try again later";
|
||||
document.getElementById("footer").style.display = "none";
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
239
blockpage/not_found.html
Normal file
|
@ -0,0 +1,239 @@
|
|||
<!DOCTYPE html>
|
||||
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title>您访问的网站不存在</title>
|
||||
<link
|
||||
rel="shortcut icon"
|
||||
href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAC8VBMVEUAAAAqKipISEgnJydDQkIDAwMcHBw8PDw8PDwWFhYVFRUqKionJycLCws+Pz8ICAgmJiYICAhHR0cNDQ0QEBApKSksLCwbGxs9PT1HR0cjIyNDQ0MwMDA5OTlHR0cHBwdGRkYyMjIVFRUODg5AQEAYGBgxMTEDAwNJSUkfHx8lJSVBQUELCwsHBwdHR0cwMDAcHBxAQEALCws6OzsDAwMyMjL///89Pj79/v0DAgInt3UnuncoKCgFBAQICQk2NzcWFxYPDw9FRUUlvHhBQUE6PTsLCgtGSEY5OTohISESEhIuLy4slnoyl3grlHM+o21htI0rk3dIqXRCpnEzMzMwoFlgsJNEqWwroFMxMTH2+vg4oWQonUwkJiUeHR02mXxPrHotlnQrlW8ynWqEwqZnuolitoY9nX84oGs9o2o/p2Y6pmEtLCz5/Pvf7+g7nngpkHVLrXA5pGg2o10jm0xLS0selUkLAADu9fKx1sJnt5BMpoZLqXgwmnIzoGE4QT3C3dBSqYpYsINIpn1AoHtBpHc2nHU6o3AnrG4qqGw0PjkQGxYIEA5ksZZdtYFSq4FDoYBZs3xTsHc0lWEqnFo2glkvFSsaHBvn8+7b6+K43Mx5vaFasIhHooVVr344m20smmQaWEZEMT8xST642san0rtxuZhZrI4+oXIbmGEAjlRFTEg3MDgwOTRasZNvvI49sn4iuXQor3EdqGkkfGYipWEsm18npE4tV0Q5SUFDOkBFKj05IDQnAR0KFBF0v5cniG80jF0dmlUAlTiwzrqezrdpt5cns3MvoWksmmkyf1g6dFQvdVMCl1AwbVA9ZE4oZUoxY0EVAAHX5t3S5t3L39Kix66Sx6yWwKVNqIFIsHcpjm8yl24VmlosiUoAjkaBvZuBtZBZo3osk2IwpFohalMvekwvckE/LToZSTg2KDQwIC0UMyceLSUOKiFWsI92rY1IrX4rhVoAkiwiABZxr4Ihw3xfqnMmgGAMmkcAjgBUQVAtAAAANnRSTlMABP4G/v0bGjcoNyEKyEbs4NPMvEMR/fz78uzYzcG7bmxsbEsq/PT05sy4rKuVk5OTfn3v202D2tR1AAAI+UlEQVRYw7SSP2uDQBjGeyqc0OIgFBKk4pChEAiEDkIcAv7B+wqd+xk635p0Le7FjtrFqf5ZMiVoiN8ihHyAzH3vbEmTJk069IeeD+/r85x33sU/Il7jjgx08LX4dzNWjJ6uareApuo9Q8HnhyCElZ7afmQIABdttadghM6xi5eGDm5hD8jQjUsRnZ7dUAXBF+DmRFHzFHhRNU58BbpSdF+wfcm3OVEeBHnEJS8Kvq5coV/8uN+2GXUmRWz6MEoSP+RSymreavcxOurvdG1Jkmw7rJ6zPAzzsB5Z1qgOmc6eqxC60O52jiSIsgpvuIx8Np1UVTAbWAO4ZkFVTaaznPcgQZXFw34N7A2ZlGwcy3EGHAfkJpEyaDQR2qEEJGtuy/zEzdIH8ANgZ1gPaeZ+dVuuJqOf678B/xayqoOgLOcvL/OyDIJ6RaC4TbjZ3weEu2bL80xCKIycVVHE8XA8juO4KFZNzfMoITC2zC5Gu/+/b3oAWaRrSqnHoGlK38eOM35nyuNQuk4XhCmzv3MekHJHAFosR4u3++ETg5DXMrFgD5LyddiUhvdvi9GyoAS4U9D3BXxwRT4hiYRhGGcJ+gvRpQ6hBy8eunRqCBM8SKc5CObgjuNCB2dAHYUcEV0WkU5jB5fJ2cEM2oO6ECjuJmqHlkhb3ENBErWLkBRFQd6KiPa07/fNuMQ+Mwzf9877/Ob53tGj2mKxHalakw8nu7lcbvfoWrSCH/6jVbw+wqWTh6S1GmkXF1G3/tUhBgwWpGIuHAaC1dQSxZ3WAtg1wbK1I4otkxX84XCuiNsNA/8CjOlw5b5bRwTTApLpP6lF5K9373G7buxNH2CwOODau6u73eFIpCFCN9Y3TdrWJDYikbDbXb/bwwZDHzCktzgcDrrkrruBgBDVSiWZrFS+alJ3VWQHP7SVaDBY9EMaYM4I25ICAd6CKEqW5drn7e2Pmx6PZxM9vny4qKVrUKZQA4qglMBinNNGOAufRwGwW/D7fc4VZ/J9IZvN5rOJRDYPix9c0m73+fyCQCEIRKAhxKw6xkEdDVLaYL8RkFuSOuV8ECkTPD/MZPAixnYkacUJDIRoKzRJ07pBDBg3kiCle0Nh+3pKKuej8y6XiwgknpvNqw0i4HIF5qMxVkqtq4ibroI8xnEMMJBTJMmv9e3sfixDEPNwn141XwSq+XIehQ0UMoUy20es8STYDOoIyCme7rX9mr/sCWI/4fr9p8FQMJamcOhSETG2zEmA8PvbPRoAeAiTM/wUT36/FdQEEseysaiKOH16bAgyxciPz2cEKuURAGe4VWiwzUwCYExnNvN4BHEmpIZI7Z8F8CcDeV+TYeJx5rh5FX0NCH1SSN5s1o0BYGTCbDaTvYO4LEOn12Zf2eLY1K8NNXT0/PjCG4cXjzBLIpZCALvTGzrokWCbGAHAMALwfDrExOUahPA67curLMcWtNEFL3/amDjTOIR1ocOltpYRIM3zCDAMgNFpM4hMg9PG1BDCtmRfTrHcfgLOQQQ2LpfsNi/DHD+dErEOt6oBUIB306MY8JfJ8glJJAzDOLEgRHQqCDoaHbp1Wjp4mFMwgczgwBxcnNVRajq0wl5aRwX/ewhJiDLTssP6F9ZzF5FglRUqxLVSMgw7BUm1dOi4z/epu72n+eR7fj7PO++LmkywAIDgMhuA+MQhh+toVV29jm/E0+XyqtkgcF/Xb7tX1wOAQBxADwCNwBLCDv3iI59LuT1f58izj1cTaZutklB5HxFxCtphBoDgdoieRQTSRJY16fZOw5zgAoB/abW6eU4hJ75crsQ3mjZe5Y9ckHHK8bFiMLsELny6pzOxLG3ixALLsrrS7j+A4+Nl71wBwWC4axrJRB1keDW57RIETrECIQCwW9JBtjBBB4kCzsK5oGvbl+Rf0pBc5RWrIvy6Gw1xhedVHxC5MEFYlfAZBdBB+rAoIUPphAKSfCbpwAuPd3NWqzWXr42G+DfJsd32B0EgiJMSEkiLdJ+10oxkYn+kckE/AajfMXL7z918CoRUoXe5RAlGD83hD+YI4r4vsZBp6TZOz8YkWDgNvgNgk3uFWqpWS+UL2Ge6Gt/SqsoPEOE/r6wkxWanKUCzEIOF1/oQUHUMTBt/3hdSHYLotowDxBdbpsr7kCNYfzXBwIIGctKE2HxMkvode8Df9vLVjGPUulahkIKFZ6wWtXCQqIrJtj9g7+gkCSK0gNbcDMMwscZFKASEMys+JTyj1j0XCj0PHmioxJOYdUIeCl00YpDMzEFMM0wx8zj3ZXfIDoRXjBRtTbSOIDyj19C0FSOitx2A3i33GQaSKc0QMKZlqIW6uwNEIOr0imJxtM/DlayIouh1RiHHpToMoLRjI8D4JI4rTOPNLbuHiIgYSe9DjEJ4R1WMZAdyXHlrMCsQTI7//3HVrqCY5ccbWbZY9EAcOrORYpV0k0xAogj5YdQe0rstsnzzuMyQ+1q0cGRBM0U+2dp8kFEWvf7zWvTQCwS6uUTDw/2aXa+3yKiHzS1ye0rz/g/C39rLl7dBIA7DaxaaUCCEQDUCUQOG1CCOBHOCXJtgapuqWRx6Gr5CBapuCk0w+wwT1YgmDfsKe48jpQtJm4m9Cclx93ue+6fO0qM4jvKsPGyRQYHT/P76/Nj1+B54P1ZmOa/VLfCjQPXjCIFhe+BVveLIT3PHV/828BgEj8I48tV7ATbhopMbLmd2WwQUp9P7cZyenS8D7942MN5EhNA8u1YsSdMkSViv4Ph+g1/0seqa5TRCNBn877wuDBpRSussK8+DYrOHAjgTeFNmWU0pyowFbmBisIShqIOubZhwbIALmjVtF9SF4C3BT9aghZSGYViTIC+rlN0lrco8IDUGUaEN808NsosCXgRF0JVtVTVIVbVlFwDnQ/hcecKPd+HrJERIWBQBDwC4kKIIeSSi+/NHTxbVMQmRJIkQOACBHhpDt+mos8ePrrltYEIUc1YELU6j27Dns9nTZ59sayvuQAQvCXql2fLriD9chePBcR/QnjPO/jyqYtmeaax1ZG2Ynm0p6stfoy4VeYHIyhLwv+UH4kmftbvi1LgAAAAASUVORK5CYII="
|
||||
/>
|
||||
<style>
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.container {
|
||||
text-align: center;
|
||||
word-break: keep-all;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: white;
|
||||
font-size: 14px;
|
||||
min-height: 450px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.logo {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.intercepted {
|
||||
margin-top: 3.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
font-size: 20px;
|
||||
line-height: 1.6;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.intercepted-item {
|
||||
margin: 8px 0;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: absolute;
|
||||
bottom: 32px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
color: rgba(0, 0, 0, 0.3);
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
}
|
||||
.footer-waflink {
|
||||
color: #27b876;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<table class="content">
|
||||
<tr>
|
||||
<td>
|
||||
<div class="logo">
|
||||
<svg
|
||||
width="200px"
|
||||
height="200px"
|
||||
viewBox="0 0 396 407"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient
|
||||
x1="50%"
|
||||
y1="0%"
|
||||
x2="50%"
|
||||
y2="100%"
|
||||
id="linearGradient-1"
|
||||
>
|
||||
<stop stop-color="#4B4B4B" offset="0%"></stop>
|
||||
<stop stop-color="#000000" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<filter
|
||||
x="-3.0%"
|
||||
y="-2.8%"
|
||||
width="106.1%"
|
||||
height="105.6%"
|
||||
filterUnits="objectBoundingBox"
|
||||
id="filter-2"
|
||||
>
|
||||
<feGaussianBlur
|
||||
stdDeviation="3"
|
||||
in="SourceGraphic"
|
||||
></feGaussianBlur>
|
||||
</filter>
|
||||
<linearGradient
|
||||
x1="50%"
|
||||
y1="0%"
|
||||
x2="50%"
|
||||
y2="100%"
|
||||
id="linearGradient-3"
|
||||
>
|
||||
<stop
|
||||
stop-color="#24BC43"
|
||||
stop-opacity="0.8"
|
||||
offset="0%"
|
||||
></stop>
|
||||
<stop
|
||||
stop-color="#3ACBAB"
|
||||
stop-opacity="0.7"
|
||||
offset="100%"
|
||||
></stop>
|
||||
</linearGradient>
|
||||
<path
|
||||
d="M110.049657,49.667649 C110.049657,49.667649 81.1358702,46.2263115 76.8,26.7636364 C72.4880848,46.2263115 43.5503431,49.667649 43.5503431,49.667649 C14.2053649,53.3001718 0,36.4567369 0,36.4567369 C13.941859,65.8036979 38.4,64.7712967 38.4,64.7712967 L115.2,64.7712967 C115.2,64.7712967 139.634186,65.8036979 153.6,36.4567369 C153.6,36.4567369 139.394635,53.3192904 110.049657,49.667649 Z"
|
||||
id="path-4"
|
||||
></path>
|
||||
<filter
|
||||
x="-16.9%"
|
||||
y="-57.9%"
|
||||
width="133.9%"
|
||||
height="236.8%"
|
||||
filterUnits="objectBoundingBox"
|
||||
id="filter-5"
|
||||
>
|
||||
<feOffset
|
||||
dx="0"
|
||||
dy="4"
|
||||
in="SourceAlpha"
|
||||
result="shadowOffsetOuter1"
|
||||
></feOffset>
|
||||
<feGaussianBlur
|
||||
stdDeviation="8"
|
||||
in="shadowOffsetOuter1"
|
||||
result="shadowBlurOuter1"
|
||||
></feGaussianBlur>
|
||||
<feColorMatrix
|
||||
values="0 0 0 0 0 0 0 0 0 0.490319293 0 0 0 0 0.292243323 0 0 0 1 0"
|
||||
type="matrix"
|
||||
in="shadowBlurOuter1"
|
||||
></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g
|
||||
stroke="none"
|
||||
stroke-width="1"
|
||||
fill="none"
|
||||
fill-rule="evenodd"
|
||||
>
|
||||
<g transform="translate(49.000000, 38.000000)">
|
||||
<path
|
||||
d="M292.40836,59.04 C290.927217,51.9634286 285.002646,46.6971429 277.761503,46.368 C222.13636,44.8868571 176.385503,16.5805714 157.953503,3.08571429 C152.358074,-1.02857143 144.95236,-1.02857143 139.356931,3.08571429 C120.431217,16.5805714 75.1740742,44.8868571 19.5489314,46.368 C12.4723599,46.6971429 6.21864565,51.9634286 4.90207422,59.04 C-3.98478292,103.474286 -19.2899258,254.057143 148.902074,324 C316.60036,253.892571 300.966074,103.474286 292.40836,59.04 Z"
|
||||
fill="url(#linearGradient-1)"
|
||||
fill-rule="nonzero"
|
||||
></path>
|
||||
<path
|
||||
d="M292.40836,59.04 C290.927217,51.9634286 285.002646,46.6971429 277.761503,46.368 C222.13636,44.8868571 176.385503,16.5805714 157.953503,3.08571429 C152.358074,-1.02857143 144.95236,-1.02857143 139.356931,3.08571429 C120.431217,16.5805714 75.1740742,44.8868571 19.5489314,46.368 C12.4723599,46.6971429 6.21864565,51.9634286 4.90207422,59.04 C-3.98478292,103.474286 -19.2899258,254.057143 148.902074,324 C316.60036,253.892571 300.966074,103.474286 292.40836,59.04 Z"
|
||||
fill="url(#linearGradient-1)"
|
||||
fill-rule="nonzero"
|
||||
filter="url(#filter-2)"
|
||||
></path>
|
||||
<path
|
||||
d="M149,261.4 C205.553958,261.4 251.4,215.553958 251.4,159 C251.4,131.275004 240.381593,106.123494 222.484813,87.6855068 C209.900749,96.0964568 185.81512,106.024178 175.564259,100.853688 C166.334879,96.1984273 157.476591,88.4505652 148.989396,77.610101 C142.047769,88.5334102 134.670586,95.5517221 126.857848,98.6650367 C120.689419,101.123107 98.2592604,102.915695 75.4419467,87.761039 C57.5883513,106.192154 46.6,131.312844 46.6,159 C46.6,215.553958 92.4460416,261.4 149,261.4 Z"
|
||||
fill="url(#linearGradient-3)"
|
||||
></path>
|
||||
<g
|
||||
transform="translate(91.771423, 102.101722)"
|
||||
fill="#FFFFFF"
|
||||
>
|
||||
<polygon
|
||||
transform="translate(57.217971, 95.920999) rotate(-180.000000) translate(-57.217971, -95.920999) "
|
||||
points="56.6651511 64.9496372 -7.57241738e-17 97.1108413 50.6084036 126.892361 68.8016729 117.264704 34.3433228 97.1108413 56.6651511 84.5503086 96.9001091 107.376711 96.9001091 114.88399 114.435942 125.435553 114.435942 97.1108413"
|
||||
></polygon>
|
||||
<polygon
|
||||
transform="translate(57.217971, 30.971362) rotate(-360.000000) translate(-57.217971, -30.971362) "
|
||||
points="56.6651511 2.84217094e-14 -7.57241738e-17 32.1612041 50.6084036 61.9427239 68.8016729 52.3150668 34.3433228 32.1612041 56.6651511 19.6006714 96.9001091 42.4270741 96.9001091 49.9343528 114.435942 60.4859155 114.435942 32.1612041"
|
||||
></polygon>
|
||||
<polygon
|
||||
opacity="0.40499442"
|
||||
transform="translate(57.217971, 95.920999) rotate(-180.000000) translate(-57.217971, -95.920999) "
|
||||
points="56.6651511 64.9496372 -7.57241738e-17 97.1108413 50.6084036 126.892361 68.8016729 117.264704 34.3433228 97.1108413 56.6651511 84.5503086 96.9001091 107.376711 96.9001091 114.88399 114.435942 125.435553 114.435942 97.1108413"
|
||||
></polygon>
|
||||
<polygon
|
||||
opacity="0.40499442"
|
||||
transform="translate(57.217971, 30.971362) rotate(-360.000000) translate(-57.217971, -30.971362) "
|
||||
points="56.6651511 4.8316906e-13 -7.57241738e-17 32.1612041 50.6084036 61.9427239 68.8016729 52.3150668 34.3433228 32.1612041 56.6651511 19.6006714 96.9001091 42.4270741 96.9001091 49.9343528 114.435942 60.4859155 114.435942 32.1612041"
|
||||
></polygon>
|
||||
</g>
|
||||
<g
|
||||
transform="translate(72.200000, 45.222222)"
|
||||
fill-rule="nonzero"
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d="M96.7632666,18.0061837 C96.7632666,18.0061837 79.3862969,15.2966085 76.7907961,0 C74.1952953,15.2966085 56.8183256,18.0061837 56.8183256,18.0061837 C39.1836466,20.8694936 30.6424242,7.60987058 30.6424242,7.60987058 C39.0363842,30.6893013 53.7258141,29.862977 53.7258141,29.862977 L99.8741859,29.862977 C99.8741859,29.862977 114.563616,30.6700845 122.957576,7.60987058 C122.957576,7.60987058 114.416353,20.8694936 96.7816744,18.0061837 L96.7632666,18.0061837 Z"
|
||||
fill="#27B876"
|
||||
></path>
|
||||
<g>
|
||||
<use
|
||||
fill="black"
|
||||
fill-opacity="1"
|
||||
filter="url(#filter-5)"
|
||||
xlink:href="#path-4"
|
||||
></use>
|
||||
<use fill="#27B876" xlink:href="#path-4"></use>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="intercepted">您访问的网站不存在</div>
|
||||
<div class="intercepted-item">当前域名可能有误,请检查配置</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="footer">
|
||||
安全检测能力由
|
||||
<a class="footer-waflink" href="https://waf-ce.chaitin.cn"
|
||||
>长亭雷池 WAF</a
|
||||
>
|
||||
驱动
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
3
documents/.dockerignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
build
|
||||
.docusaurus
|
20
documents/.gitignore
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Dependencies
|
||||
/node_modules
|
||||
|
||||
# Production
|
||||
/build
|
||||
|
||||
# Generated files
|
||||
.docusaurus
|
||||
.cache-loader
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
4
documents/.npmrc
Normal file
|
@ -0,0 +1,4 @@
|
|||
strict-ssl=false
|
||||
save-prefix=""
|
||||
engine-strict=true
|
||||
registry="https://registry.npmmirror.com"
|
12
documents/README.md
Normal file
|
@ -0,0 +1,12 @@
|
|||
# doc
|
||||
|
||||
使用 [Docusaurus 2](https://docusaurus.io/), 作为基础框架。
|
||||
|
||||
### 开发
|
||||
|
||||
```sh
|
||||
# 代码变动后可以自动更新,但是不能搜索
|
||||
npm start
|
||||
# 支持搜索功能,但是无法自动更新
|
||||
npm run preview
|
||||
```
|
3
documents/babel.config.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
module.exports = {
|
||||
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
|
||||
};
|
60
documents/docs/01-introduction.md
Normal file
|
@ -0,0 +1,60 @@
|
|||
---
|
||||
title: "雷池简介"
|
||||
slug: /
|
||||
---
|
||||
|
||||
# 雷池简介
|
||||
|
||||
## 什么是雷池
|
||||
|
||||
雷池(SafeLine)是长亭科技耗时近 10 年倾情打造的 WAF,核心检测能力由智能语义分析算法驱动。
|
||||
|
||||
Slogan: 不让黑客越雷池一步。
|
||||
|
||||
## 什么是 WAF
|
||||
|
||||
WAF 是 Web Application Firewall 的缩写,也被称为 Web 应用防火墙。
|
||||
|
||||
区别于传统防火墙,WAF 工作在应用层,对基于 HTTP/HTTPS 协议的 Web 系统有着更好的防护效果,使其免于受到黑客的攻击。
|
||||
|
||||
## 为什么是雷池
|
||||
|
||||
#### 便捷性
|
||||
|
||||
采用容器化部署,一条命令即可完成安装,0 成本上手
|
||||
|
||||
安全配置开箱即用,无需人工维护,可实现安全躺平式管理
|
||||
|
||||
#### 安全性
|
||||
|
||||
首创业内领先的智能语义分析算法,精准检测、低误报、难绕过
|
||||
|
||||
语义分析算法无规则,面对未知特征的 0day 攻击不再手足无措
|
||||
|
||||
#### 高性能
|
||||
|
||||
无规则引擎,线性安全检测算法,平均请求检测延迟在 1 毫秒级别
|
||||
|
||||
并发能力强,单核轻松检测 2000+ TPS,只要硬件足够强,可支撑的流量规模无上限
|
||||
|
||||
#### 高可用
|
||||
|
||||
流量处理引擎基于 Nginx 开发,性能与稳定性均可得到保障
|
||||
|
||||
内置完善的健康检查机制,服务可用性高达 99.99%
|
||||
|
||||
## WAF 部署架构
|
||||
|
||||
下图是一个简单的网站流量拓扑,外部用户发出请求,经过网络最终传递到网站服务器。
|
||||
|
||||
此时,若外部用户中存在恶意用户,那么由恶意用户发出的攻击请求也会经过网络最终传递到网站服务器。
|
||||
|
||||

|
||||
|
||||
社区版雷池以反向代理方式接入,优先于网站服务器接收流量,对流量中的攻击行为进行检测和清洗,将清洗过后的流量转发给网站服务器。
|
||||
|
||||
通过以上行为,最终确保外部攻击流量无法触达网站服务器。
|
||||
|
||||

|
||||
|
||||
详情查看 **[雷池技术架构](/about/framework)**
|
140
documents/docs/02-guide/01-install.md
Normal file
|
@ -0,0 +1,140 @@
|
|||
---
|
||||
title: "安装雷池"
|
||||
---
|
||||
|
||||
# 安装雷池
|
||||
|
||||
根据实际情况选择安装方式,支持一键安装
|
||||
|
||||
- [环境检测](#环境检测) : 查看环境是否符合安装要求
|
||||
- [在线安装](#在线安装) : 推荐方式,一行命令完成安装
|
||||
- [离线安装](#离线安装) : 下载离线安装包,轻松完成安装
|
||||
- [其他方式安装](#使用牧云助手安装) : 使用牧云助手,点击即可完安装
|
||||
|
||||
## 在线安装(推荐)
|
||||
|
||||
**_如果服务器可以访问互联网环境,推荐使用该方式_**
|
||||
|
||||
复制以下命令执行,即可完成安装
|
||||
|
||||
```sh
|
||||
bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)"
|
||||
```
|
||||
如果需要使用华为云加速,可使用
|
||||
```sh
|
||||
CDN=1 bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)"
|
||||
```
|
||||
如果需要安装最新版本流式检测模式,可使用
|
||||
```sh
|
||||
STREAM=1 bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)"
|
||||
```
|
||||
|
||||
**若安装失败,请参考 [安装问题](/faq/install)**
|
||||
|
||||
### 在线安装演示
|
||||
|
||||
<iframe src="//player.bilibili.com/player.html?aid=236214137&bvid=BV1Je411f7hQ&cid=1339636220&p=1&autoplay=0" scrolling="no" border="0" frameBorder="no" framespacing="0" allowFullScreen='{true}'
|
||||
style={{ width: '100%', height: '350px' }}
|
||||
>
|
||||
</iframe>
|
||||
|
||||
## 离线安装
|
||||
|
||||
**_如果服务器不可以访问互联网环境,推荐使用该方式_**
|
||||
|
||||
> 离线安装前需完成[环境检测](#环境检测),默认已完成 docker 环境准备
|
||||
|
||||
1. 下载 [雷池社区版镜像包](https://demo.waf-ce.chaitin.cn/image.tar.gz) 并传输到需要安装雷池的服务器上,执行以下命令加载镜像
|
||||
|
||||
```shell
|
||||
cat image.tar.gz | gzip -d | docker load
|
||||
```
|
||||
|
||||
2. 执行以下命令创建并进入雷池安装目录
|
||||
|
||||
```shell
|
||||
mkdir -p safeline && cd safeline # 创建 safeline 目录并且进入
|
||||
```
|
||||
|
||||
3. **下载 [编排脚本](https://waf-ce.chaitin.cn/release/latest/compose.yaml) 并传输到 safeline 目录中**
|
||||
|
||||
4. 复制执行以下命令,生成雷池运行所需的相关环境变量
|
||||
|
||||
```shell
|
||||
cat >> .env <<EOF
|
||||
SAFELINE_DIR=$(pwd)
|
||||
IMAGE_TAG=latest
|
||||
MGT_PORT=9443
|
||||
POSTGRES_PASSWORD=$(LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 32)
|
||||
SUBNET_PREFIX=172.22.222
|
||||
IMAGE_PREFIX=chaitin
|
||||
EOF
|
||||
```
|
||||
|
||||
注意:不要一行一行复制,一次性复制全部命令后执行,如图
|
||||
|
||||

|
||||
|
||||
5. 执行以下命令启动雷池
|
||||
|
||||
```shell
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
**若安装失败,请参考 [安装问题](/faq/install)**
|
||||
|
||||
### 离线安装演示
|
||||
|
||||
<iframe src="//player.bilibili.com/player.html?aid=278701847&bvid=BV1gw411P7om&cid=1339618895&p=1&autoplay=0" scrolling="no" border="0" frameBorder="no" framespacing="0" allowFullScreen='{true}'
|
||||
style={{ width: '100%', height: '350px' }}
|
||||
>
|
||||
</iframe>
|
||||
|
||||
## 使用牧云助手安装
|
||||
|
||||
使用 [牧云主机管理助手](https://collie.chaitin.cn/) 进行一键安装
|
||||
|
||||
直接点击应用市场的安装按钮安装
|
||||
|
||||

|
||||
|
||||
### 助手安装演示
|
||||
|
||||
<iframe src="//player.bilibili.com/player.html?aid=613778738&bvid=BV1sh4y1t7Pk&cid=1134834926&p=1&autoplay=0" scrolling="no" border="0" frameBorder="no" framespacing="0" allowFullScreen="{true}"
|
||||
style={{ width: '100%', height: '350px' }}
|
||||
> </iframe>
|
||||
|
||||
## 环境检测
|
||||
|
||||
最低配置需求
|
||||
|
||||
- 操作系统:Linux
|
||||
- 指令架构:x86_64
|
||||
- 软件依赖:Docker 20.10.14 版本以上
|
||||
- 软件依赖:Docker Compose 2.0.0 版本以上
|
||||
- 最小化环境:1 核 CPU / 1 GB 内存 / 5 GB 磁盘
|
||||
|
||||
可以逐行执行以下命令来确认服务器配置
|
||||
|
||||
```shell
|
||||
uname -m # 查看指令架构
|
||||
docker version # 查看 Docker 版本
|
||||
docker compose version # 查看 Docker Compose 版本
|
||||
docker-compose version # 老版本查看Compose 版本
|
||||
cat /proc/cpuinfo| grep "processor" # 查看 CPU 信息
|
||||
free -h # 查看内存信息
|
||||
df -h # 查看磁盘信息
|
||||
lscpu | grep ssse3 # 确认CPU是否支持 ssse3 指令集
|
||||
```
|
||||
|
||||
### 配置检测演示
|
||||
|
||||
<iframe src="//player.bilibili.com/player.html?aid=918634668&bvid=BV1Uu4y1L7Ko&cid=1339439164&p=1&autoplay=0" scrolling="no" border="0" frameBorder="no" framespacing="0" allowFullScreen='{true}'
|
||||
style={{ width: '100%', height: '350px' }}
|
||||
></iframe>
|
||||
|
||||
## 常见安装问题
|
||||
|
||||
请参考 [安装问题](/faq/install)
|
||||
|
||||
下一步请参考 [登录雷池](/guide/login)
|
39
documents/docs/02-guide/02-login.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
title: "登录雷池"
|
||||
---
|
||||
|
||||
# 登录雷池
|
||||
|
||||
> TOTP (Time-based One-Time Password algorithm) 将密钥与当前时间进行组合,通过哈希算法产生一次性密码,已被采纳为 RFC 6238,被用于许多双因素身份验证系统。
|
||||
|
||||
## 登录流程
|
||||
|
||||
1.浏览器打开后台管理页面 `https://<waf-ip>:9443`。
|
||||
|
||||
2.输入初始的admin密码
|
||||
|
||||
完成安装后在shell会自动输出密码。
|
||||
|
||||

|
||||
|
||||
若忘记查看,需手生执行命令重置获得初始密码
|
||||
|
||||
`docker exec safeline-mgt resetadmin`
|
||||
|
||||

|
||||
|
||||
3.根据界面提示,使用 **支持 TOTP 的认证软件或者小程序** 扫描二维码,然后输入动态口令登录:
|
||||
|
||||
<iframe src="//player.bilibili.com/player.html?aid=748637002&bvid=BV1wC4y177zN&cid=1339420830&p=1&autoplay=0" scrolling="no" border="0" frameBorder="no" framespacing="0" allowFullScreen='{true}'
|
||||
style={{ width: '100%', height: '350px' }}
|
||||
></iframe>
|
||||
|
||||
### 注意事项:
|
||||
|
||||
1.服务器和 totp 应用的**时间必须保持一致**,否则无法验证通过
|
||||
|
||||
2.完成首次登录后,**无法回退查看二维码**,使用页面提供的方法重置
|
||||
|
||||
## 常见登录问题
|
||||
|
||||
请参考 [登录问题](/faq/login)
|
81
documents/docs/02-guide/03-professional.md
Normal file
|
@ -0,0 +1,81 @@
|
|||
---
|
||||
title: "购买专业版"
|
||||
---
|
||||
|
||||
# 购买专业版
|
||||
|
||||
社区版永久免费,使用雷池专业版需要购买授权
|
||||
|
||||
## 在百川进行授权购买
|
||||
|
||||
### 打开长亭百川云平台
|
||||
|
||||
百川网站地址:https://rivers.chaitin.cn/
|
||||
|
||||
### 在平台添加雷池社区版应用
|
||||
|
||||
专业版购买地址:https://rivers.chaitin.cn/?share=85db8d21d63711ee91390242c0a8176b
|
||||
|
||||
使用上方链接登录百川以后默认有对应的雷池社区版应用,若无,可以手动添加
|
||||
|
||||

|
||||
|
||||
### 按需购买
|
||||
|
||||
进入应用后点击购买,根据需求完成购买,如有开票需求单独找社区管理
|
||||
|
||||

|
||||
|
||||
购买一年更优惠!
|
||||

|
||||
|
||||
## 手动使用授权码进行授权
|
||||
|
||||
### 查看授权码
|
||||
|
||||
购买完成后右上角点击绑定查看授权码
|
||||

|
||||
|
||||

|
||||
|
||||
### 输入授权码
|
||||
在雷池内打开授权页面,输入授权码进行授权
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
## 使用云托管自动进行授权
|
||||
|
||||
什么是雷池云托管?请参考 [雷池云托管](/practice/safeline-cloud)
|
||||
|
||||
### 获取云托管安装命令
|
||||
|
||||
点击获取云托管的安装命令
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### 完成云托管安装
|
||||
|
||||
完成安装后可以看到设备的基本信息
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### 云托管升级专业版
|
||||
|
||||
点击云托管的升级为专业版按钮,选择购买的授权即可快捷完成专业版授权
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 完成授权
|
||||
完成授权后可以使用所有专业版功能
|
||||
|
||||

|
||||
|
108
documents/docs/02-guide/04-config.md
Normal file
|
@ -0,0 +1,108 @@
|
|||
---
|
||||
title: "配置站点"
|
||||
---
|
||||
|
||||
# 配置站点
|
||||
|
||||
根据指导,完成站点配置
|
||||
|
||||
## 工作原理
|
||||
|
||||
雷池社区版主要以 **反向代理** 的方式工作,类似nginx。
|
||||
|
||||
**让网站流量先抵达雷池,经过雷池检测和过滤后,再转给原来的网站业务。**
|
||||
|
||||
## 配置界面
|
||||
|
||||

|
||||
|
||||
## 在单独的服务器部署雷池时配置(推荐)
|
||||
|
||||
### 开始配置
|
||||
|
||||
```shell
|
||||
环境信息:
|
||||
网站服务器:IPA,对外端口80,域名‘example.com’
|
||||
雷池服务器:IPB
|
||||
|
||||
步骤:
|
||||
1.将原网站流量指向雷池的IPB(必须)。例如修改域名解析服务,将域名解析到IPB
|
||||
2.参考配置如下图
|
||||
3.禁止网站服务器上,除雷池之外的访问。例如配置防火墙
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 配置完成
|
||||
|
||||
如果浏览器访问`example.com:80`能获取到业务网站的响应,并且数据统计页的 “今日请求数” 增加,代表配置成功。
|
||||
|
||||
|
||||
效果大致如下:
|
||||
|
||||

|
||||
|
||||
## 在网站服务器上部署雷池时配置
|
||||
|
||||
提示:不建议,因为这样单机的负载更高、设备宕机的概率更大。非纯净的环境还会提高升级失败的概率,故障排查更困难。
|
||||
|
||||
### 开始配置
|
||||
|
||||
```shell
|
||||
环境信息:
|
||||
网站服务器:IPA,对外端口80,域名‘example.com’
|
||||
|
||||
步骤:
|
||||
1.需要原网站的监听修改为端口A,使80端口变成未使用状态,再进行配置
|
||||
2.具体配置参考下图
|
||||
```
|
||||
|
||||

|
||||
|
||||
<!-- ### 参考视频
|
||||
|
||||
<video width="640" height="360" controls id="mp4" src="https://chaitin-marketing-public.oss-cn-beijing.aliyuncs.com/chaitin-website/safeline.mp4" type="video/mp4">
|
||||
|
||||
</video> -->
|
||||
|
||||
### 配置完成
|
||||
|
||||
如果浏览器访问`example.com:80`能获取到业务网站的响应,并且数据统计页的 “今日请求数” 增加,代表配置成功。
|
||||
|
||||
效果大致如图:
|
||||
|
||||

|
||||
|
||||
## 和其他反代设备一起部署时配置
|
||||
|
||||
雷池作为反代设备,可以在任意位置接入主链路。
|
||||
|
||||
将接入位置的流量指向雷池,并在雷池的 “上游服务器” 处填写请求的下一跳服务器地址即可。
|
||||
|
||||
### 开始配置
|
||||
|
||||
```shell
|
||||
环境信息:
|
||||
网站服务器:IPA
|
||||
雷池服务器:IPB
|
||||
上游服务器:IPC,端口C
|
||||
下游服务器:IPD,域名‘example.com’
|
||||
|
||||
步骤:
|
||||
1.将下游nginx的流量指向雷池的IPC,访问端口指向80。
|
||||
2.具体配置参考下图
|
||||
```
|
||||
|
||||

|
||||
|
||||
### 配置完成
|
||||
|
||||
如果浏览器访问`example.com:80`能获取到业务网站的响应,并且数据统计页的 “今日请求数” 增加,代表配置成功。
|
||||
|
||||
效果大致如图:
|
||||
|
||||

|
||||
|
||||
## 常见配置问题
|
||||
|
||||
请参考 [配置问题](/faq/config)
|
82
documents/docs/02-guide/05-test.md
Normal file
|
@ -0,0 +1,82 @@
|
|||
---
|
||||
title: "测试防护"
|
||||
---
|
||||
|
||||
# 测试防护
|
||||
|
||||
使用手工或者自动的方式测试防护效果
|
||||
|
||||
## 确认网站可以正常访问
|
||||
|
||||
根据雷池 WAF 配置的网站参数访问你的网站。
|
||||
|
||||
打开浏览器访问 `http://<IP或域名>:<端口>/`。
|
||||
|
||||
> 网站协议默认是 http,勾选 ssl 则为 https
|
||||
> 主机名可以是雷池的 IP,也可以是网站的域名(确保域名已经解析到雷池)
|
||||
> 端口是你在雷池页面中配置的网站端口
|
||||
|
||||
若网站访问不正常,请参考 [配置问题](/03-faq/03-config.md)。
|
||||
|
||||
整体监测流程参考:
|
||||
|
||||

|
||||
|
||||
|
||||
## 尝试手动模拟攻击
|
||||
|
||||
访问以下地址模拟出对应的攻击:
|
||||
|
||||
- 模拟 SQL 注入,请访问 `http://<IP或域名>:<端口>/?id=1%20AND%201=1`
|
||||
- 模拟 XSS,请访问 `http://<IP或域名>:<端口>/?html=<script>alert(1)</script>`
|
||||
|
||||
通过浏览器,你将会看到雷池已经发现并阻断了攻击请求。
|
||||

|
||||
|
||||
若请求没有被阻断,请参考 [防护问题](/03-faq/04-test.md)
|
||||
|
||||
## 自动化测试防护效果
|
||||
|
||||
两条请求当然无法完整的测试雷池的防护效果,可以使用 blazehttp 自动化工具进行批量测试
|
||||
|
||||
### 下载测试工具
|
||||
|
||||
- [Windows 版本](https://waf-ce.chaitin.cn/blazehttp/blazehttp_windows.exe)
|
||||
- [Mac 版本(x64)](https://waf-ce.chaitin.cn/blazehttp/blazehttp_mac_x64)
|
||||
- [Mac 版本(M1)](https://waf-ce.chaitin.cn/blazehttp/blazehttp_mac_m1)
|
||||
- [Linux 版本(x64)](https://waf-ce.chaitin.cn/blazehttp/blazehttp_linux_x64)
|
||||
- [Linux 版本(ARM)](https://waf-ce.chaitin.cn/blazehttp/blazehttp_linux_arm64)
|
||||
- [源码仓库](https://github.com/chaitin/blazehttp)
|
||||
|
||||
### 准备测试样本
|
||||
|
||||
- [测试样本](https://waf-ce.chaitin.cn/blazehttp/testcases.zip)
|
||||
|
||||
下载请求样本后解压到 `testcases` 目录
|
||||
|
||||
### 开始测试
|
||||
|
||||
1. 将测试工具 `blazehttp` 和测试样本 `testcases` 放在同一个目录下
|
||||
2. 进入对应的目录
|
||||
3. 使用以下请求开始测试
|
||||
|
||||
```
|
||||
./blazehttp -t http://<IP或域名>:<端口>
|
||||
```
|
||||
|
||||
### 测试效果展示
|
||||
|
||||
```sh
|
||||
# 测试请求
|
||||
.//blazehttp -t http://127.0.0.1:8008
|
||||
sending 100% |█████████████████████████████████████████████████████████| (33669/33669, 940 it/s) [35s:0s]
|
||||
总样本数量: 33669 成功: 33669 错误: 0
|
||||
检出率: 71.65% (恶意样本总数: 575 , 正确拦截: 412 , 漏报放行: 163)
|
||||
误报率: 0.07% (正常样本总数: 33094 , 正确放行: 33071 , 误报拦截: 23)
|
||||
准确率: 99.45% (正确拦截 + 正确放行)/样本总数
|
||||
平均耗时: 1.00毫秒
|
||||
```
|
||||
|
||||
## 常见防护问题
|
||||
|
||||
请参考 [防护问题](/faq/test)
|
73
documents/docs/02-guide/06-upgrade.md
Normal file
|
@ -0,0 +1,73 @@
|
|||
---
|
||||
title: "升级雷池"
|
||||
---
|
||||
|
||||
# 升级雷池
|
||||
|
||||
**注意**: 升级雷池时服务会重启,流量会中断一小段时间,根据业务情况选择合适的时间来执行升级操作。
|
||||
|
||||
[版本更新记录](/about/changelog)
|
||||
|
||||
## 在线升级
|
||||
|
||||
执行以下命令进行升级,升级不会清除历史数据。
|
||||
|
||||
```sh
|
||||
bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/upgrade.sh)"
|
||||
```
|
||||
|
||||
[可选] 执行以下命令删除旧版本 Docker 镜像,释放磁盘空间。
|
||||
|
||||
```sh
|
||||
docker rmi $(docker images | grep "safeline" | grep "none" | awk '{print $3}')
|
||||
```
|
||||
|
||||
> 有部分环境的默认 SafeLine 安装路径是在 `/data/safeline-ce`,安装之后可能会发现需要重新绑定 OTP、配置丢失等情况,可以修改 .env 的 `SAFELINE_DIR` 变量,指向 `/data/safeline-ce`
|
||||
|
||||
如果需要使用华为云加速,可使用
|
||||
```sh
|
||||
CDN=1 bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/upgrade.sh)"
|
||||
```
|
||||
如果需要升级到最新版本流式检测模式,可使用
|
||||
```sh
|
||||
STREAM=1 bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/upgrade.sh)"
|
||||
```
|
||||
|
||||
## 离线镜像
|
||||
|
||||
适用于 docker hub 拉取镜像失败的场景,手动更新镜像。
|
||||
|
||||
```sh
|
||||
# cd /path/to/safeline
|
||||
|
||||
mv compose.yaml compose.yaml.old
|
||||
wget "https://waf-ce.chaitin.cn/release/latest/compose.yaml" --no-check-certificate -O compose.yaml
|
||||
|
||||
wget "https://waf-ce.chaitin.cn/release/latest/seccomp.json" --no-check-certificate -O seccomp.json
|
||||
|
||||
sed -i "s/IMAGE_TAG=.*/IMAGE_TAG=latest/g" ".env"
|
||||
|
||||
grep "SAFELINE_DIR" ".env" > /dev/null || echo "SAFELINE_DIR=$(pwd)" >> ".env"
|
||||
grep "IMAGE_TAG" ".env" > /dev/null || echo "IMAGE_TAG=latest" >> ".env"
|
||||
grep "MGT_PORT" ".env" > /dev/null || echo "MGT_PORT=9443" >> ".env"
|
||||
grep "POSTGRES_PASSWORD" ".env" > /dev/null || echo "POSTGRES_PASSWORD=$(LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 32)" >> ".env"
|
||||
grep "SUBNET_PREFIX" ".env" > /dev/null || echo "SUBNET_PREFIX=172.22.222" >> ".env"
|
||||
grep "IMAGE_PREFIX" ".env" >/dev/null || echo "IMAGE_PREFIX=chaitin" >>".env"
|
||||
```
|
||||
|
||||
下载 [雷池社区版镜像包](https://demo.waf-ce.chaitin.cn/image.tar.gz) 并传输到需要安装雷池的服务器上,执行以下命令加载镜像
|
||||
|
||||
```
|
||||
docker load -i image.tar.gz
|
||||
```
|
||||
|
||||
执行以下命令替换 Docker 容器
|
||||
|
||||
```
|
||||
docker compose down --remove-orphans
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## 常见升级问题
|
||||
|
||||
请参考 [升级问题](/faq/upgrade)
|
128
documents/docs/02-guide/07-other_config.md
Normal file
|
@ -0,0 +1,128 @@
|
|||
---
|
||||
title: "配置其他"
|
||||
---
|
||||
|
||||
# 配置其他
|
||||
|
||||
其他配置项介绍
|
||||
|
||||
## 防护配置
|
||||
|
||||
### 黑白名单
|
||||
|
||||
黑名单:拦截
|
||||
|
||||
白名单:放通
|
||||
|
||||
注意:条件 AND 是指同时符合,如果希望多个匹配条件需要增加多条黑名单或者白名单
|
||||
|
||||

|
||||
|
||||
### 频率限制
|
||||
|
||||
通过开启频率限制功能封锁恶意 IP
|
||||
|
||||

|
||||
|
||||
### 人机验证
|
||||
|
||||
人机验证的有效时间默认是一个小时,未来可能会支持配置,敬请期待。
|
||||
|
||||
详情查看 [人机验证 2.0](/about/challenge)
|
||||
|
||||
### 语义分析
|
||||
|
||||
详情查看 [语义分析检测算法](/about/syntaxanalysis)
|
||||
|
||||
### 补充规则(专业版)
|
||||
|
||||
补充规则能在语义分析的基础上,针对一些特殊的业务漏洞、框架漏洞的利用行为进行防护。
|
||||
|
||||
社区版默认进行平衡防护,业版可进一步配置防护模式。
|
||||
|
||||

|
||||
|
||||
### 身份认证
|
||||
|
||||
可以通过添加认证规则,对雷池保护的站点额外增加身份认证功能。
|
||||
|
||||

|
||||
|
||||
如图,触发身份认证规则后需要使用账户密码登录后继续访问网站。
|
||||
|
||||

|
||||
|
||||
## 通用配置
|
||||
|
||||
### IP 组配置
|
||||
|
||||
1.支持自定义 IP 组
|
||||
|
||||
2.长亭社区恶意 IP 情报,需要加入 IP 情报共享计划才可以使用
|
||||
|
||||
### 证书管理
|
||||
|
||||
管理需要使用的证书,点击添加证书添加
|
||||
|
||||
### 其他
|
||||
|
||||
#### 源 ip 获取方式
|
||||
|
||||
1.使用默认的方式获取源 IP
|
||||
|
||||
2.自定义获取源 IP 的 header
|
||||
|
||||
#### 站点通用配置
|
||||
|
||||
1.如果配置站点需要 http 自动转为 https 功能时,需要手动开启
|
||||
|
||||
2.支持使用 HTTP2
|
||||
|
||||
3.雷池支持开启 IPv6 的访问
|
||||
|
||||
4.代理增加信息,方便数据分析
|
||||
|
||||
注:开启后并不会遵循源请求的信息,雷池会覆盖,为防止客户端伪造
|
||||
|
||||
#### 拦截页面附加说明
|
||||
|
||||
自定义拦截页面的提示信息
|
||||
|
||||
#### 雷池控制台证书
|
||||
|
||||
存放默认证书,可以自定义证书
|
||||
|
||||
#### 雷池控制台登录设置
|
||||
|
||||
用于配置登录雷池管理端的方式
|
||||
|
||||
低于5.0.0版本升级上来的,shell会显示初始密码,忘记可以手动重置
|
||||
|
||||
社区版支持单用户,**专业版**支持多用户管理
|
||||
|
||||
管理员固定为 admin,非管理员不能修改其他用户配置
|
||||
|
||||
#### 自定义拦截页面(专业版)
|
||||
|
||||
专业版用户可以自定义拦截页面
|
||||
|
||||
#### Syslog 设置
|
||||
|
||||
让雷池发送syslog到设置的服务器,**当前只支持UDP协议**
|
||||
|
||||

|
||||
|
||||
保存信息后可以点击测试按钮测试,收到测试信息表示配置成功
|
||||
|
||||
雷池发现攻击事件后,会发送事件的syslog信息
|
||||
|
||||

|
||||
|
||||
|
||||
#### IP 情报共享计划
|
||||
|
||||
默认加入共享计划,加入后将共享攻击 IP 信息到社区,并可使用 IP 组 “长亭社区恶意 IP 情报”。
|
||||
|
||||
## 常见配置问题
|
||||
|
||||
请参考 [其他问题](/faq/other)
|
7
documents/docs/02-guide/_category_.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"label": "上手指南",
|
||||
"collapsed": false,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
}
|
||||
}
|
114
documents/docs/03-faq/01-install.md
Normal file
|
@ -0,0 +1,114 @@
|
|||
---
|
||||
title: "安装问题"
|
||||
---
|
||||
|
||||
# 安装问题
|
||||
|
||||
记录常见的安装问题
|
||||
|
||||
## 在线安装失败
|
||||
|
||||
1. 检查是否手动关闭防火墙
|
||||
|
||||
2. 检测配置是否符合最低的配置要求
|
||||
|
||||
> 参考 [环境检测](/guide/install#环境检测) 方式
|
||||
|
||||
3. 如果连接 Docker Hub 网络不稳,导致镜像下载失败(超时):
|
||||
|
||||
> docker hub 默认使用国外节点拉取镜像,可以自行搜索配置国内镜像加速源
|
||||
|
||||
> 采用 [离线安装](/guide/install#离线安装) 方式
|
||||
|
||||
## 安装时遇到报错处理方法
|
||||
|
||||
#### 报错:ERROR: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
|
||||
|
||||
需要安装 docker。尝试 `curl -fLsS https://get.docker.com/ | sh` 或者 [Install Docker Engine](https://docs.docker.com/engine/install/)。
|
||||
|
||||
#### 报错:docker not found, unable to deploy
|
||||
|
||||
failed to create network safeline-ce
|
||||
safeline-ce 是雷池部署时候创建的 network,出现类似报错,先重启下 dockerd 之后重试
|
||||
|
||||
需要启动 docker daemon 才能执行相关的命令。尝试 `systemctl start docker`。
|
||||
|
||||
#### 报错:docker compose v2 not found, unable to deploy
|
||||
|
||||
需要安装 `docker compose v2`。尝试 `[Install Docker Compose](https://docs.docker.com/compose/install/)`。
|
||||
|
||||
#### 报错: `failed to create network safeline-ce`
|
||||
|
||||
safeline-ce 是雷池部署时候创建的 network,出现类似报错,先重启下 dockerd 之后重试。
|
||||
|
||||
#### 报错: safeline-tengine 出现 Address already in use
|
||||
|
||||
`docker logs -f safeline-tengine` 容器日志中看到 `Address already in use` 信息。
|
||||
|
||||
端口冲突,根据报错信息中的端口号,排查是哪个服务占用了,手动处理冲突。
|
||||
|
||||
#### 报错:safelint-mgt-api 出现 Operation not permitted
|
||||
|
||||
`docker logs -f safelint-mgt-api` 容器日志中看到 `runtime/cgo: pthread_create failed: Operation not permitted` 报错,这个错误一般会在 docker 20.10.9 及以下发生。
|
||||
|
||||
- 最推荐的方式是升级 docker 到最新版本尝试解决这个问题。
|
||||
- 或您的系统支持配置 seccomp (执行 `grep CONFIG_SECCOMP= /boot/config-$(uname -r)` 输出 `CONFIG_SECCOMP=y` 则为支持),
|
||||
则可以在雷池工作目录下载 [seccomp](https://waf-ce.chaitin.cn/release/latest/seccomp.json) 并且编辑 compose.yaml 文件,
|
||||
在 management 下加入如下配置项,然后执行 `docker compose down && docker compose up -d` 来尝试解决这个问题:
|
||||
|
||||
```yaml
|
||||
security_opt:
|
||||
- seccomp=./seccomp.json
|
||||
```
|
||||
|
||||
#### 报错:safeline-pg 出现 Operation not permitted
|
||||
|
||||
`docker logs -f safeline-pg` 容器日志中看到 `Operation not permitted` 报错。
|
||||
|
||||
可能是您的 docker 版本过低,升级 docker 到最新版本尝试一下。
|
||||
|
||||
#### 其他奇怪的报错比如:It does not belong to any of this network's subnets...等等
|
||||
|
||||
查看[如何卸载](#如何卸载) ,卸载以后重新安装一次
|
||||
|
||||
## 如何自定义 SafeLine 安装路径?
|
||||
|
||||
基于最新的 `compose.yaml`,你可以手动修改 `.env` 文件的 `SAFELINE_DIR` 变量。
|
||||
|
||||
## 雷池和业务服务可以部署到同一台机器中吗?
|
||||
|
||||
可以,但是不建议,机器负载将高于分开部署。
|
||||
|
||||
## MacOS/Windows 是否支持安装雷池
|
||||
|
||||
社区版暂不支持,如有需求咨询企业版。
|
||||
|
||||
## docker compose 还是 docker-compose?
|
||||
|
||||
属于两个版本,推荐使用 docker compose
|
||||
|
||||
参考资料:https://stackoverflow.com/questions/66514436/difference-between-docker-compose-and-docker-compose
|
||||
|
||||
## 如何修改 SafeLine 后台管理的默认端口?比如:本机 `:9443` 已经被别的服务占用
|
||||
|
||||
使用 `ss -antp|grep LISTEN` 确认端口使用情况,找到未被占用端口
|
||||
|
||||
修改在安装目录(默认 safeline)下的隐藏文件`.env` 文件,你可以手动添加 `MGT_PORT` 变量到 `.env` 文件。
|
||||
|
||||
文件修改后,需要等重启才会生效。
|
||||
|
||||
在安装目录(默认 safeline)下执行 `docker compose down && docker compose up -d`
|
||||
|
||||
## 如何卸载
|
||||
|
||||
在安装目录(默认 safeline)下
|
||||
|
||||
根据本地的compose版本,执行 `docker compose down` 或者 `docker-compose down`
|
||||
|
||||
|
||||
|
||||
## 问题无法解决
|
||||
|
||||
1. 通过右上角搜索检索其他页面
|
||||
|
||||
2. 通过社群(官网首页加入微信讨论组)寻求帮助或者 Github issue 提交反馈,并附上排查的过程和截图
|
52
documents/docs/03-faq/02-login.md
Normal file
|
@ -0,0 +1,52 @@
|
|||
---
|
||||
title: "登录问题"
|
||||
---
|
||||
|
||||
# 登录问题
|
||||
|
||||
记录常见的登录问题
|
||||
|
||||
## 动态口令错误
|
||||
|
||||
### 时间不一致
|
||||
|
||||
雷池社区版动态口令认证采用了 TOTP 算法,TOTP 与时间强相关,如果相关设备的时间不准,可能会导致动态口令计算错误。
|
||||
|
||||
1. 检查手机时间是否准确(或其他 TOTP 扫码设备),注意关注时区
|
||||
2. 检查雷池服务器时间是否准确
|
||||
|
||||
### 口令可能已失效
|
||||
|
||||
TOTP 动态口令只有 30 秒的有效期,如果认证失败,请在动态口令刷新后重新尝试。
|
||||
|
||||
### 其他情况
|
||||
|
||||
检测容器状态是否正常,使用命令重置口令后继续尝试
|
||||
|
||||
## 重新绑定动态口令
|
||||
|
||||
登录服务器,打开终端,执行以下命令即可重置动态口令
|
||||
|
||||
命令执行完成后打开雷池页面重新绑定即可。
|
||||
|
||||
```
|
||||
docker exec safeline-mgt resetadmin
|
||||
```
|
||||
|
||||
**注意:重置动态口令后要尽快完成绑定,别被其他人捷足先登了。**
|
||||
|
||||
## 多人使用
|
||||
|
||||
如果之前未保存绑定二维码,想多人使用雷池社区版,只需要以下 3 步:
|
||||
|
||||
1. 重置动态口令(参考 [重新绑定动态口令](#重新绑定动态口令))
|
||||
2. 进入登录页面,这时会自动跳转到 TOTP 绑定页面,保存 “绑定二维码”(注意,非 “认证二维码”)
|
||||
3. 将 “绑定二维码” 分享给其他人进行绑定(“绑定二维码” 无绑定次数限制,无时效限制)
|
||||
|
||||
**注意:保存的 “绑定二维码” 千万别泄漏,任何人得到以后都可以绑定并登录。**
|
||||
|
||||
## 问题无法解决
|
||||
|
||||
1. 通过右上角搜索检索其他页面
|
||||
|
||||
2. 通过社群(官网首页加入微信讨论组)寻求帮助或者 Github issue 提交反馈,并附上排查的过程和截图
|
120
documents/docs/03-faq/03-config.md
Normal file
|
@ -0,0 +1,120 @@
|
|||
---
|
||||
title: "配置问题"
|
||||
---
|
||||
|
||||
# 配置问题
|
||||
|
||||
记录常见的配置问题
|
||||
|
||||
## 配置后网站无法访问,排查思路
|
||||
|
||||
如果按照指引配置了站点,但配置的网站无法访问
|
||||
|
||||
梳理问题可能存在的几个原因:
|
||||
|
||||
1. 配置站点错误,ip 错误、端口冲突等
|
||||
|
||||
2. 雷池端与配置的站点网络不通
|
||||
|
||||
3. 访问雷池配置的站点端口网络不通,对于雷池端已配置的端口没有被开放访问(防火墙、安全组等)
|
||||
|
||||
4. 同时存在其他错误的配置可能会导致新的配置一直不生效,检查有没有存在其他错误的配置
|
||||
|
||||
5. 雷池本身的状态不正常,使用 docker ps 检查容器状态
|
||||
|
||||
## 排查步骤
|
||||
|
||||
1. 明确 “网站无法访问” 的具体表现:
|
||||
|
||||
- 如果 `502 Bad Gateway tengine`:
|
||||
|
||||
大概率是是雷池的上游服务器配置不正确,或者雷池无法访问到上游服务器,请继续按下面步骤排查。
|
||||
|
||||

|
||||
|
||||
- 如果请求能够返回但是十分缓慢
|
||||
|
||||
- 确认服务器负载是否正常,检查服务器的 CPU、内存、带宽使用情况
|
||||
|
||||
- 在客户端执行命令,检查雷池服务器与上游服务器的网络:`curl -H "Host: <雷池 IP>" -vv -o /dev/null -s -w 'time_namelookup: %{time_namelookup}\ntime_connect: %{time_connect}\ntime_starttransfer: %{time_starttransfer}\ntime_total: %{time_total}\n' http://<上游服务器地址>`
|
||||
|
||||
- 如果 time_namelookup 时间过大,请检查 dns server 配置
|
||||
- 如果 time_connect 时间过大,请检查雷池与上游服务器之间的网络状态
|
||||
- 如果 time_starttransfer 时间过大,请检查上游服务器状态,是否出现资源过载情况
|
||||
|
||||
- 如果不是以上情况,继续下一步
|
||||
|
||||
2. 在客户端执行 `curl -v -H "Host: <域名或者IP>" http://<雷池 IP>:<雷池监听端口>` 。如能获取到业务网站的响应,如图,并且站点的 “今日访问量” +1,说明雷池配置正确,网络正常
|
||||
|
||||

|
||||
|
||||
如果浏览器无法访问,但这一步正常获取到响应,大概率是因为:
|
||||
|
||||
- 网站域名还没有切到雷池,浏览器测试时访问的是 `http(s)://<雷池 IP>`,恰好业务服务上有 Host 验证,所以拒绝了该请求。这种情况需要修改本机 host,把域名解析到雷池 IP,再访问 `http(s)://<域名>`,才能准确测试
|
||||
- 网站业务做了其他一些特殊处理。例如访问后 301 跳转到了其他地址,需要具体排查网站业务的响应内容
|
||||
- 如果不能获取到响应,继续下一步
|
||||
|
||||
3. 在雷池设备上执行 `curl -v -H "Host: <域名或者IP>" http://<雷池 IP>:<雷池监听端口>`。如能获取到业务网站的响应,并且站点上 “今日访问量” +1,说明雷池配置正确
|
||||
|
||||
- 如果步骤 2 失败而这里成功,说明客户端到雷池之间的网络存在问题。请排查网络,保证客户端可访问到雷池,检测防火墙、端口开放等
|
||||
- 如果不能获取到响应,继续下一步
|
||||
|
||||
4. 在雷池设备上执行 `curl -H "Host: <域名或者IP>" http://127.0.0.1:<雷池监听端口>`。如能获取到业务网站的响应,并且站点的 “今日访问量” +1,说明雷池配置正确
|
||||
|
||||
- 如果步骤 3 失败而这里成功,且 `telnet <雷池 IP> <雷池监听端口>` 返回 `Unable to connect to remote host: Connection refused`,可能是被雷池设备上的防火墙拦截了。
|
||||
- 排查操作系统本身的防火墙,还有可能是云服务商的防火墙。请根据实际情况逐项排查,开放雷池监听端口的访问
|
||||
- 如果不能获取到响应,继续下一步
|
||||
|
||||
5. 在雷池设备上执行 `netstat -anp | grep <雷池监听端口>` 确认端口监听情况。正常情况下,应该有一个 nginx 进程监听在 `0.0.0.0:<雷池监听端口>`。
|
||||
|
||||
- 没有的话请通过社群或者 Github issue 提交反馈,附上排查过程。有的话继续下一步
|
||||
|
||||

|
||||
|
||||
6. 在雷池设备上 `curl -H "Host: <域名或者IP>" <上游服务器地址>`。如能获取到业务网站的响应,说明雷池设备和站点网络没有问题
|
||||
|
||||

|
||||
|
||||
- 如果步骤 4 失败而这里成功,可能是配置错误,查看配置站点教程确认配置是否正确,如无法解决,请通过社群或者 Github issue 提交反馈,附上排查过程
|
||||
|
||||
- 如果这步失败,说明雷池和上游服务器之间的网络存在问题。请排查网络,确保雷池可以访问到上游服务器
|
||||
|
||||
## 配置完成后,测试时返回 400 Request Header Or Cookie Too Large
|
||||
|
||||
请麻烦检查是否形成了环路,即:雷池将请求转发给上游服务器后,上游服务器又将请求转发回雷池。
|
||||
|
||||
## 不同版本关闭防火墙的命令
|
||||
|
||||
Ubuntu 18.04 LTS 、 Ubuntu 20.04 LTS 、 Ubuntu 22.04 LTS
|
||||
|
||||
Debian 9 (Stretch)、Debian 10 (Buster)、Debian 11 (Bullseye)
|
||||
```
|
||||
关闭防火墙命令(UFW):sudo ufw disable
|
||||
注:Debian 默认可能不安装 UFW,依赖于 iptables。
|
||||
```
|
||||
|
||||
CentOS 7、CentOS 8、RHEL 7、 RHEL 8、Fedora 32、 Fedora 33、Fedora 34
|
||||
```
|
||||
关闭防火墙命令(Firewalld):sudo systemctl stop firewalld && sudo systemctl disable firewalld
|
||||
```
|
||||
openSUSE Leap 15.2、openSUSE Leap 15.3
|
||||
```
|
||||
关闭防火墙命令(通常是 SuSEfirewall2 或 firewalld):
|
||||
1.SuSEfirewall2, 使用 sudo SuSEfirewall2 stop
|
||||
2.firewalld, 使用 sudo systemctl stop firewalld && sudo systemctl disable firewalld
|
||||
```
|
||||
|
||||
## 如何对站点开启强制https访问、开启IPV6监听、使用HTTP/2
|
||||
|
||||
根据站点需求开启
|
||||
|
||||
开启路径:防护配置-通用配置-其他-站点通用配置
|
||||
|
||||

|
||||
|
||||
|
||||
## 问题无法解决
|
||||
|
||||
1. 通过右上角搜索检索其他页面
|
||||
|
||||
2. 通过社群(官网首页加入微信讨论组)寻求帮助或者 Github issue 提交反馈,并附上排查的过程和截图
|
52
documents/docs/03-faq/04-test.md
Normal file
|
@ -0,0 +1,52 @@
|
|||
---
|
||||
title: "防护问题"
|
||||
---
|
||||
|
||||
# 防护问题
|
||||
|
||||
记录常见的防护问题
|
||||
|
||||
## 攻击测试时未记录攻击,并且访问记录为 0
|
||||
|
||||
检查是否直接访问了源站,没有走雷池的配置站点访问
|
||||
|
||||
## 内网用户如何使用在线的威胁情报 IP?加白哪个域名?
|
||||
|
||||
威胁情报的云服务部署在百川云平台,域名是 **`https://challenge.rivers.chaitin.cn/`**
|
||||
|
||||
雷池部署在内网的师傅需要加白一下,就可以正常同步情报数据了。
|
||||
|
||||
## 如何记录所有访问雷池的请求 (如何开启访问日志)
|
||||
|
||||
默认情况下雷池是并不会保存请求记录的,如果需要保存请求记录,可以修改waf的安装目录下的**resources/nginx/nginx.conf**
|
||||
|
||||

|
||||
|
||||
如图所示,去掉文件第 98 行的注释,删除第 99 行的内容,保存后运行命令检查配置文件
|
||||
|
||||
```shell
|
||||
docker exec safeline-tengine nginx -t
|
||||
```
|
||||
|
||||
检查应显示
|
||||
|
||||
```shell
|
||||
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
|
||||
nginx: configuration file /etc/nginx/nginx.conf test is successful
|
||||
```
|
||||
|
||||
最后应用配置文件
|
||||
|
||||
```shell
|
||||
docker exec safeline-tengine nginx -s reload
|
||||
```
|
||||
|
||||
配置生效后,访问日志将会保存至安装路径下的**logs/nginx**
|
||||
|
||||
**_注意:该操作会加快对硬盘的消耗,请定时清理访问日志_**
|
||||
|
||||
## 问题无法解决
|
||||
|
||||
1. 通过右上角搜索检索其他页面
|
||||
|
||||
2. 通过社群(官网首页加入微信讨论组)寻求帮助或者 Github issue 提交反馈,并附上排查的过程和截图
|
51
documents/docs/03-faq/05-upgrade.md
Normal file
|
@ -0,0 +1,51 @@
|
|||
---
|
||||
title: "升级问题"
|
||||
---
|
||||
|
||||
# 升级问题
|
||||
|
||||
记录常见的升级问题
|
||||
|
||||
## 默认账号密码
|
||||
|
||||
雷池社区版5.0.0以后的版本都有一个默认的账户密码
|
||||
|
||||
正常情况升级时shell会自动输出新密码
|
||||
|
||||
若非在线升级,需手生重置获得初始密码
|
||||
|
||||
重置密码命令:`docker exec safeline-mgt resetadmin`
|
||||
|
||||
初始密码是随机的,需要修改可以进入【通用配置-其他-雷池控制台登录设置】设置新的密码
|
||||
|
||||
## 升级提示目录不对
|
||||
|
||||
在错误的目录下执行(比如 safeline 的子目录)会导致无法升级成功。
|
||||
|
||||
切换目录到安装目录下再次执行升级,默认目录为:/data/safeline。
|
||||
|
||||
## 配置的备份与恢复(还原)
|
||||
|
||||
升级过程担心配置受到影响
|
||||
|
||||
备份:备份安装目录的全部文件,默认目录为:/data/safeline
|
||||
|
||||
恢复(还原):把备份的内容放回安装目录执行 `docker compose down && docker compose up -d`,重新启动雷池
|
||||
|
||||
## 升级过程中下载超时
|
||||
|
||||
网络问题导致,建议等待网络稳定或者尝试离线升级。
|
||||
|
||||
## 升级后系统信息显示 api 错误或者 docker 状态显示异常
|
||||
|
||||
重启 docker
|
||||
|
||||
## 升级后原配置不生效
|
||||
|
||||
极少数情况出现,一般删掉重新配置即可
|
||||
|
||||
## 问题无法解决
|
||||
|
||||
1. 通过右上角搜索检索其他页面
|
||||
|
||||
2. 通过社群(官网首页加入微信讨论组)寻求帮助或者 Github issue 提交反馈,并附上排查的过程和截图
|
205
documents/docs/03-faq/06-other.md
Normal file
|
@ -0,0 +1,205 @@
|
|||
---
|
||||
title: "其他问题"
|
||||
---
|
||||
|
||||
# 其他问题
|
||||
|
||||
记录不常见的其他问题
|
||||
|
||||
## 雷池获得的请求者的源IP 显示不正确
|
||||
|
||||
雷池默认会通过 Socket 连接获取请求者的源 IP,如果请求在到达雷池之前,还经过了其他代理设备(如:反代、LB、CDN、AD 等),这种情况会影响雷池获取正确的源 IP 信息。
|
||||
|
||||
通常,代理设备都会将真实源 IP 通过 HTTP Header 的方式传递给下一跳设备。
|
||||
|
||||
如下方的 HTTP 请求,在 `X-Forwarded-For` 和 `X-Real-IP` 两个 Header 中都包含了源 IP:
|
||||
|
||||
```
|
||||
GET /path HTTP/1.1
|
||||
Host: waf-ce.chaitin.cn
|
||||
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
|
||||
X-Forwarded-For: 110.123.66.233, 10.10.3.15
|
||||
X-Real-IP: 110.123.66.233
|
||||
```
|
||||
|
||||
> `X-Forwarded-For` 是链式结构,若请求经过了多级代理,这里将会按顺序记录每一跳的客户端 IP。
|
||||
|
||||
如果请求中没有包含存在源 IP 的相关 Header,可以通过修改前方代理设备的配置来解决。例如,Nginx 可以增加如下配置来传递 `X-Real-IP` 给后方设备:
|
||||
|
||||
```
|
||||
location /xxx {
|
||||
proxy_pass http://xxx.xxx;
|
||||
...
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
遇到这种情况,打开雷池控制台的 “通用配置” 页面,将选项 “源 IP 获取方式” 的内容修改为 “从 HTTP Header 中获取”,并在对应的输入框中填入 `X-Real-IP` 即可。
|
||||
|
||||

|
||||
|
||||
|
||||
## 上游服务器获得请求者的源IP 显示不正确
|
||||
|
||||
有可能上游服务器获取到的全都是雷池 WAF 的 IP,如何获取真是的请求者源IP?
|
||||
|
||||
雷池默认透传了源 IP,放在 HTTP Header 中的 `X-Forwarded-For` 里面。
|
||||
|
||||
如果上游服务器是 NGINX,添加如下配置就可以。如果不是,需要自行配置解析 XFF
|
||||
|
||||
```
|
||||
set_real_ip_from 0.0.0.0/0;
|
||||
real_ip_header X-Forwarded-For;
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 清理数据库中的统计信息和检测日志
|
||||
|
||||
**_注意:该操作会清除所有日志信息,且不可恢复_**
|
||||
|
||||
```shell
|
||||
docker exec safeline-mgt cleanlogs
|
||||
```
|
||||
|
||||
## 将雷池的日志导出到 XXX
|
||||
|
||||
雷池社区版自发布以来经常有用户询问如何将拦截日志通过 syslog 转发至目标地址,接下来我们将尝试使用 `fluentd` 来实现这个需求。
|
||||
|
||||
首先,我们编写 `fluent.conf`,我们将读取 `mgt_detect_log_basic` 中的数据,并通过配置 syslog 转发出去。下面是 input 部分,match 部分可以参考参考文档中的 syslog 部分。
|
||||
|
||||
```
|
||||
<source>
|
||||
@type sql
|
||||
|
||||
host safeline-pg // 默认数据库地址,如果在 compose.yml 中改过,请使用改后值
|
||||
port 5432
|
||||
database safeline-ce // 数据库名
|
||||
adapter postgresql
|
||||
username safeline-ce // 默认用户名,如果在 compose.yml 中改过,请使用改后值
|
||||
password POSTGRES_PASSWORD // 数据库密码,见安装目录下 .env
|
||||
|
||||
select_interval 60s # optional
|
||||
select_limit 500 # optional
|
||||
|
||||
state_file /var/run/fluentd/sql_state
|
||||
|
||||
<table>
|
||||
table mgt_detect_log_basic
|
||||
update_column timestamp
|
||||
time_column timestamp # optional
|
||||
</table>
|
||||
|
||||
# detects all tables instead of <table> sections
|
||||
#all_tables
|
||||
</source>
|
||||
```
|
||||
|
||||
之后,来编写我们的 fluentd 的 Dockerfile
|
||||
|
||||
```
|
||||
FROM fluent/fluentd:v1.16-1
|
||||
|
||||
# Use root account to use apk
|
||||
USER root
|
||||
|
||||
# below RUN includes plugin as examples elasticsearch is not required
|
||||
# you may customize including plugins as you wish
|
||||
RUN apk add --no-cache --update --virtual .build-deps \
|
||||
sudo build-base ruby-dev \
|
||||
&& apk add libpq-dev \
|
||||
&& sudo gem install pg --no-document \
|
||||
&& sudo gem install fluent-plugin-remote_syslog \
|
||||
&& sudo gem sources --clear-all \
|
||||
&& apk del .build-deps libpq-dev \
|
||||
&& rm -rf /tmp/* /var/tmp/* /usr/lib/ruby/gems/*/cache/*.gem
|
||||
|
||||
COPY fluent.conf /fluentd/etc/fluent.conf
|
||||
|
||||
USER fluent
|
||||
```
|
||||
|
||||
最后,编译完成后,我们将容器跑起来,参考命令
|
||||
|
||||
```
|
||||
echo "" > ./sql-state
|
||||
docker run -d --restart=always --name safeline-fluentd --net safeline-ce -v ./sql-state:/var/run/fluentd/sql_state safeline-flunetd:latest
|
||||
```
|
||||
|
||||
参考文档
|
||||
[SQL input plugin for Fluentd event collector](https://github.com/fluent/fluent-plugin-sql)
|
||||
[fluent-plugin-remote_syslog](https://github.com/fluent-plugins-nursery/fluent-plugin-remote_syslog)
|
||||
|
||||
## 有多个防护站点监听在同一个端口上,匹配顺序是怎么样的
|
||||
|
||||
如果域名处填写的分别为 IP 与域名,那么当使用进行 IP 请求时,则将会命中第一个配置的站点
|
||||

|
||||
以上图为例,如果用户使用 IP 访问,命中 example.com。
|
||||
|
||||
如果域名处填写的分别为域名与泛域名,除非准确命中域名,否则会命中泛域名,不论泛域名第几个配置。
|
||||

|
||||
以上图为例,如果用户使用 a.example.com 访问,命中 a.example.com。 如果用户使用 b.example.com,命中 \*.example.com。
|
||||
|
||||
## 自定义站点 nginx conf
|
||||
|
||||
雷池每次修改站点或者重启服务时,都会在waf的安装目录下的**resources/nginx/sites-enabled/**重新生成 nginx conf 文件。因为没法“智能”合并用户自定义的配置和自动生成的配置。但是也还是有方式能持久化地添加一些 nginx conf,不会被覆盖。
|
||||
|
||||
每个 `IF_backend_XXX` 的 location 中都有 `include proxy_params;` 这一行配置,且 `resources/nginx/proxy_params` 这个文件不会被修改站点、重启服务等动作覆盖。2.1.0 版本之后支持 `include custom_params/backend_XXX;` 可以自定义站点级的 nginx location 配置。
|
||||
|
||||
```shell
|
||||
server {
|
||||
location ^~ / {
|
||||
proxy_pass http://backend_1;
|
||||
include proxy_params;
|
||||
include custom_params/IF_backend_1;
|
||||
# ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
所以只需要根据需求修改对应的文件就可以了。比如在 `resources/nginx/proxy_params` 里面增加如下配置,即可支持 `X-Forwarded-Proto`:
|
||||
|
||||
```shell
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
```
|
||||
|
||||
修改完成后运行命令检查配置文件
|
||||
|
||||
```shell
|
||||
docker exec safeline-tengine nginx -t
|
||||
```
|
||||
|
||||
检查应显示
|
||||
|
||||
```shell
|
||||
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
|
||||
nginx: configuration file /etc/nginx/nginx.conf test is successful
|
||||
```
|
||||
|
||||
最后应用配置文件
|
||||
|
||||
```shell
|
||||
docker exec safeline-tengine nginx -s reload
|
||||
```
|
||||
|
||||
## 攻击日志中的域名不是我的网站
|
||||
|
||||
攻击日志中显示的域名字段是取的 HTTP Header 中的 Host,如果这个字段不存在,则默认使用目的 IP 作为域名。如果客户端修改了 HTTP Header 的 Host,那么这里显示的就是修改之后的。
|
||||
|
||||
放一张截图更容易理解,注意下面「请求报文」中的 Host 字段:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## 是否支持 WebSocket ?
|
||||
|
||||
默认支持
|
||||
|
||||
|
||||
## 问题无法解决
|
||||
|
||||
1. 通过右上角搜索检索其他页面
|
||||
|
||||
2. 通过社群(官网首页加入微信讨论组)寻求帮助或者 Github issue 提交反馈,并附上排查的过程和截图
|
7
documents/docs/03-faq/_category_.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"label": "常见问题排查",
|
||||
"collapsed": false,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
}
|
||||
}
|
30
documents/docs/04-practice/00-monitor.md
Normal file
|
@ -0,0 +1,30 @@
|
|||
---
|
||||
title: "百川网站监控"
|
||||
---
|
||||
|
||||
# 百川网站监控
|
||||
|
||||
安装雷池社区版,领取长亭网站监控产品 100 元体验金
|
||||
|
||||
## 关于网站监控
|
||||
|
||||
### 什么是网站监控
|
||||
|
||||
**除了对网站的安全防护以外,不少站长还对网站的可用性、稳定性健康监测和敏感内容监测也有强烈需求。**
|
||||
|
||||
[长亭百川网站监测](https://rivers.chaitin.cn/landing/radar) 是一款优秀的网站监测工具,能够有效监测站点可用性、SSL 证书合法性、网站敏感内容等信息。
|
||||
|
||||
交互界面简洁直观、操作上手轻松,实时监测每个页面的状态和详细信息,让你对网站运行状态了如指掌。
|
||||
|
||||

|
||||
|
||||
### 领取方式
|
||||
|
||||
1. 安装雷池社区版,查看雷池设备码
|
||||
|
||||
2. 登录网站监测,在网站监测页输入雷池设备码,地址:[长亭百川网站监测](https://rivers.chaitin.cn/landing/radar)
|
||||
|
||||

|
||||
|
||||

|
||||
|
9
documents/docs/04-practice/01-effect.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
title: "WAF检测效果对比"
|
||||
---
|
||||
|
||||
# WAF检测效果对比
|
||||
|
||||
雷池社区版与其他 WAF 的检测能力对比
|
||||
|
||||

|
32
documents/docs/04-practice/02-IpIntelligence.md
Normal file
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
title: "免费黑 IP 情报源"
|
||||
---
|
||||
|
||||
# 免费黑 IP 情报源
|
||||
|
||||
长亭免费开放 WAF 黑 IP 情报源
|
||||
|
||||
## IP 情报赋能 WAF
|
||||
|
||||
在过去的几年,各种大小重保活动期间,总会看到甲方的安全工程师们会拉一个群,用于共享攻击源 IP,这些 IP 也是重保防护能力的重要支撑。
|
||||
|
||||
威胁情报对于 Web 攻击防护的作用毋庸置疑,可以精准识别 Bot、C2、VPN、僵尸网络,对于防 0Day 攻击、防自动化攻击、降低误报漏报等方面都有着非常不错的效果。
|
||||
|
||||
## 情报从哪来
|
||||
|
||||
安装雷池社区版后,若选择 “加入 IP 情报共享计划”,雷池将定时自动聚合攻击 IP 数据(只有攻击 IP,不涉及任何敏感信息)发送到长亭百川云平台。
|
||||
|
||||
长亭百川云平台收到来自五湖四海的社区版兄弟们共享的 IP 情报,使用算法进行汇总和优选,生成雷池社区黑 IP 库,最终再回馈给社区。
|
||||
|
||||
### 使用方式
|
||||
|
||||
1. 在 “通用配置” 页面选择 “加入 IP 情报共享计划”:
|
||||

|
||||
|
||||
2. IP 组页面中将会出现 “长亭社区恶意 IP 情报”:
|
||||

|
||||
|
||||
3. 在 “黑白名单” 页面增加黑名单规则,条件设置为对应的 IP 组:
|
||||

|
||||
|
||||
4. 坐等 IP 情报拦截。
|
161
documents/docs/04-practice/03-apisix.md
Normal file
|
@ -0,0 +1,161 @@
|
|||
---
|
||||
title: "APISIX 联动雷池"
|
||||
---
|
||||
|
||||
# APISIX 联动雷池
|
||||
|
||||
Apache APISIX 是一个动态、实时、高性能的云原生 API 网关,提供了负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。
|
||||
|
||||
雷池是由长亭科技开发的 WAF 系统,提供对 HTTP 请求的安全请求,提供完整的 API 管理和防护能力。
|
||||
|
||||
自 APISIX 3.5.0 之后的版本将内置长亭雷池 WAF 插件,在启用 chaitin-waf 插件后,流量将被转发给长亭 WAF 服务,用以检测和防止各种 Web 应用程序攻击,以保护应用程序和用户数据的安全。
|
||||
|
||||
## 开源仓库
|
||||
|
||||
apisix:https://github.com/apache/apisix
|
||||
|
||||
## 使用方式
|
||||
|
||||
### 安装 APISIX
|
||||
|
||||
> 注意,要使用 APISIX 3.5.0 及以上版本
|
||||
|
||||
本文使用 apisix 的 docker 版本来做演示,克隆 apisix-docker 仓库,运行以下命令来安装:
|
||||
|
||||
```
|
||||
git clone <https://github.com/apache/apisix-docker>
|
||||
cd apisix-docker/compose
|
||||
echo 'APISIX_DOCKER_TAG=3.5.0-debian' >> .env
|
||||
docker compose -f docker-compose-release.yaml up -d
|
||||
```
|
||||
|
||||
业务地址:http://127.0.0.1:9080/
|
||||
|
||||
管理地址:http://127.0.0.1:9180/
|
||||
|
||||
### 安装雷池
|
||||
|
||||
使用雷池官方提供的一句话安装命令即可:
|
||||
|
||||
```
|
||||
bash -c "$(curl -fsSLk <https://waf-ce.chaitin.cn/release/latest/setup.sh>)"
|
||||
```
|
||||
|
||||
不出意外的话,一路回车就能安装成功。
|
||||
|
||||
安装目录:/data/safeline/
|
||||
|
||||
### 修改雷池检测引擎的工作模式
|
||||
|
||||
社区版雷池的检测引擎默认以 unix socket 的方式提供服务,我们需要把他修改为 tcp 方式,供 APISIX 调用。
|
||||
|
||||
进入雷池检测引擎的配置目录:
|
||||
|
||||
```
|
||||
cd /data/safeline/resources/detector/
|
||||
```
|
||||
|
||||
用文本编辑器打开目录里的 detector.yml 文件,我们需要将 bind 方式从 unix socket 改为 tcp,添加如下配置:
|
||||
|
||||
```
|
||||
bind_addr: 0.0.0.0
|
||||
listen_port: 8000
|
||||
```
|
||||
|
||||
detector配置的属性值将覆盖容器内默认配置文件的同名属性值。这样我们就把雷池引擎的服务监听到了 8000 端口,现在只需要把容器内的 8000 端口映射到宿主机即可。
|
||||
|
||||
进入雷池的安装目录
|
||||
|
||||
> cd /data/safeline/
|
||||
> 用文本编辑器打开目录里的 compose.yaml 文件,为 detector 容器增加 ports 字段,暴露其 8000
|
||||
|
||||
端口,参考如下:
|
||||
|
||||
```
|
||||
......
|
||||
|
||||
detector:
|
||||
......
|
||||
ports:
|
||||
- 8000:8000
|
||||
|
||||
......
|
||||
```
|
||||
|
||||
OK,改好了,在雷池安装目录下执行以下命令重启雷池即可生效。
|
||||
|
||||
```
|
||||
docker compose down
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### 修改雷池的默认端口
|
||||
|
||||
雷池和 apisix 默认都监听 9443 端口,如果在同一台机器上安装,需要修改雷池的默认端口。
|
||||
|
||||
在雷池的安装目录下,有一个名为 .env 的隐藏文件,其中的 MGT_PORT 字段,修改这里后使用上面的方法再重启雷池即可生效。
|
||||
|
||||
### 在 apisix 里绑定雷池
|
||||
|
||||
调用 apisix 的 api,设置雷池检测引擎的地址,供 apisix 调用,参考以下请求:
|
||||
|
||||
192.168.99.11 是我本地雷池的地址,替换为你的 IP 即可
|
||||
|
||||
```
|
||||
curl <http://127.0.0.1:9180/apisix/admin/plugin_metadata/chaitin-waf> -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"nodes":[
|
||||
{
|
||||
"host": "192.168.99.11",
|
||||
"port": 8000
|
||||
}
|
||||
]
|
||||
}'
|
||||
```
|
||||
|
||||
调用 apisix 的 api,设置一条路由,参考以下请求:
|
||||
|
||||
> 192.168.99.12:80 是上游服务器的地址,apisix 会将请求反向代理到这个地址。
|
||||
|
||||
```
|
||||
curl <http://127.0.0.1:9180/apisix/admin/routes/1> -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
|
||||
{
|
||||
"uri": "/*",
|
||||
"plugins": {
|
||||
"chaitin-waf": {}
|
||||
},
|
||||
"upstream": {
|
||||
"type": "roundrobin",
|
||||
"nodes": {
|
||||
"192.168.99.12:80": 1
|
||||
}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
### 测试防护效果
|
||||
|
||||
经过以上步骤,雷池 + apisix 基本配置完成,可以试试效果了,请求 9080 端口,可以看到 apisix 成功代理了上游服务器的页面:
|
||||
|
||||
```sh
|
||||
curl '<http://127.0.0.1:9080/>'
|
||||
```
|
||||
|
||||
在请求中加入一个 a 参数,模拟 SQL 注入攻击:
|
||||
|
||||
```sh
|
||||
curl '<http://127.0.0.1:9080/>' -d 'a=1 and 1=1'
|
||||
```
|
||||
|
||||
返回了 HTTP 403 错误,从错误消息中可以看出,雷池成功抵御了此次攻击。
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 403,
|
||||
"success": false,
|
||||
"message": "blocked by Chaitin SafeLine Web Application Firewall",
|
||||
"event_id": "18e0f220f7a94127acb21ad3c1b4ac47"
|
||||
}
|
||||
```
|
||||
|
||||
打开雷池的控制台界面,可以看到雷池记录了完整的攻击信息
|
58
documents/docs/04-practice/04-safeline-cloud.md
Normal file
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
title: "雷池云托管"
|
||||
---
|
||||
|
||||
# 雷池云托管
|
||||
|
||||
雷池云托管是长亭融合牧云主机助手的技术,专门为雷池社区用户打造的托管工具,帮你解放双手,像放羊一样管理雷池服务器。
|
||||
|
||||
雷池云托管使用地址:https://rivers.chaitin.cn/?share=85db8d21d63711ee91390242c0a8176b
|
||||
|
||||
主机助手的文档地址:https://rivers.chaitin.cn/docs/zh/cloudwalker
|
||||
|
||||
|
||||
|
||||
## 产品简介
|
||||
|
||||
### 系统信息
|
||||
|
||||
#### 展示当前系统信息
|
||||
|
||||
安装完成后页面会显示当前雷池服务器的基本信息。
|
||||
|
||||
包括雷池社区版的版本、机器码等信息
|
||||
|
||||
#### 快捷升级专业版
|
||||
|
||||
安装云托管的雷池服务器,购买授权后,支持一键升级专业版。
|
||||
|
||||

|
||||
|
||||
|
||||
### 资源监控
|
||||
|
||||
#### 实时监控
|
||||
实时监控CPU,内存,网络,磁盘使用情况,并可以查看7天历史监控。
|
||||
|
||||

|
||||
|
||||
#### 查看历史
|
||||
|
||||
在“资源负载”页面点击“历史”按钮,进入资源占用的历史页面。历史记录可以选择起始日期,起始时间,历史记录时长。
|
||||
|
||||

|
||||
|
||||
### 在线终端
|
||||
|
||||
类似于牧云主机助手,云托管的设备也支持免密登录服务器终端。
|
||||
|
||||
### 使用在线终端
|
||||
|
||||
在“详情”页面点击“在线终端”图标按钮,进入终端界面。
|
||||
|
||||

|
||||
|
||||

|
||||
### 其他
|
||||
|
||||
未来雷池云托管将会增加更多功能,敬请期待
|
7
documents/docs/04-practice/_category_.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"label": "最佳实践",
|
||||
"collapsed": false,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
}
|
||||
}
|
BIN
documents/docs/04-practice/sample-screenshot.png
Normal file
After Width: | Height: | Size: 158 KiB |
943
documents/docs/05-about/00-changelog.md
Normal file
|
@ -0,0 +1,943 @@
|
|||
---
|
||||
title: "版本更新记录"
|
||||
---
|
||||
|
||||
# 版本更新记录
|
||||
|
||||
[版本升级方法](/guide/upgrade)
|
||||
|
||||
### [5.2.0] - 2024-03-28
|
||||
|
||||
#### 新增
|
||||
|
||||
* 黑白名单、人机验证、身份认证中,规则匹配条件增加 “Method”(请求方法),方便对 POST、PUT、DELETE 等客户端操作进行限制
|
||||
* 攻击原始日志的防护模块为 “补充规则” 时,“命中规则” 处增加规则的 ID
|
||||
|
||||
#### 优化
|
||||
|
||||
* 优化导航,调整功能位置,方便寻找:
|
||||
* 证书管理 移动到 防护站点->证书管理
|
||||
* IP 组 移动到 防护配置->通用配置->IP 组
|
||||
* 源 IP 获取方式、站点通用配置 移动到 防护站点->代理设置
|
||||
* 拦截页面附加说明、自定义拦截页面、IP 情报共享计划 移动到 防护配置->通用配置->拦截页面、IP 情报共享计划
|
||||
* 雷池控制台登录设置、雷池控制台证书、Syslog 设置、系统信息 移动到一级导航 系统设置
|
||||
* 密码登录框增加请求频率限制,提高暴力猜解的难度
|
||||
* 免费证书由过期前 10 天自动续期,改为过期前 30 天就自动续期
|
||||
* 修复站点数量较多时,站点管理处采集不到资源的问题
|
||||
* 修复移动端点击登录页的 “忘记密码” 无法弹出重置命令的问题
|
||||
* 修复 syslog 因请求内容较多被截断时,json 格式会被截得不合法的问题
|
||||
* 修复其他一些已知问题
|
||||
* 优化一些 UI 交互细节
|
||||
|
||||
### [5.1.0] - 2024-03-21
|
||||
|
||||
#### 新增
|
||||
|
||||
- 专业版支持 syslog 转发攻击日志到外部服务器。
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复某些情况下站点资源批量删除失败的问题。
|
||||
- 修复身份认证中配置 ip 组规则时功能异常的问题。
|
||||
- 修复某些攻击日志不显示地址位置的问题。
|
||||
- 修复页面缓存导致显示错误的问题。
|
||||
- 修复其他一些已知问题。
|
||||
|
||||
### [5.0.0] - 2024-03-14
|
||||
|
||||
#### 新增
|
||||
|
||||
- 社区版支持密码登录。系统登录方式改为 密码+可选开启二步验证:
|
||||

|
||||
|
||||
- 专业版
|
||||
- 支持添加多个用户
|
||||
- 支持导出攻击日志为 .csv 文件
|
||||
- 站点的负载均衡支持 IP Hash 算法、最小连接数算法
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复 luigi 容器有时负载过高降不下来的问题
|
||||
- 修复其他一些已知问题
|
||||
|
||||
### [4.4.2] - 2024-03-09
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复 FVM 服务在某些情况下 TCP 连接异常升高的问题
|
||||
|
||||
### [4.4.1] - 2024-03-07
|
||||
|
||||
#### 优化
|
||||
|
||||
- 专业版支持在明亮主题和黑金主题之间切换
|
||||
- 优化人机验证([#693](https://github.com/chaitin/SafeLine/issues/693),云端更新,历史版本也生效)
|
||||
- 降低旋转图片的误差要求
|
||||
- 图片不容易对齐时,支持刷新图片
|
||||
- 修复一些低版本浏览器转不动图片的问题
|
||||
- 删除某些特别难对齐的图片
|
||||
- 优化一些界面 UI 和交互细节
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复防护配置某些极端情况下会失效的问题
|
||||
- 修复向 luigi 发大量日志后,CPU 占用畸高不下的问题
|
||||
- 修复升级或重启后限频可能失效,直到修改任意防护配置的问题
|
||||
- 修复站点选择证书后再直接关闭 SSL,证书管理处 “使用站点”
|
||||
仍然显示该站点的问题([#656](https://github.com/chaitin/SafeLine/issues/656))
|
||||
- 修复攻击事件页面中,允许把 IP 加入至内置 IP 组的问题
|
||||
- 修复其他一些已知问题
|
||||
|
||||
### [4.4.0] - 2024-02-29
|
||||
|
||||
#### 新增
|
||||
|
||||
- 支持升级至专业版,包含内容:
|
||||
- 自定义拦截页面
|
||||
- 商用地理位置库
|
||||
- 额外补充规则
|
||||
- 节点负载均衡
|
||||
- 专属黑金主题
|
||||
|
||||
#### 优化
|
||||
|
||||
- 大幅优化频率限制的即时性,解决限频延迟时间过长的问题
|
||||
|
||||
### [4.3.3] - 2024-02-22
|
||||
|
||||
#### 优化
|
||||
|
||||
- 人机验证拦截页面,增加 Content-Security-Policy
|
||||
策略配置,加强安全性 ([#685](https://github.com/chaitin/SafeLine/issues/685))
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复左侧菜单滚动条样式错误的问题
|
||||
|
||||
### [4.3.2] - 2024-02-06
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复“内置规则”服务 IP 地址无法访问的问题,使用容器名称代替固定 IP
|
||||
|
||||
### [4.3.1] - 2024-02-05
|
||||
|
||||
#### 优化
|
||||
|
||||
- 修改日志详情接口地址,避免被浏览器插件误拦
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复日志详情中,“补充规则” 的防护模块名字未正确显示的问题
|
||||
- 修复有时候添加 http 站点后,站点会错误地显示到 证书管理->使用站点
|
||||
处的问题([#656](https://github.com/chaitin/SafeLine/issues/656))
|
||||
|
||||
### [4.3.0] - 2024-02-02
|
||||
|
||||
#### 新增
|
||||
|
||||
- 新增 防护配置 - 身份认证,可以给防护的网站加上用户名密码验证:
|
||||
|
||||

|
||||
|
||||
- 新增智能 AI 请求分析。在 攻击事件 - 原始日志 - 日志详情 中,点击 “智能 AI 攻击分析”,就可以分析该请求的攻击特征和原理了:
|
||||
|
||||

|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化英文模式下中国省份的显示([#512](https://github.com/chaitin/SafeLine/issues/512))
|
||||
- 优化站点的域名验证逻辑。当客户端发送了域名不正确的请求时,除了普通流量会被雷池直接拒绝之外,现在攻击流量也会被直接拒绝,不会返回拦截信息并记录日志了
|
||||
- 优化一些界面交互和 UI 细节
|
||||
|
||||
### [4.2.1] - 2024-01-19
|
||||
|
||||
#### 新增
|
||||
|
||||
- 点击右上角可领取 2023 专属年度报告:
|
||||

|
||||
- 新增补充规则,可以一览系统当前的通用漏洞规则:
|
||||

|
||||
- 黑白名单、人机验证新增匹配方式,包括:
|
||||
- IP 不等于
|
||||
- Host 不等于
|
||||
- Header 某个参数的内容不等于、包含、不包含
|
||||
|
||||
#### 优化
|
||||
|
||||
- 代理时开启
|
||||
SNI,避免访问上游服务时无法获取正确的证书 ([#491](https://github.com/chaitin/SafeLine/issues/491)、[#609](https://github.com/chaitin/SafeLine/issues/609))
|
||||
- 当尝试在同一端口同时监听 http 和 https 时,给出更具体的错误提示
|
||||
- 优化英文英文模式下中国省份的显示([#512](https://github.com/chaitin/SafeLine/issues/512))
|
||||
- 优化英文模式下攻击事件页 tab 按钮的对齐([#604](https://github.com/chaitin/SafeLine/issues/604))
|
||||
- 优化英文模式下威胁情报同步成功的提示信息 ([#605](https://github.com/chaitin/SafeLine/issues/605))
|
||||
- 优化删除 IP 组确认的提示信息([#610](https://github.com/chaitin/SafeLine/issues/610))
|
||||
- 优化 “刚果(金)”和 “刚果(布)” 的地区名称([#620](https://github.com/chaitin/SafeLine/issues/620))
|
||||
- 更新底层检测引擎版本,提高防护能力
|
||||
- 修复创建订阅的 IP 组时,有时无法保存的问题
|
||||
- 修复订阅的 IP 组存在行内注释时,对应的 IP 会失效的问题
|
||||
|
||||
### [4.1.1] - 2024-01-11
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复 IP 组在线订阅失败时会保存错误内容的问题
|
||||
|
||||
### [4.1.0] - 2024-01-11
|
||||
|
||||
#### 新增
|
||||
|
||||
- 拦截日志一键复制为 cURL ([#531](https://github.com/chaitin/SafeLine/issues/531))
|
||||
|
||||
#### 优化
|
||||
|
||||
- IP 组若为在线订阅,显示更新时间([#574](https://github.com/chaitin/SafeLine/issues/574))
|
||||
- 优化 safeline-fvm 容器重启速度,重启时间减少 10s
|
||||
- 优化 safeline-mgt 容器镜像层数,从 39 层下降到 24 层
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复日志列表 IP 来源地区未翻译国家编号的问题([#578](https://github.com/chaitin/SafeLine/issues/578))
|
||||
- 修复英文翻译问题([#591](https://github.com/chaitin/SafeLine/issues/591))
|
||||
- 修复雷池管理后台证书更新后未自动重启问题
|
||||
|
||||
### [4.0.2] - 2024-01-06
|
||||
|
||||
#### 修复
|
||||
|
||||
- 管理后台 mgt 启动时提示证书异常
|
||||
- 统计页面中 QPS 数据统计方法由窗口时间(5s)改为按秒计算平均值
|
||||
|
||||
### [4.0.1] - 2024-01-05
|
||||
|
||||
#### 修复
|
||||
|
||||
- safeline-luigi 容器打印与功能无关的错误日志
|
||||
- 统计页面中不显示 QPS 数据
|
||||
|
||||
### [4.0.0] - 2024-01-05
|
||||
|
||||
#### 新增
|
||||
|
||||
- 完整支持 **流式语义分析检测**,包含 协议解析、解码、模式匹配 三个阶段的改造,解决经典 “大包绕过” 问题
|
||||
- IP 组支持通过 URL 在线订阅内容([#414](https://github.com/chaitin/SafeLine/issues/414)):
|
||||

|
||||
- 新增 “搜索引擎爬虫 IP”,包含 Google、Bing、百度、360 的爬虫
|
||||
IP([#374](https://github.com/chaitin/SafeLine/issues/374)、[#399](https://github.com/chaitin/SafeLine/issues/399)):
|
||||

|
||||
- 出厂预置 “搜索引擎爬虫白名单” 和 “长亭社区恶意 IP 情报黑名单”,方便配置
|
||||
|
||||
#### 优化
|
||||
|
||||
- 支持类 ChatGPT 应用的流式 HTTP 响应([#513](https://github.com/chaitin/SafeLine/issues/513))
|
||||
- 在 证书管理 编辑证书后,若证书正被站点使用,自动重启 nginx
|
||||
使新证书生效([#534](https://github.com/chaitin/SafeLine/issues/534))
|
||||
- safeline-fvm 容器体积减小 60%
|
||||
- safeline-mgt 服务减少宿主机文件依赖
|
||||
- safeline-mgt 服务日志全部写入 docker 标准输出,默认仅输出启动信息和错误日志,减小磁盘占用
|
||||
- safeline-mgt 服务、safeline-tengine 服务支持运行时日志输出范围设置,方便问题调试
|
||||
- 更新 compose.yaml 文件配置,移除非必要环境变量配置,规范环境变量名称,移除非必要卷配置
|
||||
- 增加新统计服务 safeline-luigi,为更精细的统计能力做准备
|
||||
- 优化若干 UI 交互、文字描述、英文翻译的细节(感谢国际友人的帮助)
|
||||
- 修复 3.16 以及之前版本的一些问题:
|
||||
- safeline-tcd 启动时因启动顺序导致输出错误提示
|
||||
- http 强制跳转到 https 功能未生效
|
||||
- 修复 4.0.0-beta.x 版本中的一些问题:
|
||||
- 登录雷池失败,提示 HTTP/2 协议错误([#564](https://github.com/chaitin/SafeLine/issues/564))
|
||||
- 升级脚本未正常检测到雷池安装目录([#561](https://github.com/chaitin/SafeLine/pull/561),感谢热心网友 nmgliangwei)
|
||||
- safeline-mgt 持续输出版本号错误日志
|
||||
- 拦截页面未显示时间
|
||||
|
||||
### [4.0.0-beta.3] - 2023-12-28
|
||||
|
||||
#### 优化
|
||||
|
||||
- 支持类 ChatGPT 应用的流式 HTTP 响应([#513](https://github.com/chaitin/SafeLine/issues/513))
|
||||
- 更新流式检测引擎到 (20231228) 版本
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复由于服务启动顺序导致输出非必要的错误日志
|
||||
|
||||
### [4.0.0-beta.2] - 2023-12-22
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复 safeline-tcd 启动时因启动顺序导致输出错误提示信息
|
||||
- 修复 safeline-mgt 在 beta 版本下持续输出版本号错误日志
|
||||
- 修复 http 强制跳转到 https 功能未生效问题
|
||||
|
||||
#### 优化
|
||||
|
||||
- 更新流式检测引擎版本到 20231222 版本
|
||||
|
||||
### [4.0.0-beta.1] - 2023-12-21
|
||||
|
||||
#### 新增
|
||||
|
||||
- 完整支持 **流式语义分析检测**,包含 协议解析、解码、模式匹配 三个阶段的改造,解决经典 “大包绕过” 问题
|
||||
|
||||
#### 优化
|
||||
|
||||
- safeline-fvm 容器体积减小 60%
|
||||
- safeline-mgt 服务减少宿主机文件依赖
|
||||
- safeline-mgt 服务日志全部写入 docker 标准输出,默认仅输出启动信息和错误日志,减小磁盘占用
|
||||
- safeline-mgt 服务、safeline-tengine 服务支持运行时日志输出范围设置,方便问题调试
|
||||
- 更新 compose.yaml 文件配置,移除非必要环境变量配置,规范环境变量名称,移除非必要卷配置
|
||||
- 增加新统计服务 safeline-luigi,为更精细的统计能力做准备
|
||||
- 美化 502/504 页面
|
||||
- 优化频率限制配置的英文翻译(感谢国际友人的提示)
|
||||
|
||||
### [3.16.1] - 2023-12-15
|
||||
|
||||
#### 新增
|
||||
|
||||
- 右上角增加 “更多工具”,方便快速访问牧云主机助手、百川网站监测等常用运维管理工具
|
||||

|
||||
|
||||
#### 优化
|
||||
|
||||
- 登录时若验证码错误,不再自动清空内容,方便修改([#449](https://github.com/chaitin/SafeLine/issues/449))
|
||||
- 精简 docker 镜像文件,safeline-mgt-api 体积减小 90%
|
||||
- 获取站点的 Favicon 和标题时,增加浏览器 UserAgent,避免被上游服务拒绝
|
||||
- 数据统计页 4xx 和 5xx 错误率的默认显示方式从 “-%” 改为 “0%” ([#517](https://github.com/chaitin/SafeLine/issues/517))
|
||||
- 优化控制台和 502 、504 页面的一些样式细节
|
||||
- 未登录时,不显示任何前端页面内容,避免被报告安全问题
|
||||
|
||||
### [3.15.3] - 2023-12-08
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复 403 拦截页面没有展示拦截页面附加说明的问题
|
||||
|
||||
### [3.15.2] - 2023-12-07
|
||||
|
||||
#### 新增
|
||||
|
||||
- 新增 502、504 页面。网站服务器异常、配置有误时,能给网站用户提供更清晰友好的说明
|
||||

|
||||
- 拦截页面支持英文,根据客户端语言自动切换
|
||||
|
||||
#### 优化
|
||||
|
||||
- 单个 IP 组内的 IP 数量,增加 1w 行的上限。避免更新配置时系统异常
|
||||
- 修复创建或修改站点时,端口占用检查没有生效的问题
|
||||
- 略微提高流量检测和配置修改时的执行效率
|
||||
|
||||
### [3.14.1] - 2023-11-30
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复日志服务 CPU 占用过高问题
|
||||
|
||||
### [3.14.0] - 2023-11-30
|
||||
|
||||
#### 新增
|
||||
|
||||
- 增加黑白名单正则表达式校验,避免 “_url_” 这类错误正则
|
||||
- 事件列表固定表头 ([#443](https://github.com/chaitin/SafeLine/issues/443))
|
||||
|
||||
#### 优化
|
||||
|
||||
- 移除 redis 依赖,减少运行容器数量
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复黑白名单 CIDR 格式校验提示文案未翻译的问题
|
||||
- 修复 safeline-tengine 容器提示缺少 MGT_API 的问题 ([#468](https://github.com/chaitin/SafeLine/issues/468))
|
||||
|
||||
### [3.13.2] - 2023-11-24
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复了 safeline-fvm-manager 容器的健康检查错误结果
|
||||
|
||||
### [3.13.1] - 2023-11-23
|
||||
|
||||
#### 新增
|
||||
|
||||
- 人机验证的二次验证,从数字验证码改为旋转图片,网站用户体验更好:
|
||||

|
||||
|
||||
#### 优化
|
||||
|
||||
- 修复 社区恶意 IP 情报 每日定时更新后,控制台上 “更新时间” 未相应更新的问题
|
||||
- 日志详情 “已拦截” “已放行” 图案改为英文,适配国际化
|
||||
- 域名不匹配时,返回的拦截页面补充更多提示
|
||||
- 优化一些界面细节
|
||||
|
||||
### [3.12.2] - 2023-11-17
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复重启 docker
|
||||
(包括雷池升级)后,站点通用配置和拦截页面附加说明没有被正确载入的问题 ([#438](https://github.com/chaitin/SafeLine/issues/438) [#446](https://github.com/chaitin/SafeLine/issues/446))
|
||||
|
||||
### [3.12.1] - 2023-11-16
|
||||
|
||||
#### 新增
|
||||
|
||||
- 登录过程输入完 6 位验证码自动登录([#335](https://github.com/chaitin/SafeLine/issues/335))
|
||||
- 统计 PV 和 UV 用的 cookie 默认添加 HttpOnly 属性,在 HTTPS 下自动添加 Secure 属性
|
||||
|
||||
#### 优化
|
||||
|
||||
- 修复证书在添加一段时间后,证书类型统一变成 “上传已有证书”
|
||||
,编辑时也看不到证书内容的问题。(免费证书需要手动再切换到免费证书申请一下,后续才能自动续期。只影响列表管理,不影响网站上的证书)
|
||||
- 开启 “强制 HTTPS” 时,HSTS 删去 preload 参数,并改为只在 https
|
||||
端口下返回 ([#407](https://github.com/chaitin/SafeLine/issues/407))
|
||||
- 修复添加、编辑站点有时出现 “Service abnormal” 异常的问题
|
||||
- 修复 “申请免费证书” 类型的证书,在证书列表上显示成 “上传已有证书” 的问题
|
||||
- 优化一些样式交互细节
|
||||
|
||||
### [3.11.1] - 2023-11-09
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复证书列表页面域名列显示不正确问题
|
||||
|
||||
### [3.11.0] - 2023-11-09
|
||||
|
||||
#### 新增
|
||||
|
||||
- 站点详情新增站点的 favicon、标题和编辑按钮
|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化 “强制 HTTPS” 中 HSTS 的参数细节([#407](https://github.com/chaitin/SafeLine/issues/407))
|
||||
- 修复英文模式下事件列表文字错位问题
|
||||
- 修复添加、编辑站点有时出现 “Service abnormal” 异常的问题
|
||||
- 优化站点 “运行模式” 的展示和交互
|
||||
- 优化一些界面交互和提示文字
|
||||
|
||||
### [3.10.3] - 2023-11-03
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复部分证书无法编辑,提示 “密钥内容解析错误” 的问题
|
||||
- 修复升级或重启后,站点证书引用成历史证书的问题
|
||||
- 修复编辑证书有时必须填写私钥的问题
|
||||
|
||||
### [3.10.1] - 2023-11-03
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复无法修改 通用配置-其他-拦截页面附加说明 的问题
|
||||
|
||||
### [3.10.0] - 2023-11-02
|
||||
|
||||
#### 新增
|
||||
|
||||
- 在证书管理创建证书时,支持直接粘贴证书与私钥内容([#77](https://github.com/chaitin/SafeLine/issues/77))
|
||||
|
||||
#### 优化
|
||||
|
||||
- 人机验证的客户端文件从 138k 减小到 78k,提高加载速度
|
||||
- 人机验证 cookie 改为 httpOnly 模式,避免在 JavaScript 运行时泄露
|
||||
- 人机验证防止简单绕过 ([#405](https://github.com/chaitin/SafeLine/issues/405))
|
||||
- 修复站点详情中,资源 “今日请求” 的总和大于站点 “今日请求总量”
|
||||
的问题([#410](https://github.com/chaitin/SafeLine/issues/410))
|
||||
|
||||
### [3.9.0] - 2023-10-26
|
||||
|
||||
#### 优化
|
||||
|
||||
- 人机验证页面增加响应头 Cache-Control,向下游声明不希望被缓存,避免被 CDN
|
||||
缓存导致不断重复验证([#402](https://github.com/chaitin/SafeLine/issues/402) )
|
||||
- 修复人机验证在 iframe 中会不断重复验证的问题([#397](https://github.com/chaitin/SafeLine/issues/397) )
|
||||
- 修复人机验证在 alook 浏览器中页面空白的问题([#393](https://github.com/chaitin/SafeLine/issues/393) )
|
||||
- 修复添加、编辑站点有时出现 “Service abnormal” 异常的问题
|
||||
- 修复申请免费证书时,无法填写多个域名的问题
|
||||
- 修复编辑站点时,域名无法设为空的问题
|
||||
- 升级过程增加安装方式检查,通过牧云助手安装的,需要通过牧云助手升级,避免故障
|
||||
|
||||
### [3.8.2] - 2023-10-19
|
||||
|
||||
#### 新增
|
||||
|
||||
- “通用漏洞规则” 的攻击日志中,新增 “命中规则”,方便管理员了解具体的拦截原因:
|
||||

|
||||
|
||||
#### 优化
|
||||
|
||||
- 修复 acme 未记录好邮箱,导致无法自动续签的问题。**旧版本已申请的证书,升级后需要再次编辑补全一下邮箱地址,才能自动续签**
|
||||
- 修复雷池重启后,已通过人机验证的页面会一直反复进行人机验证的问题
|
||||
- 修复某个站点关闭 ssl 之后,还会错误地显示在证书管理的 “使用站点” 中的问题
|
||||
- 优化安卓手机的人机验证效果,现在不会总是弹出验证码识别了
|
||||
- 修复证书管理-编辑证书时,弹窗没有正常回填已有配置的问题
|
||||
- 优化 攻击事件->原始日志 默认的筛选条件([#288](https://github.com/chaitin/SafeLine/issues/288))
|
||||
- 优化一些 UI 交互细节
|
||||
|
||||
### [3.7.3] - 2023-10-16
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复获取上游服务器的 favicon 和标题失败时,可能导致站点管理无法配置站点的问题
|
||||
- 修复 IP 组中的网段解析错误,导致匹配结果不正确的问题
|
||||
|
||||
### [3.7.2] - 2023-10-13
|
||||
|
||||
#### 优化
|
||||
|
||||
- 修复无法更新威胁情报 IP 的问题
|
||||
- 修复编辑人机验证配置时不回显的问题
|
||||
|
||||
### [3.7.1] - 2023-10-13
|
||||
|
||||
#### 新增
|
||||
|
||||
- 人机验证增加 **二次验证码验证**,在自动验证失败时进行,减少误拦
|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化人机验证
|
||||
- 简化配置,不再区分交互、非交互
|
||||
- 区分站点,验证通过的结果只能在一个站点(按域名或 IP 区分)上生效了
|
||||
- 降低算力要求,解决部分移动端验证时间过长的问题
|
||||
- 配置站点时,“上游服务器” 的服务器地址部分支持填写主机名,例如 http://localhost:8080
|
||||
- 站点的运行模式为 “观察” 时,黑名单、限频、人机 改为**都不拦截**。其中黑名单会记录 “放行” 的日志;限频会持续计入统计,但限制结果不会对观察中的站点生效
|
||||
- 修复证书管理中,泛域名的证书显示 “域名不匹配” 问题([#368](https://github.com/chaitin/SafeLine/issues/368))
|
||||
- 更新检测引擎版本,降低误报
|
||||
- 优化若干提示文字和样式细节
|
||||
|
||||
### [3.6.4] - 2023-10-09
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复了多个域名申请免费证书失败的问题
|
||||
- 修复了有时候不能创建 HTTP 站点的问题
|
||||
- 修复证书管理中,“使用站点” 不全的问题
|
||||
- 修复证书管理中,泛域名证书的使用站点始终提示 “域名不匹配” 的问题
|
||||
|
||||
### [3.6.3] - 2023-10-09
|
||||
|
||||
#### 新增
|
||||
|
||||
- 新增申请免费证书。只要域名已经指向雷池,就可以在界面上直接申请证书了
|
||||

|
||||
- 证书管理新增 “使用站点”,并且会自动检查站点和证书的域名是否一致:
|
||||

|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化站点配置证书的流程,现在所有证书都在证书管理配置,方便统一查看
|
||||
- 雷池控制台证书的配置移动到了 “通用配置” -> “其他” 中,更符合直觉:
|
||||

|
||||
- 修复某些情况下采集不到站点 favicon 的问题
|
||||
- 修复采集站点标题的时候,会把英文大写转成小写的问题
|
||||
- 修复站点详情中,删除文件夹的操作不会生效的问题
|
||||
- 修复站点详情中,资源的 今日请求 / 近 30 日请求 始终为 0 的问题
|
||||
|
||||
### [3.5.1] - 2023-09-26
|
||||
|
||||
#### 优化:
|
||||
|
||||
- 修复站点详情中,今日请求量一直为 0 的问题
|
||||
- 修复获取站点 favicon 时没有尝试默认路径,导致某些站点获取不到的问题
|
||||
- 修复小概率出现无法对站点进行任何操作的问题(不影响已配置站点的防护)
|
||||
|
||||
### [3.5.0] - 2023-09-21
|
||||
|
||||
#### 新增
|
||||
|
||||
- 人机验证新增每个规则的 “今日验证情况”,方便判断规则配置的效果:
|
||||

|
||||
|
||||
#### 优化
|
||||
|
||||
- 站点列表新增 “资源数”,方便判断判断资源管理情况
|
||||
- 优化 攻击事件->原始日志 默认的筛选条件([#288](https://github.com/chaitin/SafeLine/issues/288))
|
||||
- 修复自动采集的站点 favicon 有时候显示不出来的问题([#316](https://github.com/chaitin/SafeLine/issues/316))
|
||||
- 修复自动采集的站点标题有时候显示成乱码的问题
|
||||
- 修复站点详情的 “今日请求总量” 有时候不显示最新值的问题
|
||||
- 优化一些界面样式交互细节
|
||||
|
||||
### [3.4.1] - 2023-09-15
|
||||
|
||||
#### 优化
|
||||
|
||||
- 修复请求上游服务器的 title 和 icon 时间过长导致站点相关功能异常的问题
|
||||
- 修复站点列表中站点标题的优先显示顺序,先显示“备注”,如果没有“备注”再显示网页的“标题”
|
||||
|
||||
### [3.4.0] - 2023-09-14
|
||||
|
||||
#### 新增
|
||||
|
||||
- “防护站点” 新增站点的标题和 Favicon,每天更新一次,管理起来更加清晰:
|
||||

|
||||
- 站点详情新增“采集设置”,支持设置不记录的路径前缀和类型
|
||||

|
||||

|
||||
|
||||
#### 优化
|
||||
|
||||
- 限频后封禁的拦截页面改为 “请求频率过高,已被拦截”,与语义分析和黑名单的拦截页面区分开,方便管理员确认拦截原因
|
||||
- 修复有时候无法正常通过路径搜索日志的问题
|
||||
- 修复限频中,同时配置人机验证、直接封禁两类限制结果时,直接封禁有时候不会被触发的问题
|
||||
- 修复黑名单拦截的请求也会触发限频,导致限频日志中出现很多 “已限制请求数” 为 0 的记录的问题
|
||||
- 优化界面的一些样式交互
|
||||
|
||||
### [3.3.0] - 2023-09-07
|
||||
|
||||
#### 新增
|
||||
|
||||
- 支持设置拦截页面附加说明([#192](https://github.com/chaitin/SafeLine/issues/192))
|
||||

|
||||
- 频率限制新增 “人机验证” 的限制方式([#226](https://github.com/chaitin/SafeLine/issues/226))
|
||||

|
||||
|
||||
#### 优化
|
||||
|
||||
- 当网站域名不匹配的时候,返回 “网站不存在” ,提示更清晰([#58](https://github.com/chaitin/SafeLine/issues/58))
|
||||
- 修复 攻击事件->原始日志 的 “攻击地址” 中显示额外的转义符的问题
|
||||
- 修复站点详情中 “今日总请求量” 和站点列表的 “今日访问量”
|
||||
不一致的问题([#279](https://github.com/chaitin/SafeLine/issues/279))
|
||||
- 频率限制后直接封禁的拦截状态码改为 429,和普通拦截 403 区分开,方便排查拦截原因
|
||||
- 加强后台登录安全性(感谢微信交流 20 群「千年之狐」提供的建议)
|
||||
- 优化安装/升级时 CPU ssse3 指令集的检查方式([#273](https://github.com/chaitin/SafeLine/issues/273))
|
||||
- 优化界面样式交互,修复一些已知问题
|
||||
|
||||
### [3.2.0] - 2023-08-31
|
||||
|
||||
#### 新增
|
||||
|
||||
- 证书管理支持上传 PKCS1、PKCS8、ECC 私钥格式的证书([#257](https://github.com/chaitin/SafeLine/issues/257))
|
||||
- 站点详情新增近 30 天请求数,支持批量删除
|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化站点详情页面,提高加载速度、优化界面样式和逻辑
|
||||
- 限频的生效阈值由 “超过 xx 次” 改为 “达到 xx 次”([#245](https://github.com/chaitin/SafeLine/issues/245))
|
||||
- 修复频率限制所拦截的请求,没有被计入站点列表的 “今日访问/拦截量” 的问题
|
||||
- 修复证书管理的证书有时候无法正常删除的问题([#268](https://github.com/chaitin/SafeLine/issues/268))
|
||||
- 修复证书管理中,有时候一个证书内会解析出几个重复的域名的问题
|
||||
- 去掉对 docker 的 seccomp 特性的依赖([#255](https://github.com/chaitin/SafeLine/issues/255))
|
||||
- 优化大量界面样式、交互和操作提示细节
|
||||
|
||||
### [3.1.1] - 2023-08-28
|
||||
|
||||
#### 优化
|
||||
|
||||
- 修复创建站点时直接上传 SSL 证书显示创建失败的问题
|
||||
|
||||
### [3.1.0] - 2023-08-25
|
||||
|
||||
#### 新增
|
||||
|
||||
- 新增证书管理。自动判断域名与过期状态,配置站点时可以直接选择([#111](https://github.com/chaitin/SafeLine/issues/111)
|
||||
),还可以修改管理后台的证书([#201](https://github.com/chaitin/SafeLine/issues/201))
|
||||

|
||||
- 新增系统信息
|
||||
|
||||
#### 优化
|
||||
|
||||
- 修复站点详情全局只支持 250 个资源的问题。现在是每个站点各支持 250 个
|
||||
- 修复站点详情中,路径太长样式会错位的问题
|
||||
- 修复站点从维护切换成其他状态时,微信会缓存维护页面的问题([#221](https://github.com/chaitin/SafeLine/issues/221))
|
||||
- 修复手机和平板上不能输入动态口令的问题([#234](https://github.com/chaitin/SafeLine/issues/234))
|
||||
- 优化导航栏和若干 UI 交互细节
|
||||
|
||||
### [3.0.1] - 2023-08-18
|
||||
|
||||
- 更新底层语义分析引擎,加强基础防护能力
|
||||
- 修复站点详情中,不同域名的资源会重复记录问题
|
||||
- 修复攻击事件有小概率时间排序错误的问题
|
||||
- 修复关闭再打开频率限制时,配置不会重置到默认值的问题
|
||||
- 修复首次创建站点且配置 SSL 端口的情况下提示“端口被占用”的问题
|
||||
|
||||
### [3.0.0] - 2023-08-18
|
||||
|
||||
#### 新增
|
||||
|
||||
- 新增站点详情,能自动从流量中记录网站资源,一览资源的存活、访问情况
|
||||
- PS. 考虑机器资源消耗问题,当前版本每个站点下最多记录 250 个资源
|
||||
|
||||

|
||||
|
||||
- 站点支持输入多个域名、端口([#162](https://github.com/chaitin/safeline/issues/162))
|
||||
- 通用配置中新增 “站点通用配置”,支持一键开启:
|
||||
- 强制 HTTPS([#67](https://github.com/chaitin/safeline/issues/67))
|
||||
- 使用 HTTP/2([#161](https://github.com/chaitin/safeline/issues/161))
|
||||
- 监听 IPv6([#166](https://github.com/chaitin/safeline/issues/166))
|
||||
- 传递客户端连接的 Host 和协议,方便后续服务器处理
|
||||
|
||||

|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化限频配置的默认值
|
||||
- 增加 HTTP 497 错误重定向。当以 HTTP 协议访问 HTTPS 端口时,将重定向到
|
||||
HTTPS([#186](https://github.com/chaitin/safeline/issues/186))
|
||||
- 默认拒绝 IP 和其他非指定域名的访问。如果需要通过 IP 访问站点,可以给站点添加一个 "\*"
|
||||
域名([#58](https://github.com/chaitin/safeline/issues/58))
|
||||
- 优化若干 UI 交互细节和文字提示
|
||||
|
||||
### [2.6.0] - 2023-08-10
|
||||
|
||||
#### 新增
|
||||
|
||||
- 新增高频攻击封禁,即多次攻击后自动封禁 IP ([#29](https://github.com/chaitin/safeline/issues/29))
|
||||
- 频率限制日志显示封禁 IP 的地理位置 ([#198](https://github.com/chaitin/safeline/issues/198))
|
||||
|
||||
#### 优化
|
||||
|
||||
- 攻击检测的原始日志支持搜索端口 ([#193](https://github.com/chaitin/safeline/issues/193))
|
||||
- 修复编辑站点后,“维护模式” 会失效的问题
|
||||
- 修改默认占用的网段,避免跟腾讯云默认网段冲突 ([#40](https://github.com/chaitin/safeline/issues/40))
|
||||
- 优化安装脚本 ([#194](https://github.com/chaitin/safeline/issues/194)),优化界面一些 UI 交互、错误提示
|
||||
|
||||
### [2.5.0] - 2023-08-03
|
||||
|
||||
#### 新增
|
||||
|
||||
- 请求频率限制([#29](https://github.com/chaitin/safeline/issues/29))
|
||||
|
||||
#### 优化
|
||||
|
||||
- 支持筛选攻击检测日志的 ID([#74](https://github.com/chaitin/safeline/issues/74)),优化筛选的交互
|
||||
- 证书支持 .cer 格式([#181](https://github.com/chaitin/safeline/issues/181))
|
||||
- 优化人机校验页面,适配移动端([#184](https://github.com/chaitin/safeline/issues/184))
|
||||
- 界面增加一些配置提示:添加站点时 “域名” 的格式、黑白名单/人机验证中匹配条件的生效逻辑
|
||||
|
||||
### [2.4.0] - 2023-07-27
|
||||
|
||||
#### 新增
|
||||
|
||||
- IP 组支持注释 [#143](https://github.com/chaitin/safeline/issues/143)
|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化编辑 IP 组和相关规则时的性能
|
||||
- 优化一些界面 UI 交互细节
|
||||
|
||||
### [2.3.2] - 2023-07-24
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复了攻击事件 - 原始日志中,请求报文没有格式化的问题
|
||||
- 优化了一些已知问题
|
||||
|
||||
### [2.3.1] - 2023-07-20
|
||||
|
||||
#### 新增
|
||||
|
||||
- 检测日志升级为**攻击事件** ,自动聚合同一攻击 IP 短时间内的所有攻击日志,方便管理员进行监控和处置
|
||||
- 日志支持按时间([#102](https://github.com/chaitin/safeline/issues/102))、动作筛选
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复添加/编辑站点时,上传证书处未翻译中文的问题
|
||||
- 修复数据统计中,“访问来源地区” 小概率出现的部分地区显示不正确的问题
|
||||
|
||||
### [2.2.0] - 2023-07-14
|
||||
|
||||
#### 新增
|
||||
|
||||
- IP 组中新增长亭社区恶意 IP 情报,内容来自社区版共享的攻击 IP,每日自动更新
|
||||
|
||||
#### 优化
|
||||
|
||||
- 升级核心检测引擎,修复一些绕过和误报
|
||||
- 管理界面增加浏览器版本检查,如果版本过旧,会提示升级浏览器
|
||||
- 优化一些界面的 UI 交互细节
|
||||
- 修复一些中英文翻译的问题
|
||||
|
||||
### [2.1.2] - 2023-07-07
|
||||
|
||||
- 修复了日志详情中防护策略模块没有翻译的问题
|
||||
|
||||
### [2.1.1] - 2023-07-06
|
||||
|
||||
- 修复了防护策略模块没有翻译的问题
|
||||
|
||||
### [2.1.0] - 2023-07-06
|
||||
|
||||
#### 新增
|
||||
|
||||
- 支持自定义站点的 nginx conf,详情可见[官网文档](/faq/other#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%AB%99%E7%82%B9-nginx-conf)
|
||||
- 添加/编辑站点时,自动检查端口占用情况,避免保存后配置不生效
|
||||
- [站点列表支持按域名、端口或访问量进行排序](https://github.com/chaitin/safeline/issues/14)
|
||||
- [绑定 TOTP 密钥时,支持直接复制密钥;登录时的 6 位动态密码输入框,支持粘贴](https://github.com/chaitin/safeline/issues/30)
|
||||
|
||||
#### 优化
|
||||
|
||||
- [黑白名单和人机验证列表中,可以鼠标悬浮查看 “复合条件” 的具体内容](https://github.com/chaitin/safeline/issues/120)
|
||||
- 修复人机验证列表中,“源 IP 不属于 IP 组” 的规则,IP 组名称显示成了 id 的问题
|
||||
- [优化人机验证启用/禁用交互](https://github.com/chaitin/safeline/issues/130)
|
||||
- [优化描述文字](https://github.com/chaitin/safeline/issues/122)
|
||||
- 优化一些界面 UI 交互、提示文字
|
||||
- 修复一些已知问题
|
||||
|
||||
### [2.0.1] - 2023-06-30
|
||||
|
||||
- 调整了人机验证的策略,降低误拦的情况
|
||||
- 修复了人机验证启动/禁用规则不会自动刷新状态的问题
|
||||
- 修复其他一些已知问题
|
||||
|
||||
### [2.0.0] - 2023-06-29
|
||||
|
||||
#### 新增
|
||||
|
||||
- 人机验证
|
||||
- 支持嵌入式部署,可以通过 [t1k 协议](https://github.com/chaitin/lua-resty-t1k) 直接把流量转发到雷池进行检测
|
||||
- 把日志详情中的源 IP 加入到 IP 组时,支持调整 IP 为任意 IP 或网段
|
||||
|
||||
#### 优化
|
||||
|
||||
- 日志列表按照时间和 ID 排序,防止出现小范围的时间乱序
|
||||
- 转发流量时,自动设置请求头 X-Forwarded-Proto,适配更多代理场景
|
||||
- 优化界面 UI,修复其他一些已知问题
|
||||
|
||||
### [1.10.0] - 2023-06-21
|
||||
|
||||
#### 新增
|
||||
|
||||
- 防护站点新增 “运行模式”,可以一键将站点设为 观察 或 维护 模式了
|
||||
|
||||
#### 优化
|
||||
|
||||
- 修复了站点列表没有分页器的问题
|
||||
- 修复了窗口水平滚动时导航栏会错位的问题
|
||||
- 修复了黑白名单配置 “不属于 IP 组” 的条件时,列表显示组 ID,而未显示组名称的问题
|
||||
- 优化了界面的 UI 与交互
|
||||
|
||||
### [1.9.0] - 2023-06-16
|
||||
|
||||
#### 新增
|
||||
|
||||
- 界面 UI 改造,信息层级更清晰
|
||||
- 黑白名单支持添加 源 IP - 不属于 IP 组 的条件
|
||||
|
||||
#### 优化
|
||||
|
||||
- 检测日志的路由进一步完善
|
||||
- 数据统计页面更加紧凑,现在可以在 1920\*1080 的屏幕上完全显示了
|
||||
- 黑白名单的展示优化
|
||||
- 修复 通用配置-防护模块配置 中,“批量配置为” 按钮有时候不生效的问题
|
||||
- 修复一些已知问题
|
||||
|
||||
### [1.8.2] - 2023-06-12
|
||||
|
||||
- 修复了「30 天访问情况」和「30 天拦截情况」显示相同数据的问题
|
||||
|
||||
### [1.8.1] - 2023-06-09
|
||||
|
||||
- 修复了「全部请求」和「仅拦截」数据一样的问题
|
||||
|
||||
### [1.8.0] - 2023-06-09
|
||||
|
||||
#### 新增
|
||||
|
||||
- 数据统计页面增加访问来源地区、流量统计,更好把控网站运营情况
|
||||
|
||||

|
||||
|
||||
#### 优化
|
||||
|
||||
- 更新语义引擎版本,优化了一大批检测逻辑,降低误报
|
||||
- 优化了部分操作提示信息:
|
||||
- IP 组正在使用时,无法被删除的提示
|
||||
- 未创建 IP 组时,在黑白名单中无法选择属于 IP 组的提示
|
||||
- 添加站点时,域名格式错误的提示
|
||||
|
||||
### [1.7.1] - 2023-06-05
|
||||
|
||||
#### 修复
|
||||
|
||||
- 部分情况下无法打开日志详情页面的问题
|
||||
- 部分情况下页面查询数量只有 10 条的问题
|
||||
|
||||
### [1.7.0] - 2023-06-01
|
||||
|
||||
#### 新增
|
||||
|
||||
- 新增 “IP 组” 功能,可以快速配置大量 IP 的黑/白名单了
|
||||
- 防护策略增加 “仅观察” 配置
|
||||
- 防护策略增加 “批量配置为” 按钮,可以快速切换所有模块的防护策略
|
||||
|
||||
#### 优化
|
||||
|
||||
- 自定义规则列表增加翻页
|
||||
- 优化规则生效顺序,现在会优先执行完所有白名单,再执行黑名单
|
||||
|
||||
### [1.6.0] - 2023-05-25
|
||||
|
||||
#### 新增
|
||||
|
||||
- 自定义规则支持匹配 Header 和 Body
|
||||
- 检测日志支持按域名搜索
|
||||
- 支持命令行清理检测日志和统计信息
|
||||
|
||||
### [1.5.1] - 2023-05-18
|
||||
|
||||
- 修复了自定义规则切换白名单之后,无法创建/编辑的问题
|
||||
|
||||
### [1.5.0] - 2023-05-18
|
||||
|
||||
#### 新增
|
||||
|
||||
- 支持 i18n
|
||||
- 数据统计新增 “今日请求错误情况”
|
||||
- 检测日志的筛选条件现在会显示在 URL,方便保存
|
||||
|
||||
#### 优化
|
||||
|
||||
- 修复自定义规则的编辑表单,有时候会丢失编辑中数据的问题
|
||||
- 修复 Safari 浏览器上的一些显示问题
|
||||
- 修复 Payload 中存在非 Unicode 编码时,检测日志会入库失败的问题(不影响拦截)
|
||||
- 修复新增的 “HTTP 请求走私” 攻击类型会被错误地展示成 “未知” 攻击类型的问题
|
||||
|
||||
### [1.4.0] - 2023-05-12
|
||||
|
||||
#### 新增
|
||||
|
||||
- 自定义规则支持匹配域名
|
||||
- 支持在一条自定义规则内,设置多个匹配条件
|
||||
- 站点列表新增 “今日访问 / 拦截量”
|
||||
|
||||
#### 优化
|
||||
|
||||
- 优化交互和提示文案、修复已知问题
|
||||
|
||||
### [1.3.0] - 2023-05-05
|
||||
|
||||
#### 新增
|
||||
|
||||
- 支持按照源 IP、攻击类型、URL 筛选检测日志
|
||||
|
||||
#### 修复
|
||||
|
||||
- 修复 dashboard 在部分低版本浏览器下的兼容问题
|
||||
- 修复按源 IP 添加自定义规则时,添加不了 /8 和更大的网段的问题
|
||||
|
||||
### [1.2.0] - 2023-04-27
|
||||
|
||||
#### 新增
|
||||
|
||||
- 新增了数据统计页面,可以直观的看到流量大小
|
||||
- 支持配置源 IP 提取方式,解决了源 IP 获取不对的问题
|
||||
- 支持自定义检测策略,可以动态调整检测引擎
|
||||
|
||||
### [1.1.0] - 2023-04-20
|
||||
|
||||
#### 新增
|
||||
|
||||
- 支持根据 IP 和 URL 特征配置黑白名单
|
||||
- 默认开启高防模式
|
||||
|
||||
#### 优化
|
||||
|
||||
- 支持在日志详情中展示响应报文
|
||||
- 服务器时间不准导致 TOTP 无法登录时增加了提示语
|
||||
- 修复了上游服务器填 HTTPS 时端口解析不正确的问题
|
||||
- 优化了 SSL 上传逻辑,体验更好
|
||||
|
||||
### [1.0.0] - 2023-04-13
|
||||
|
||||
- 站点配置
|
||||
|
||||
### [0.9.0] - 2023-03-20
|
||||
|
||||
- OTP 登录
|
||||
- 攻击检测日志
|
||||
- 默认防护策略
|
31
documents/docs/05-about/01-syntaxanalysis.md
Normal file
|
@ -0,0 +1,31 @@
|
|||
---
|
||||
title: "语义分析检测算法"
|
||||
---
|
||||
|
||||
# 语义分析检测算法
|
||||
|
||||
## 传统规则防护,在当下为什么失灵?
|
||||
|
||||
当下,Web 应用防火墙大多采用规则匹配方式来识别和阻断攻击流量,但由于 Web 攻击成本低、方式复杂多样、高危漏洞不定期爆发等原因,管理者们在安全运维工作中不得不持续调整防护规则,以保障业务的可用性和安全性。尽管如此,每天依然面临着不少的误报和漏报,影响正常业务运转甚至导致 Web 服务失陷。
|
||||
|
||||
究其原因,是由于基于规则匹配的攻击识别方法存在先天不足导致的。在乔姆斯基文法体系中,编写匹配规则的正则文法属于 3 型文法,而用于构造攻击 Payload 的程序语言属于 2 型文法,如下图所示:
|
||||
|
||||

|
||||
|
||||
从文法表达能力比较,3 型文法包含在 2 型文法之内,基于正则的规则描述无法完全覆盖基于程序语言的攻击 Payload,这也是基于规则匹配识别攻击的 WAF 防护效果低于预期的根本原因。
|
||||
|
||||
## 雷池的解决之道:算法的革新重构 WAF
|
||||
|
||||
长亭科技自成立起便深入探索 Web 安全防护的新思路,创新性提出以 “智能语义分析算法” 解决 Web 攻击识别问题,给 WAF 内置 “智能大脑”,使其具备自主识别攻击行为的能力,同时结合机器学习建模,不断增强和完善 “大脑” 的分析能力,不依赖传统的规则库即可满足 Web 应用日常安全防护需求。
|
||||
|
||||
雷池通过对 Web 请求和返回内容进行智能分析,使 WAF 具备智能判断攻击威胁的能力。智能语义分析算法由词法分析、语法分析、语义分析和威胁模型匹配 4 个步骤组成。
|
||||
|
||||

|
||||
|
||||
雷池内置涵盖常用编程语言的编译器,通过对 HTTP 的载荷内容进行深度解码后,按照其语言类型匹配相应语法编译器,进而匹配威胁模型得到威胁评级,阻断或允许访问请求。
|
||||
|
||||
与规则匹配型威胁检测方式相比,智能语义分析技术具有准确率高、误报率低的特点。以 SQL 注入检测为例:
|
||||
|
||||

|
||||
|
||||
作为全球范围内第一款以智能语义分析算法为核心引擎能力打造的下一代 WAF,雷池展现出了更多让安全产品 “更聪明” 的可能。除了形成了质变的检测引擎的精准程度,它可以通过插件形式灵活扩展、实现瑞士军刀般的功能增加,可以变形适配、安装部署进各种网络环境,可以跟机器学习等前沿技术更好的融合、增强流量分析的能力等。
|
28
documents/docs/05-about/02-challenge.md
Normal file
|
@ -0,0 +1,28 @@
|
|||
---
|
||||
title: "人机验证2.0"
|
||||
---
|
||||
|
||||
# 人机验证
|
||||
|
||||
自从雷池社区版发布以来,我们一直密切关注用户对于爬虫和扫描器的反馈和防护需求。 因此,在 2.0 版本中,我们致力于探索与此相关的功能,以满足用户的期望和保护网站的安全。
|
||||
|
||||

|
||||
|
||||
### 加入人机验证之后的请求处理流程
|
||||
|
||||

|
||||
|
||||
### 人机验证如何配置
|
||||
|
||||
首先,点击位于左边栏的人机验证。之后,点击 **添加人机验证**。
|
||||
|
||||
|
||||

|
||||
|
||||
在这里我们可以配置规则的名称以及规则的触发条件。
|
||||
|
||||
### 人机验证触发规则
|
||||
|
||||
1. 规则内的条件之间是并且的关系,即需要全部命中,才会触发
|
||||
2. 规则与规则之间是或的关系,则有一个命中,便会触发
|
||||
|
168
documents/docs/05-about/03-framework.md
Normal file
|
@ -0,0 +1,168 @@
|
|||
---
|
||||
title: "雷池技术架构"
|
||||
---
|
||||
|
||||
# 雷池技术架构
|
||||
|
||||
查看雷池的服务架构图。最上面虚线框住的是数据流,也就是访问业务服务器的流量数据的流动情况。中间框起来的部分是雷池的各个服务。
|
||||
|
||||

|
||||
|
||||
各个容器和服务说明:
|
||||
|
||||
| 名称 | 定义 | 详情 |
|
||||
| ----------------- | ------------ | ------------------------------------------------------- |
|
||||
| safeline-mgt | 管理容器 | 接收管理后台行为,向其他服务或容器推送消息 |
|
||||
| safeline-detector | 检测容器 | 执行检测的容器,从 Tengine 进入的流量会转发到该节点检测 |
|
||||
| safeline-mario | 日志容器 | 记录与统计恶意行为的节点 |
|
||||
| safeline-tengine | 网关 | 转发网关,有简单的过滤功能 |
|
||||
| safeline-pg | 关系型数据库 | 存储攻击日志、保护站点、黑白名单配置的数据库 |
|
||||
|
||||
对于后台管理人员,可以直接通信的节点为管理服务 `safeline-mgt`,该节点负责:
|
||||
|
||||
- 向 Tengine 网关推送自定义配置并利用 NGINX 命令进行 reload 热更新
|
||||
- 自定义检测规则(黑白名单等)并向检测引擎 `safeline-detector` 推送
|
||||
- 直接读取 `postgres` 数据库,向后台管理人员返回日志、统计、当前配置等
|
||||
|
||||
## 各个配置文件说明
|
||||
|
||||
### .env 文件
|
||||
|
||||
用于设置 `compose.yaml` 要引用的环境变量
|
||||
|
||||
```bash
|
||||
echo "SAFELINE_DIR=$(pwd)" >> .env # 设置当前路径为雷池社区版的根路径
|
||||
echo "IMAGE_TAG=latest" >> .env # 设置镜像的 tag
|
||||
echo "MGT_PORT=9443" >> .env # 管理容器服务使用的端口
|
||||
echo "POSTGRES_PASSWORD=$(LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 32)" >> .env # /dev/urandom是一个很长的随机数文本,tr -dc 命令用于删除非字母、非数字的字符,用于生成随机的 postgres 密码
|
||||
echo "SUBNET_PREFIX=172.22.222" >> .env # 定义 docker 虚拟网卡的子网前缀
|
||||
```
|
||||
|
||||
### compose.yml 文件
|
||||
|
||||
用于启动多个容器
|
||||
|
||||
```yml
|
||||
# 基于3.10 版本进行说明,最新配置文件可能存在部分变动
|
||||
networks:
|
||||
safeline-ce:
|
||||
name: safeline-ce # 定义该子网名称
|
||||
driver: bridge # 该子网为网桥模式
|
||||
ipam:
|
||||
driver: default
|
||||
config:
|
||||
- gateway: ${SUBNET_PREFIX:?SUBNET_PREFIX required}.1 # 定义网关为 SUBNET_PREFIX.1,若按上文设置,此处为 172.22.222.1
|
||||
subnet: ${SUBNET_PREFIX}.0/24
|
||||
driver_opts:
|
||||
com.docker.network.bridge.name: safeline-ce
|
||||
services:
|
||||
postgres:
|
||||
container_name: safeline-postgres
|
||||
restart: always # 容器启动失败或崩溃时自动重启
|
||||
image: postgres:15.2
|
||||
volumes: # 开启的映射文件夹
|
||||
- ${SAFELINE_DIR}/resources/postgres/data:/var/lib/postgresql/data
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
environment:
|
||||
- POSTGRES_USER=safeline-ce
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?postgres password required}
|
||||
networks: # 使用上文的 safeline-ce 网络,IP 为 172.22.222.2
|
||||
safeline-ce:
|
||||
ipv4_address: ${SUBNET_PREFIX}.2
|
||||
cap_drop:
|
||||
- net_raw
|
||||
command: [postgres, -c, max_connections=200] # 设置 postgres 的最大连接数
|
||||
management:
|
||||
container_name: safeline-mgt-api
|
||||
restart: always
|
||||
image: chaitin/safeline-mgt-api:${IMAGE_TAG:?image tag required}
|
||||
volumes:
|
||||
- ${SAFELINE_DIR?safeline dir required}/resources/management:/resources/management
|
||||
- ${SAFELINE_DIR}/resources/nginx:/resources/nginx
|
||||
- ${SAFELINE_DIR}/logs:/logs
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
ports:
|
||||
- ${MGT_PORT:-9443}:1443
|
||||
environment:
|
||||
- MANAGEMENT_RESOURCES_DIR=/resources/management
|
||||
- NGINX_RESOURCES_DIR=/resources/nginx
|
||||
- DATABASE_URL=postgres://safeline-ce:${POSTGRES_PASSWORD}@127.0.0.1/safeline-ce
|
||||
- MANAGEMENT_LOGS_DIR=/logs/management
|
||||
networks:
|
||||
safeline-ce: # 使用上文的 safeline-ce 网络,IP 为 172.22.222.4
|
||||
ipv4_address: ${SUBNET_PREFIX}.4
|
||||
cap_drop:
|
||||
- net_raw
|
||||
detector:
|
||||
container_name: safeline-detector
|
||||
restart: always
|
||||
image: chaitin/safeline-detector:${IMAGE_TAG}
|
||||
volumes:
|
||||
- ${SAFELINE_DIR}/resources/detector:/resources/detector
|
||||
- ${SAFELINE_DIR}/logs/detector:/logs/detector
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
environment:
|
||||
- LOG_DIR=/logs/detector
|
||||
networks:
|
||||
safeline-ce: # 使用上文的 safeline-ce 网络,IP 为 172.22.222.5
|
||||
ipv4_address: ${SUBNET_PREFIX}.5
|
||||
cap_drop:
|
||||
- net_raw
|
||||
mario:
|
||||
container_name: safeline-mario
|
||||
restart: always
|
||||
image: chaitin/safeline-mario:${IMAGE_TAG}
|
||||
volumes:
|
||||
- ${SAFELINE_DIR}/resources/mario:/resources/mario
|
||||
- ${SAFELINE_DIR}/logs/mario:/logs/mario
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
environment:
|
||||
- LOG_DIR=/logs/mario
|
||||
- GOGC=100
|
||||
- DATABASE_URL=postgres://safeline-ce:${POSTGRES_PASSWORD}@safeline-postgres/safeline-ce
|
||||
networks:
|
||||
safeline-ce: # 使用上文的 safeline-ce 网络,IP 为172.22.222.6
|
||||
ipv4_address: ${SUBNET_PREFIX}.6
|
||||
cap_drop:
|
||||
- net_raw
|
||||
tengine:
|
||||
container_name: safeline-tengine
|
||||
restart: always
|
||||
image: chaitin/safeline-tengine:${IMAGE_TAG}
|
||||
volumes:
|
||||
- ${SAFELINE_DIR}/resources/nginx:/etc/nginx
|
||||
- ${SAFELINE_DIR}/resources/management:/resources/management
|
||||
- ${SAFELINE_DIR}/resources/detector:/resources/detector
|
||||
- ${SAFELINE_DIR}/logs/nginx:/var/log/nginx
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- ${SAFELINE_DIR}/resources/cache:/usr/local/nginx/cache
|
||||
- /etc/resolv.conf:/etc/resolv.conf
|
||||
environment:
|
||||
- MGT_ADDR=${SUBNET_PREFIX}.4:9002 # 配置 mgt-api 的 grpc 服务器地址,用于与 mgt-api 容器通信
|
||||
ulimits:
|
||||
nofile: 131072
|
||||
network_mode: host # Tengine 直接使用宿主机网络
|
||||
```
|
||||
|
||||
### 各个服务的运行日志
|
||||
|
||||
```bash
|
||||
|
||||
docker ps # 查看各容器状态
|
||||
docker logs -f <comtainer_name> # 输出容器 std 日志
|
||||
|
||||
# 一些服务运行中的持久化也会存储在磁盘上,目录结构如下
|
||||
|
||||
root@user:/path/to/safeline-ce/logs# tree
|
||||
.
|
||||
├── detector
|
||||
│ └── snserver.log #检测容器的输出日志
|
||||
├── management
|
||||
│ ├── nginx.log # Tengine 容器中 NGINX 日志输出
|
||||
│ └── webserver.log # safeline-mgt-api 容器的日志输出
|
||||
├── mario
|
||||
│ └── mario.log # 流量日志输出
|
||||
└── nginx
|
||||
├── error.log # NGINX 的错误日志
|
||||
└── tcd.log # tcd 是 Tengine 用于与 safeline-mgt-api 通信的网络代理进程,该文件存储了两者的通信日志
|
||||
```
|
88
documents/docs/05-about/04-chaitin.md
Normal file
|
@ -0,0 +1,88 @@
|
|||
---
|
||||
title: "关于我们"
|
||||
---
|
||||
|
||||
# 关于我们
|
||||
|
||||
## 关于长亭
|
||||
|
||||
雷池是长亭科技耗时近 10 年倾情打造的 Web 应用防护产品,核心检测能力由智能语义分析算法驱动。
|
||||
|
||||
北京长亭未来科技有限公司是国际顶尖的网络信息安全公司之一,创始人团队 5 人均为清华博士,并引入阿里云安全核心人才团队。全球首发基于智能语义分析的下一代 Web 应用防火墙产品,目前,公司已形成以攻(安全评估系统)、防(下一代 Web 应用防火墙)、知(安全分析与管理平台)、查(主机安全管理平台)、抓(伪装欺骗系统)为核心的新一代安全防护体系,并提供优质的安全测试及咨询服务,为企业级客户带来智能的全新安全防护思路。
|
||||
|
||||
长亭专注为企业级用户提供专业的网络信息安全解决方案。2016 年即发布基于人工智能语义分析的下一代 Web 应用防火墙,颠覆了传统依赖规则防护的工作原理,为企业用户带来智能、简单、省心的安全产品及服务。
|
||||
|
||||
长亭雷池坚持以技术为导向,产品与服务所涉及到的算法与核心技术均领先国际行业前沿标准,不仅颠覆了繁琐耗时的传统工作原理,更将产品性能提升至领先水准,为企业用户带来更快、更精准、更智能的安全防护。
|
||||
|
||||
## 荣誉 & 资质
|
||||
|
||||
### 2021 年
|
||||
|
||||
- 入选 IDC《中国硬件 Web 应用防火墙(WAF)市场份额》前四
|
||||
- 重磅发布《实战攻防-企业红蓝对抗实践指南》
|
||||
- 荣获 2021 网信自主创新优秀产品 “补天奖”
|
||||
- 荣膺 CNNVD 2020 年度优秀技术支撑单位
|
||||
- 10 项虚拟机漏洞获 Oracle 官方致谢
|
||||
- 入选安全牛第八版中国网络安全行业全景图
|
||||
- 入选 CCSIP 2021 中国网络安全产业全景图
|
||||
- 入选嘶吼 2021 网络安全产业链图谱
|
||||
|
||||
### 2020 年
|
||||
|
||||
- 2020 年金融科技产品创新突出贡献奖
|
||||
- 2020 年网络安全创新能力 100 强
|
||||
- 入选数世咨询《蜜罐诱捕能力指南》
|
||||
- 入选数说安全中国网络安全市场全景图
|
||||
- Network Products Guide IT World Award
|
||||
- 2020 年中国人工智能商业落地价值潜力 100 强
|
||||
- 2020 Application Security and Testing 铜奖
|
||||
- 入选安全牛《2020 中国网络安全企业 100 强报告》
|
||||
- 发现并命名幽灵猫(Ghostcat)漏洞
|
||||
- 联合发布《国家区块链漏洞库-区块链漏洞定级细则》
|
||||
|
||||
### 2019 年
|
||||
|
||||
- 入选 Forrester《Now Tech:Web Application Firewalls, Q4 2019》报告
|
||||
- 2019 年关键信息基础设施“盘古奖”
|
||||
- 荣获《金融电子化》“2019 年度金融科技产品创新突出贡献奖”
|
||||
- 中国网络安全与信息产业 “金智奖” 2019 年度优秀单位
|
||||
|
||||
### 2018 年
|
||||
|
||||
- 通过国家保密局涉密信息系统产品认证
|
||||
- 通信网络安全服务能力一级资质认证
|
||||
- 中国 IT 思想力奖-金融科技产品创新奖
|
||||
- TSRC 2017 最佳客户端洞主 & 年度最佳合作伙伴
|
||||
- 获 Info Security Products Guide 全球卓越奖
|
||||
- 入选《CIO Advisor》亚太地区 25 家最热门人工智能公司
|
||||
- 入围 Gartner 2018《Web 应用防火墙魔力象限报告亚太版》
|
||||
- 2018 年度金融科技优秀产品创新奖
|
||||
- “2018 年度金牌服务机构” 安全服务奖
|
||||
|
||||
### 2017 年
|
||||
|
||||
- OWASP 认证雷池(SafeLine)下一代 Web 应用防火墙
|
||||
- 通过国家测评中心/信息安全服务资质测评单位
|
||||
- Gartner 魔力象限报告提名
|
||||
- 再次登上 Black Hat USA 演讲
|
||||
- 《财富》杂志评选中国创新百强 “人工智能和机器人” 领域全国第一
|
||||
- 受邀出席世界互联网大会网络安全闭门会
|
||||
- 阿里巴巴年度优秀生态合作伙伴
|
||||
- 入选 Cyber Defense Magazine 全球网络安全领导者 Top 25
|
||||
|
||||
### 2016 年
|
||||
|
||||
- ISO9001 国际质量体系认证
|
||||
- ISO27001 国际质量体系认证
|
||||
- 长亭雷池 Web 应用防火墙(增强级)销售许可证
|
||||
- 国家信息安全漏洞库(CNNVD)二级技术支撑单位资质
|
||||
- 中国年度最佳产品奖、IT 行业最具影响力企业奖
|
||||
- 年度特殊贡献奖
|
||||
- GeekPwn 三周年特别贡献奖
|
||||
|
||||
### 2015 年
|
||||
|
||||
- 中国国家高新技术企业称号
|
||||
- 中关村高新技术企业称号
|
||||
- “最具价值安全问题” 荣誉认证
|
||||
- 首次登上 Black Hat USA 演讲
|
7
documents/docs/05-about/_category_.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"label": "关于雷池",
|
||||
"collapsed": false,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
}
|
||||
}
|
162
documents/docusaurus.config.js
Normal file
|
@ -0,0 +1,162 @@
|
|||
// @ts-check
|
||||
// Note: type annotations allow type checking and IDEs autocompletion
|
||||
|
||||
// const lightCodeTheme = require("prism-react-renderer/themes/github");
|
||||
// const darkCodeTheme = require("prism-react-renderer/themes/dracula");
|
||||
|
||||
/** @type {import('@docusaurus/types').Config} */
|
||||
const config = {
|
||||
title: "雷池 WAF 社区版",
|
||||
tagline: "",
|
||||
favicon: "images/favicon.ico",
|
||||
|
||||
// Set the production url of your site here
|
||||
url: "https://waf-ce.chaitin.cn/",
|
||||
// Set the /<baseUrl>/ pathname under which your site is served
|
||||
// For GitHub pages deployment, it is often '/<projectName>/'
|
||||
baseUrl: "/docs",
|
||||
|
||||
// GitHub pages deployment config.
|
||||
// If you aren't using GitHub pages, you don't need these.
|
||||
organizationName: "chaitin", // Usually your GitHub org/user name.
|
||||
projectName: "document", // Usually your repo name.
|
||||
|
||||
onBrokenLinks: "throw",
|
||||
onBrokenMarkdownLinks: "warn",
|
||||
|
||||
// Even if you don't use internalization, you can use this field to set useful
|
||||
// metadata like html lang. For example, if your site is Chinese, you may want
|
||||
// to replace "en" with "zh-Hans".
|
||||
i18n: {
|
||||
defaultLocale: "zh-Hans",
|
||||
locales: ["zh-Hans"],
|
||||
},
|
||||
|
||||
themes: [
|
||||
[
|
||||
// @ts-ignore
|
||||
require.resolve("@easyops-cn/docusaurus-search-local"),
|
||||
/** @type {import("@easyops-cn/docusaurus-search-local").PluginOptions} */
|
||||
// @ts-ignore
|
||||
({
|
||||
docsRouteBasePath: "/",
|
||||
// ... Your options.
|
||||
// `hashed` is recommended as long-term-cache of index file is possible.
|
||||
hashed: true,
|
||||
// For Docs using Chinese, The `language` is recommended to set to:
|
||||
// ```
|
||||
language: ["en", "zh"],
|
||||
// ```
|
||||
}),
|
||||
],
|
||||
],
|
||||
|
||||
presets: [
|
||||
[
|
||||
"classic",
|
||||
/** @type {import('@docusaurus/preset-classic').Options} */
|
||||
({
|
||||
docs: {
|
||||
routeBasePath: "/",
|
||||
sidebarPath: require.resolve("./sidebars.js"),
|
||||
// Remove this to remove the "edit this page" links.
|
||||
// editUrl: "https://github.com/chaitin/safeline/tree/main/website",
|
||||
},
|
||||
blog: false,
|
||||
theme: {
|
||||
customCss: require.resolve("./src/css/custom.css"),
|
||||
},
|
||||
}),
|
||||
],
|
||||
],
|
||||
|
||||
themeConfig:
|
||||
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
|
||||
({
|
||||
// Replace with your project's social card
|
||||
image: "images/safeline.svg",
|
||||
navbar: {
|
||||
title: "",
|
||||
logo: { alt: "Logo", src: "images/safeline.svg", href: "https://waf-ce.chaitin.cn" },
|
||||
items: [
|
||||
{
|
||||
to: "https://www.bilibili.com/medialist/detail/ml2342694989",
|
||||
label: "教学视频",
|
||||
position: "right",
|
||||
},
|
||||
{
|
||||
to: "https://demo.waf-ce.chaitin.cn:9443/dashboard",
|
||||
label: "演示环境",
|
||||
position: "right",
|
||||
},
|
||||
],
|
||||
},
|
||||
footer: {
|
||||
style: "dark",
|
||||
links: [
|
||||
{
|
||||
title: "雷池 SafeLine",
|
||||
items: [
|
||||
{
|
||||
label: "主页",
|
||||
to: "https://waf-ce.chaitin.cn",
|
||||
},
|
||||
{
|
||||
label: "开发计划",
|
||||
to: "https://waf-ce.chaitin.cn/community",
|
||||
},
|
||||
{
|
||||
label: "付费版本",
|
||||
to: "https://waf-ce.chaitin.cn/version",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "资源",
|
||||
items: [
|
||||
// {
|
||||
// label: "技术文档",
|
||||
// to: "/",
|
||||
// },
|
||||
{
|
||||
label: "教学视频",
|
||||
to: "https://www.bilibili.com/medialist/detail/ml2342694989",
|
||||
},
|
||||
// {
|
||||
// label: "学习资料",
|
||||
// to: "/",
|
||||
// },
|
||||
// {
|
||||
// label: "更新日志",
|
||||
// to: "/about/changelog",
|
||||
// },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "关于我们",
|
||||
items: [
|
||||
{
|
||||
label: "长亭科技",
|
||||
to: "https://www.chaitin.cn/zh/",
|
||||
},
|
||||
{
|
||||
label: "CT Stack 安全社区",
|
||||
to: "https://stack.chaitin.cn/",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
copyright: `Copyright © ${new Date().getFullYear()} 北京长亭科技有限公司.All rights reserved.`,
|
||||
},
|
||||
prism: {
|
||||
// theme: lightCodeTheme,
|
||||
// darkTheme: darkCodeTheme,
|
||||
},
|
||||
colorMode: {
|
||||
defaultMode: 'light',
|
||||
disableSwitch: true,
|
||||
},
|
||||
}),
|
||||
};
|
||||
|
||||
module.exports = config;
|
15094
documents/package-lock.json
generated
Normal file
55
documents/package.json
Normal file
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"name": "website",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
"start": "docusaurus start --port 3002",
|
||||
"build": "docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
"clear": "docusaurus clear",
|
||||
"serve": "docusaurus serve",
|
||||
"preview": "docusaurus clear; docusaurus build; docusaurus serve",
|
||||
"write-translations": "docusaurus write-translations",
|
||||
"write-heading-ids": "docusaurus write-heading-ids",
|
||||
"typecheck": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.0.0",
|
||||
"@docusaurus/preset-classic": "3.0.0",
|
||||
"@easyops-cn/docusaurus-search-local": "0.37.4",
|
||||
"@emotion/react": "11.11.1",
|
||||
"@emotion/styled": "11.11.0",
|
||||
"@mdx-js/react": "3.0.0",
|
||||
"@mui/icons-material": "5.14.3",
|
||||
"@mui/lab": "5.0.0-alpha.138",
|
||||
"@mui/material": "5.14.3",
|
||||
"clsx": "^1.2.1",
|
||||
"countup.js": "2.7.0",
|
||||
"prism-react-renderer": "2.1.0",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-responsive-carousel": "3.2.23"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "3.0.0",
|
||||
"@tsconfig/docusaurus": "^1.0.5",
|
||||
"typescript": "5.2.2"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.5%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
}
|
33
documents/sidebars.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
/**
|
||||
* Creating a sidebar enables you to:
|
||||
- create an ordered group of docs
|
||||
- render a sidebar for each doc of that group
|
||||
- provide next/previous navigation
|
||||
|
||||
The sidebars can be generated from the filesystem, or explicitly defined here.
|
||||
|
||||
Create as many sidebars as you want.
|
||||
*/
|
||||
|
||||
// @ts-check
|
||||
|
||||
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
|
||||
const sidebars = {
|
||||
// By default, Docusaurus generates a sidebar from the docs folder structure
|
||||
tutorialSidebar: [{type: 'autogenerated', dirName: '.'}],
|
||||
|
||||
// But you can create a sidebar manually
|
||||
/*
|
||||
tutorialSidebar: [
|
||||
'intro',
|
||||
'hello',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Tutorial',
|
||||
items: ['tutorial-basics/create-a-document'],
|
||||
},
|
||||
],
|
||||
*/
|
||||
};
|
||||
|
||||
module.exports = sidebars;
|
46
documents/src/css/custom.css
Normal file
|
@ -0,0 +1,46 @@
|
|||
/**
|
||||
* Any CSS included here will be global. The classic template
|
||||
* bundles Infima by default. Infima is a CSS framework designed to
|
||||
* work well for content-centric websites.
|
||||
*/
|
||||
|
||||
body {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* You can override the default Infima variables here. */
|
||||
:root {
|
||||
--ifm-color-primary: #0fc6c2;
|
||||
--ifm-breadcrumb-color-active: #0fc6c2;
|
||||
--ifm-menu-color: #000;
|
||||
--ifm-menu-color-active: #0fc6c2;
|
||||
--ifm-link-hover-color: #0fc6c2;
|
||||
--ifm-footer-link-hover-color: #0fc6c2;
|
||||
--ifm-footer-background-color: #121427;
|
||||
--ifm-navbar-link-hover-color: #0fc6c2;
|
||||
--ifm-navbar-background-color: #fff;
|
||||
--ifm-navbar-link-color: #000;
|
||||
}
|
||||
|
||||
/* Overriding root Infima variables */
|
||||
[data-theme="dark"] {
|
||||
--ifm-navbar-background-color: #fff;
|
||||
}
|
||||
|
||||
aside.theme-doc-sidebar-container {
|
||||
width: 240px !important;
|
||||
}
|
||||
|
||||
/* .navbar__toggle.clean-btn svg {
|
||||
color: white;
|
||||
} */
|
||||
|
||||
@media (max-width: 996px) {
|
||||
:root {
|
||||
--ifm-menu-color: #000;
|
||||
}
|
||||
}
|
20
documents/src/theme/Footer/Copyright/index.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
import React from "react";
|
||||
export default function FooterCopyright({ copyright }) {
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="footer__copyright"
|
||||
// Developer provided the HTML, so assume it's safe.
|
||||
// eslint-disable-next-line react/no-danger
|
||||
dangerouslySetInnerHTML={{ __html: copyright }}
|
||||
/>
|
||||
{/* 自定义组件的目的是为了插入 cnzz 统计代码 */}
|
||||
{process.env.NODE_ENV == "production" && (
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="https://v1.cnzz.com/z_stat.php?id=1281262430&web_id=1281262430"
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
0
documents/static/.nojekyll
Normal file
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
BIN
documents/static/images/album/0.png
Normal file
After Width: | Height: | Size: 464 KiB |
BIN
documents/static/images/album/1.png
Normal file
After Width: | Height: | Size: 499 KiB |
BIN
documents/static/images/album/2.png
Normal file
After Width: | Height: | Size: 499 KiB |
BIN
documents/static/images/album/3.png
Normal file
After Width: | Height: | Size: 245 KiB |
BIN
documents/static/images/album/4.png
Normal file
After Width: | Height: | Size: 363 KiB |
BIN
documents/static/images/album/5.png
Normal file
After Width: | Height: | Size: 127 KiB |
BIN
documents/static/images/album/block.png
Normal file
After Width: | Height: | Size: 432 KiB |
BIN
documents/static/images/docs/DNS.png
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
documents/static/images/docs/LoadBlance.png
Normal file
After Width: | Height: | Size: 27 KiB |
77
documents/static/images/docs/Untitled10.svg
Normal file
|
@ -0,0 +1,77 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="938px" height="569px" viewBox="0 0 938 569" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>语义分析检测算法(1)</title>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="-33.3829376%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#F6FEE9" offset="0%"></stop>
|
||||
<stop stop-color="#0FC6C2" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="-33.3829376%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#F6FEE9" offset="0%"></stop>
|
||||
<stop stop-color="#0FC6C2" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="-24.6708029%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#F6FEE9" offset="0%"></stop>
|
||||
<stop stop-color="#0FC6C2" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="-37.157067%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#F6FEE9" offset="0%"></stop>
|
||||
<stop stop-color="#0FC6C2" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<rect id="path-5" x="663" y="445" width="148" height="64" rx="4"></rect>
|
||||
<filter x="-47.3%" y="-78.1%" width="194.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-6">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-7" x="770" y="305" width="128" height="64" rx="4"></rect>
|
||||
<filter x="-54.7%" y="-78.1%" width="209.4%" height="318.8%" filterUnits="objectBoundingBox" id="filter-8">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="官网设计" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="语义分析检测算法(1)" transform="translate(-103.000000, -78.000000)">
|
||||
<g transform="translate(103.000000, 78.000000)">
|
||||
<ellipse id="椭圆形" fill="url(#linearGradient-1)" opacity="0.1" cx="444.5" cy="256" rx="444.5" ry="256"></ellipse>
|
||||
<ellipse id="椭圆形" fill="url(#linearGradient-2)" opacity="0.2" cx="444.5" cy="319" rx="335.111328" ry="193"></ellipse>
|
||||
<ellipse id="椭圆形" fill="url(#linearGradient-3)" opacity="0.303152902" cx="444.5" cy="365" rx="255.240234" ry="147"></ellipse>
|
||||
<ellipse id="椭圆形" fill="url(#linearGradient-4)" opacity="0.395972842" cx="444.787109" cy="385" rx="185.787109" ry="107"></ellipse>
|
||||
<text id="3型文法-正规文法" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="24" font-weight="bold" line-spacing="32" fill="#000000">
|
||||
<tspan x="399.92" y="376">3型文法</tspan>
|
||||
<tspan x="395" y="408">正规文法</tspan>
|
||||
</text>
|
||||
<text id="2型文法-上下文无关文法" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" line-spacing="24" fill="#000000">
|
||||
<tspan x="407.1" y="246">2型文法</tspan>
|
||||
<tspan x="373" y="270">上下文无关文法</tspan>
|
||||
</text>
|
||||
<text id="1型文法-上下文无关文法" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" line-spacing="24" fill="#000000">
|
||||
<tspan x="408.8" y="167">1型文法</tspan>
|
||||
<tspan x="373" y="191">上下文无关文法</tspan>
|
||||
</text>
|
||||
<text id="0型文法-无限制文法" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" line-spacing="24" fill="#000000">
|
||||
<tspan x="407.1" y="54">0型文法</tspan>
|
||||
<tspan x="393" y="78">无限制文法</tspan>
|
||||
</text>
|
||||
<g id="矩形">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-6)" xlink:href="#path-5"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-5"></use>
|
||||
</g>
|
||||
<g id="矩形备份">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-8)" xlink:href="#path-7"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-7"></use>
|
||||
</g>
|
||||
<line x1="770" y1="326.414498" x2="699.740234" y2="265.658884" id="路径-94" stroke="#0FC6C2" stroke-width="2"></line>
|
||||
<line x1="770" y1="338.5" x2="657.70446" y2="338.5" id="路径-110" stroke="#0FC6C2" stroke-width="2"></line>
|
||||
<text id="编程语言" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="794" y="344">编程语言</tspan>
|
||||
</text>
|
||||
<text id="正规表达式" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="687" y="484">正规表达式</tspan>
|
||||
</text>
|
||||
<line x1="663" y1="477" x2="548.522007" y2="436.093667" id="路径-111" stroke="#0FC6C2" stroke-width="2"></line>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.8 KiB |
67
documents/static/images/docs/Untitled11.svg
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="933px" height="144px" viewBox="0 0 933 144" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>语义分析检测算法(2)</title>
|
||||
<defs>
|
||||
<rect id="path-1" x="0" y="0" width="148" height="64" rx="4"></rect>
|
||||
<filter x="-47.3%" y="-78.1%" width="194.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-2">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-3" x="235" y="0" width="148" height="64" rx="4"></rect>
|
||||
<filter x="-47.3%" y="-78.1%" width="194.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-4">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-5" x="470" y="0" width="148" height="64" rx="4"></rect>
|
||||
<filter x="-47.3%" y="-78.1%" width="194.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-6">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-7" x="705" y="0" width="148" height="64" rx="4"></rect>
|
||||
<filter x="-47.3%" y="-78.1%" width="194.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-8">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="官网设计" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="用户-服务器备份-2" transform="translate(-22.000000, -42.000000)">
|
||||
<g id="语义分析检测算法(2)" transform="translate(62.000000, 62.000000)">
|
||||
<g id="矩形备份-2">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
<g id="矩形备份-3">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-3"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-3"></use>
|
||||
</g>
|
||||
<g id="矩形备份-4">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-6)" xlink:href="#path-5"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-5"></use>
|
||||
</g>
|
||||
<g id="矩形备份-5">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-8)" xlink:href="#path-7"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-7"></use>
|
||||
</g>
|
||||
<text id="词法分析" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="34" y="39">词法分析</tspan>
|
||||
</text>
|
||||
<text id="语法分析" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="269" y="39">语法分析</tspan>
|
||||
</text>
|
||||
<text id="语义分析" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="504" y="39">语义分析</tspan>
|
||||
</text>
|
||||
<text id="威胁模型" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="739" y="39">威胁模型</tspan>
|
||||
</text>
|
||||
<path id="路径-104备份-2" d="M219,25 L233,32 L219,39 L219,33 L148,33 L148,31 L219,31 L219,25 Z" fill="#0FC6C2" fill-rule="nonzero"></path>
|
||||
<path id="路径-104备份-3" d="M454,25 L468,32 L454,39 L454,33 L383,33 L383,31 L454,31 L454,25 Z" fill="#0FC6C2" fill-rule="nonzero"></path>
|
||||
<path id="路径-104备份-4" d="M689,25 L703,32 L689,39 L689,33 L618,33 L618,31 L689,31 L689,25 Z" fill="#0FC6C2" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 5.2 KiB |
433
documents/static/images/docs/Untitled12.svg
Normal file
|
@ -0,0 +1,433 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="1320px" height="1444px" viewBox="0 0 1320 1444" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>语义分析检测算法(3)</title>
|
||||
<defs>
|
||||
<rect id="path-1" x="0" y="132" width="177" height="64" rx="4"></rect>
|
||||
<filter x="-39.5%" y="-78.1%" width="179.1%" height="318.8%" filterUnits="objectBoundingBox" id="filter-2">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-3" x="0" y="864" width="177" height="64" rx="4"></rect>
|
||||
<filter x="-39.5%" y="-78.1%" width="179.1%" height="318.8%" filterUnits="objectBoundingBox" id="filter-4">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-5" x="608" y="164" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-6">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-7" x="608" y="896" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-8">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-9" x="608" y="0" width="243" height="92" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-54.3%" width="157.6%" height="252.2%" filterUnits="objectBoundingBox" id="filter-10">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-11" x="608" y="732" width="243" height="92" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-54.3%" width="157.6%" height="252.2%" filterUnits="objectBoundingBox" id="filter-12">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-13" x="997" y="28" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-14">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.258823529 0 0 0 0 0.560784314 0 0 0 0 0.976470588 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-15" x="996" y="760" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-16">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.258823529 0 0 0 0 0.560784314 0 0 0 0 0.976470588 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-17" x="608" y="284" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-18">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-19" x="608" y="1016" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-20">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-21" x="608" y="404" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-22">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-23" x="608" y="1136" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-24">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-25" x="608" y="524" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-26">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-27" x="608" y="1256" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-28">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-29" x="997" y="164" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-30">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.258823529 0 0 0 0 0.560784314 0 0 0 0 0.976470588 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-31" x="997" y="896" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-32">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.258823529 0 0 0 0 0.560784314 0 0 0 0 0.976470588 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-33" x="997" y="284" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-34">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.258823529 0 0 0 0 0.560784314 0 0 0 0 0.976470588 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-35" x="997" y="1016" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-36">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.258823529 0 0 0 0 0.560784314 0 0 0 0 0.976470588 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-37" x="997" y="404" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-38">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.258823529 0 0 0 0 0.560784314 0 0 0 0 0.976470588 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-39" x="997" y="1136" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-40">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.258823529 0 0 0 0 0.560784314 0 0 0 0 0.976470588 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-41" x="997" y="524" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-42">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.258823529 0 0 0 0 0.560784314 0 0 0 0 0.976470588 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-43" x="997" y="1256" width="243" height="64" rx="4"></rect>
|
||||
<filter x="-28.8%" y="-78.1%" width="157.6%" height="318.8%" filterUnits="objectBoundingBox" id="filter-44">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.258823529 0 0 0 0 0.560784314 0 0 0 0 0.976470588 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-45" x="0" y="272" width="177" height="64" rx="4"></rect>
|
||||
<filter x="-39.5%" y="-78.1%" width="179.1%" height="318.8%" filterUnits="objectBoundingBox" id="filter-46">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-47" x="0" y="1004" width="177" height="64" rx="4"></rect>
|
||||
<filter x="-39.5%" y="-78.1%" width="179.1%" height="318.8%" filterUnits="objectBoundingBox" id="filter-48">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-49" x="0" y="412" width="177" height="64" rx="4"></rect>
|
||||
<filter x="-39.5%" y="-78.1%" width="179.1%" height="318.8%" filterUnits="objectBoundingBox" id="filter-50">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-51" x="0" y="1144" width="177" height="64" rx="4"></rect>
|
||||
<filter x="-39.5%" y="-78.1%" width="179.1%" height="318.8%" filterUnits="objectBoundingBox" id="filter-52">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-53" x="0" y="552" width="177" height="64" rx="4"></rect>
|
||||
<filter x="-39.5%" y="-78.1%" width="179.1%" height="318.8%" filterUnits="objectBoundingBox" id="filter-54">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-55" x="0" y="1284" width="177" height="64" rx="4"></rect>
|
||||
<filter x="-39.5%" y="-78.1%" width="179.1%" height="318.8%" filterUnits="objectBoundingBox" id="filter-56">
|
||||
<feOffset dx="0" dy="20" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
|
||||
<feColorMatrix values="0 0 0 0 0.0588235294 0 0 0 0 0.776470588 0 0 0 0 0.760784314 0 0 0 0.2 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="官网设计" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="用户-服务器备份-3" transform="translate(-22.000000, -15.000000)">
|
||||
<g id="语义分析检测算法(3)" transform="translate(62.000000, 35.000000)">
|
||||
<rect id="矩形备份-3" fill-opacity="0.1" fill="#0FC6C2" x="576" y="132" width="306" height="484" rx="4"></rect>
|
||||
<rect id="矩形备份-18" fill-opacity="0.1" fill="#0FC6C2" x="576" y="864" width="306" height="484" rx="4"></rect>
|
||||
<g id="矩形备份-2">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
<g id="矩形备份-19">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-3"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-3"></use>
|
||||
</g>
|
||||
<g id="矩形备份-5">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-6)" xlink:href="#path-5"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-5"></use>
|
||||
</g>
|
||||
<g id="矩形备份-20">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-8)" xlink:href="#path-7"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-7"></use>
|
||||
</g>
|
||||
<g id="矩形备份-12">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-10)" xlink:href="#path-9"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-9"></use>
|
||||
</g>
|
||||
<g id="矩形备份-21">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-12)" xlink:href="#path-11"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-11"></use>
|
||||
</g>
|
||||
<g id="矩形备份-13">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-14)" xlink:href="#path-13"></use>
|
||||
<use fill="#428FF9" fill-rule="evenodd" xlink:href="#path-13"></use>
|
||||
</g>
|
||||
<g id="矩形备份-22">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-16)" xlink:href="#path-15"></use>
|
||||
<use fill="#428FF9" fill-rule="evenodd" xlink:href="#path-15"></use>
|
||||
</g>
|
||||
<g id="矩形备份-9">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-18)" xlink:href="#path-17"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-17"></use>
|
||||
</g>
|
||||
<g id="矩形备份-23">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-20)" xlink:href="#path-19"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-19"></use>
|
||||
</g>
|
||||
<g id="矩形备份-10">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-22)" xlink:href="#path-21"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-21"></use>
|
||||
</g>
|
||||
<g id="矩形备份-24">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-24)" xlink:href="#path-23"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-23"></use>
|
||||
</g>
|
||||
<g id="矩形备份-11">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-26)" xlink:href="#path-25"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-25"></use>
|
||||
</g>
|
||||
<g id="矩形备份-25">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-28)" xlink:href="#path-27"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-27"></use>
|
||||
</g>
|
||||
<rect id="矩形备份-4" fill-opacity="0.1" fill="#428FF9" x="965" y="132" width="306" height="484" rx="4"></rect>
|
||||
<rect id="矩形备份-26" fill-opacity="0.1" fill="#428FF9" x="965" y="864" width="306" height="484" rx="4"></rect>
|
||||
<g id="矩形备份-14">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-30)" xlink:href="#path-29"></use>
|
||||
<use fill="#428FF9" fill-rule="evenodd" xlink:href="#path-29"></use>
|
||||
</g>
|
||||
<g id="矩形备份-27">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-32)" xlink:href="#path-31"></use>
|
||||
<use fill="#428FF9" fill-rule="evenodd" xlink:href="#path-31"></use>
|
||||
</g>
|
||||
<g id="矩形备份-15">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-34)" xlink:href="#path-33"></use>
|
||||
<use fill="#428FF9" fill-rule="evenodd" xlink:href="#path-33"></use>
|
||||
</g>
|
||||
<g id="矩形备份-28">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-36)" xlink:href="#path-35"></use>
|
||||
<use fill="#428FF9" fill-rule="evenodd" xlink:href="#path-35"></use>
|
||||
</g>
|
||||
<g id="矩形备份-16">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-38)" xlink:href="#path-37"></use>
|
||||
<use fill="#428FF9" fill-rule="evenodd" xlink:href="#path-37"></use>
|
||||
</g>
|
||||
<g id="矩形备份-29">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-40)" xlink:href="#path-39"></use>
|
||||
<use fill="#428FF9" fill-rule="evenodd" xlink:href="#path-39"></use>
|
||||
</g>
|
||||
<g id="矩形备份-17">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-42)" xlink:href="#path-41"></use>
|
||||
<use fill="#428FF9" fill-rule="evenodd" xlink:href="#path-41"></use>
|
||||
</g>
|
||||
<g id="矩形备份-30">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-44)" xlink:href="#path-43"></use>
|
||||
<use fill="#428FF9" fill-rule="evenodd" xlink:href="#path-43"></use>
|
||||
</g>
|
||||
<g id="矩形备份-6">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-46)" xlink:href="#path-45"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-45"></use>
|
||||
</g>
|
||||
<g id="矩形备份-31">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-48)" xlink:href="#path-47"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-47"></use>
|
||||
</g>
|
||||
<g id="矩形备份-7">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-50)" xlink:href="#path-49"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-49"></use>
|
||||
</g>
|
||||
<g id="矩形备份-32">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-52)" xlink:href="#path-51"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-51"></use>
|
||||
</g>
|
||||
<g id="矩形备份-8">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-54)" xlink:href="#path-53"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-53"></use>
|
||||
</g>
|
||||
<g id="矩形备份-33">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-56)" xlink:href="#path-55"></use>
|
||||
<use fill="#0FC6C2" fill-rule="evenodd" xlink:href="#path-55"></use>
|
||||
</g>
|
||||
<text id="SQLi-常见攻击" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="24.13" y="171">SQLi 常见攻击</tspan>
|
||||
</text>
|
||||
<text id="SQLi-常见攻击备份" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="24.13" y="903">SQLi 常见攻击</tspan>
|
||||
</text>
|
||||
<text id="1-‘union-select-admi" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#000000">
|
||||
<tspan x="192.5" y="199">1 ‘union select admin from users; #</tspan>
|
||||
</text>
|
||||
<text id="1-‘union-select-admi备份" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#000000">
|
||||
<tspan x="192.5" y="931">1 ‘union select admin from users; #</tspan>
|
||||
</text>
|
||||
<text id="1-‘/**/UnioN/**/SelE" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" line-spacing="32" fill="#000000">
|
||||
<tspan x="193" y="335">1 ‘/**/UnioN/**/SelEct/**/admin/</tspan>
|
||||
<tspan x="193" y="367">**/FrOm/**/users; #</tspan>
|
||||
</text>
|
||||
<text id="1-‘/**/UnioN/**/SelE备份" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" line-spacing="32" fill="#000000">
|
||||
<tspan x="193" y="1067">1 ‘/**/UnioN/**/SelEct/**/admin/</tspan>
|
||||
<tspan x="193" y="1099">**/FrOm/**/users; #</tspan>
|
||||
</text>
|
||||
<text id="(……#iswin?{\`-cmd.ex" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" line-spacing="32" fill="#000000">
|
||||
<tspan x="193" y="475">(……#iswin?{\` cmd.exe\` ,\` /c\` ,#</tspan>
|
||||
<tspan x="193" y="507">cmd};{\` /bin/bash\` ,\` -c\` ,#cmd}…</tspan>
|
||||
</text>
|
||||
<text id="(……#iswin?{\`-cmd.ex备份" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" line-spacing="32" fill="#000000">
|
||||
<tspan x="193" y="1207">(……#iswin?{\` cmd.exe\` ,\` /c\` ,#</tspan>
|
||||
<tspan x="193" y="1239">cmd};{\` /bin/bash\` ,\` -c\` ,#cmd}…</tspan>
|
||||
</text>
|
||||
<text id="We-should-select-the" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" line-spacing="32" fill="#000000">
|
||||
<tspan x="193" y="615">We should select the best students </tspan>
|
||||
<tspan x="193" y="647">from this class as the student union </tspan>
|
||||
<tspan x="193" y="679">presentation</tspan>
|
||||
</text>
|
||||
<text id="We-should-select-the备份" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" line-spacing="32" fill="#000000">
|
||||
<tspan x="193" y="1347">We should select the best students </tspan>
|
||||
<tspan x="193" y="1379">from this class as the student union </tspan>
|
||||
<tspan x="193" y="1411">presentation</tspan>
|
||||
</text>
|
||||
<text id="拦截" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="709.5" y="203">拦截</tspan>
|
||||
</text>
|
||||
<text id="拦截-SQL-引擎-符合-SQL-语法" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="665.39" y="923">拦截 SQL 引擎</tspan>
|
||||
<tspan x="665.39" y="947">符合 SQL 语法</tspan>
|
||||
</text>
|
||||
<text id="拦截-SQL-引擎-符合-SQL-语法" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="665.39" y="1043">拦截 SQL 引擎</tspan>
|
||||
<tspan x="665.39" y="1067">符合 SQL 语法</tspan>
|
||||
</text>
|
||||
<text id="拦截-SQL-引擎-符合-OGNL-表达" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="665.39" y="1163">拦截 SQL 引擎</tspan>
|
||||
<tspan x="646.86" y="1187">符合 OGNL 表达式</tspan>
|
||||
</text>
|
||||
<text id="传统-WAF-特征库命中-预设的多个关键" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="18" font-weight="bold" line-spacing="24" fill="#FFFFFF">
|
||||
<tspan x="642.362" y="27">传统 WAF 特征库命中</tspan>
|
||||
<tspan x="657.5" y="51">预设的多个关键字</tspan>
|
||||
<tspan x="637.682" y="75">select |union|from</tspan>
|
||||
</text>
|
||||
<text id="NGWAF-智能语义分析引擎-(SQL" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="18" font-weight="bold" line-spacing="24" fill="#FFFFFF">
|
||||
<tspan x="697.181" y="759">NGWAF</tspan>
|
||||
<tspan x="657.5" y="783">智能语义分析引擎</tspan>
|
||||
<tspan x="631.562" y="807">(SQL 引擎、ONGL...)</tspan>
|
||||
</text>
|
||||
<text id="真实服务器" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="1068.5" y="67">真实服务器</tspan>
|
||||
</text>
|
||||
<text id="真实服务器备份-2" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="1068.5" y="799">真实服务器</tspan>
|
||||
</text>
|
||||
<text id="真实服务器备份" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="1068.5" y="203">真实服务器</tspan>
|
||||
</text>
|
||||
<text id="不受影响" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="1078.5" y="935">不受影响</tspan>
|
||||
</text>
|
||||
<text id="成功执行" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="1078.5" y="323">成功执行</tspan>
|
||||
</text>
|
||||
<text id="不受影响" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="1078.5" y="1055">不受影响</tspan>
|
||||
</text>
|
||||
<text id="成功执行" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="1078.5" y="443">成功执行</tspan>
|
||||
</text>
|
||||
<text id="不受影响" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="1078.5" y="1175">不受影响</tspan>
|
||||
</text>
|
||||
<text id="正常业务受影响" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="1048.5" y="563">正常业务受影响</tspan>
|
||||
</text>
|
||||
<text id="不受影响" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="1078.5" y="1295">不受影响</tspan>
|
||||
</text>
|
||||
<text id="无规则命中(绕过)" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="639.5" y="323">无规则命中(绕过)</tspan>
|
||||
</text>
|
||||
<text id="无规则命中(无法识别)" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="619.5" y="443">无规则命中(无法识别)</tspan>
|
||||
</text>
|
||||
<text id="命中规则(误拦截)" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="639.5" y="563">命中规则(误拦截)</tspan>
|
||||
</text>
|
||||
<text id="正常请求" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="689.5" y="1295">正常请求</tspan>
|
||||
</text>
|
||||
<text id="SQLi-变种攻击" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="24.13" y="311">SQLi 变种攻击</tspan>
|
||||
</text>
|
||||
<text id="SQLi-变种攻击备份" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="24.13" y="1043">SQLi 变种攻击</tspan>
|
||||
</text>
|
||||
<text id="新型攻击攻击-(Struts2)" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="28.5" y="439">新型攻击攻击</tspan>
|
||||
<tspan x="34.67" y="463">(Struts2)</tspan>
|
||||
</text>
|
||||
<text id="新型攻击攻击-(Struts2)备份" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="28.5" y="1171">新型攻击攻击</tspan>
|
||||
<tspan x="34.67" y="1195">(Struts2)</tspan>
|
||||
</text>
|
||||
<text id="一段英文" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="48" y="591">一段英文</tspan>
|
||||
</text>
|
||||
<text id="一段英文备份" font-family="AlimamaShuHeiTi-Bold, Alimama ShuHeiTi" font-size="20" font-weight="bold" fill="#FFFFFF">
|
||||
<tspan x="48" y="1323">一段英文</tspan>
|
||||
</text>
|
||||
<path id="路径-104备份-5" d="M560,157 L574,164 L560,171 L560,165 L177,165 L177,163 L560,163 L560,157 Z" fill="#0FC6C2" fill-rule="nonzero"></path>
|
||||
<path id="路径-104备份-11" d="M560,889 L574,896 L560,903 L560,897 L177,897 L177,895 L560,895 L560,889 Z" fill="#0FC6C2" fill-rule="nonzero"></path>
|
||||
<path id="路径-104备份-9" d="M955.745131,229.564212 L963.745131,234.064212 L964.519864,234.5 L963.745131,234.935788 L955.745131,239.435788 L955.254869,238.564212 L961.591,235 L882,235 L882,234 L961.591,234 L955.254869,230.435788 L955.745131,229.564212 Z" fill-opacity="0.3" fill="#000000" fill-rule="nonzero"></path>
|
||||
<path id="路径-104备份-12" d="M955.745131,961.564212 L963.745131,966.064212 L964.519864,966.5 L963.745131,966.935788 L955.745131,971.435788 L955.254869,970.564212 L961.591,967 L882,967 L882,966 L961.591,966 L955.254869,962.435788 L955.745131,961.564212 Z" fill-opacity="0.3" fill="#000000" fill-rule="nonzero"></path>
|
||||
<path id="路径-104备份-10" d="M955.745131,369.564212 L963.745131,374.064212 L964.519864,374.5 L963.745131,374.935788 L955.745131,379.435788 L955.254869,378.564212 L961.591,375 L882,375 L882,374 L961.591,374 L955.254869,370.435788 L955.745131,369.564212 Z" fill-opacity="0.3" fill="#000000" fill-rule="nonzero"></path>
|
||||
<path id="路径-104备份-13" d="M955.745131,1101.56421 L963.745131,1106.06421 L964.519864,1106.5 L963.745131,1106.93579 L955.745131,1111.43579 L955.254869,1110.56421 L961.591,1107 L882,1107 L882,1106 L961.591,1106 L955.254869,1102.43579 L955.745131,1101.56421 Z" fill-opacity="0.3" fill="#000000" fill-rule="nonzero"></path>
|
||||
<path id="路径-104备份-6" d="M560,297 L574,304 L560,311 L560,305 L177,305 L177,303 L560,303 L560,297 Z" fill="#0FC6C2" fill-rule="nonzero"></path>
|
||||
<path id="路径-104备份-14" d="M560,1029 L574,1036 L560,1043 L560,1037 L177,1037 L177,1035 L560,1035 L560,1029 Z" fill="#0FC6C2" fill-rule="nonzero"></path>
|
||||
<path id="路径-104备份-7" d="M560,437 L574,444 L560,451 L560,445 L177,445 L177,443 L560,443 L560,437 Z" fill="#0FC6C2" fill-rule="nonzero"></path>
|
||||
<path id="路径-104备份-15" d="M560,1169 L574,1176 L560,1183 L560,1177 L177,1177 L177,1175 L560,1175 L560,1169 Z" fill="#0FC6C2" fill-rule="nonzero"></path>
|
||||
<path id="路径-104备份-8" d="M560,577 L574,584 L560,591 L560,585 L177,585 L177,583 L560,583 L560,577 Z" fill="#0FC6C2" fill-rule="nonzero"></path>
|
||||
<path id="路径-104备份-16" d="M560,1309 L574,1316 L560,1323 L560,1317 L177,1317 L177,1315 L560,1315 L560,1309 Z" fill="#0FC6C2" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 37 KiB |
BIN
documents/static/images/docs/about_changelog/4.2.0-1.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
documents/static/images/docs/about_changelog/4.2.0-2.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
documents/static/images/docs/about_changelog/4.3.0-1.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
documents/static/images/docs/about_changelog/4.3.0-2.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
documents/static/images/docs/about_changelog/5.0.0-1.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
documents/static/images/docs/about_changelog/502_page.png
Normal file
After Width: | Height: | Size: 78 KiB |
BIN
documents/static/images/docs/about_changelog/acl_page.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
documents/static/images/docs/about_changelog/api_assets.png
Normal file
After Width: | Height: | Size: 105 KiB |
After Width: | Height: | Size: 51 KiB |
After Width: | Height: | Size: 87 KiB |
BIN
documents/static/images/docs/about_changelog/cert_create.png
Normal file
After Width: | Height: | Size: 86 KiB |
BIN
documents/static/images/docs/about_changelog/cs_statistics.png
Normal file
After Width: | Height: | Size: 53 KiB |