Compare commits

...

35 Commits

Author SHA1 Message Date
xiaobing.wang
bca9cba2eb feat: 去掉 collie 限制 2024-06-24 14:51:58 +08:00
xiaobing.wang
97dbf6b85c feat: 6.1.3 2024-06-21 19:53:16 +08:00
xiaobing.wang
16cf7385e1 feat: 6.1.2 2024-06-20 18:10:32 +08:00
xiaobing.wang
5fb5277205 fix: change log 2024-06-19 17:39:29 +08:00
xiaobing.wang
97e71288ce fix: show log 2024-06-19 15:35:16 +08:00
xbingW
585b5e441c Merge pull request #942 from awesomeYG/main
fix: discount_end_tip
2024-06-19 10:42:47 +08:00
bens.CN
6561a780ab fix: discount_end_tip 2024-06-18 20:17:37 +08:00
xiaobing.wang
bf9245ec27 fix: docker image 2024-06-18 19:08:02 +08:00
xiaobing.wang
992488972a fix: docker image 2024-06-18 19:06:24 +08:00
xiaobing.wang
6e109d7187 fix: start docker 2024-06-18 18:09:42 +08:00
xiaobing.wang
8d62dedcc1 feat: not -qq 2024-06-18 17:54:38 +08:00
xiaobing.wang
593359fa6f feat: not -q 2024-06-18 17:51:20 +08:00
xiaobing.wang
e85277811e fix: rm azure 2024-06-18 17:44:59 +08:00
xiaobing.wang
51294b5016 fix: docker install 2024-06-17 16:34:31 +08:00
xiaobing.wang
72334ede65 fix upgrade 2024-06-14 20:44:54 +08:00
xiaobing.wang
22e8b6f475 feat: 6.1。1 2024-06-14 20:16:31 +08:00
xiaobing.wang
3f186c046c feat: add Tencent 2024-06-14 19:20:43 +08:00
xiaobing.wang
ec218b269e feat: add Tencent 2024-06-14 19:19:27 +08:00
xiaobing.wang
f92f87be15 feat: rm Tencent 2024-06-14 19:17:46 +08:00
xiaobing.wang
624cddcf7b feat: code style 2024-06-14 19:14:42 +08:00
xiaobing.wang
6d56781e6d feat: code style 2024-06-14 19:14:20 +08:00
xiaobing.wang
86b6bb3441 feat: 6.1.0 2024-06-14 17:50:36 +08:00
xiaobing.wang
fac90ae03d feat: 自动检测国家 2024-06-14 11:30:56 +08:00
xiaobing.wang
3cd6cc6d3b feat: add docker mirror 2024-06-14 11:19:44 +08:00
xiaobing.wang
08945b90d0 feat: add docker install 2024-06-14 10:25:42 +08:00
xbingW
771676b544 Merge pull request #921 from okxlin/main
feat:优化docker安装
2024-06-13 18:32:57 +08:00
safe1ine
150e7778f5 Update README.md 2024-06-12 22:02:51 +08:00
safe1ine
1ee3a2f161 Update README.md 2024-06-12 17:24:53 +08:00
safe1ine
74b5324d2b Update README.md 2024-06-12 16:52:28 +08:00
xbingW
89ec86a4fe Merge pull request #924 from awesomeYG/main
feat: docs link
2024-06-12 16:35:24 +08:00
bens.CN
c8df3d0244 fix: icon 2024-06-12 16:09:54 +08:00
xbingW
edfa792613 Merge pull request #920 from dhsifss/main
feat: mgt mount nginx log
2024-06-12 15:42:38 +08:00
bens.CN
cc591c1a6c feat: docs link 2024-06-12 14:54:22 +08:00
okxlin
c6173276db feat:优化docker安装 2024-06-11 21:35:39 +08:00
姚凯
23a75fd21d feat: mgt mount nginx log 2024-06-11 16:28:15 +08:00
18 changed files with 1209 additions and 371 deletions

View File

@@ -1,5 +1,42 @@
# SAFELINE-CE CHANGELOG
## [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
### 优化

130
README.md
View File

@@ -1,42 +1,49 @@
<h1 align="center">SafeLine, The Best Free WAF For Webmaster</h1>
<p align="center">
<img src="https://raw.githubusercontent.com/chaitin/SafeLine/main/documents/static/images/403.svg" width="160">
</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>
# SafeLine, the best free WAF for webmaster
<p align="center">
<a target="_blank" href="https://waf.chaitin.com/">Home</a> |
<a target="_blank" href="https://demo.waf.chaitin.com:9443/dashboard">Demo</a> |
<a target="_blank" href="https://docs.waf.chaitin.com/">Docs</a> |
<a target="_blank" href="https://discord.gg/wyshSVuvxC">Discord</a> |
<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> &nbsp; | &nbsp;
<a target="_blank" href="https://docs.waf.chaitin.com/">📖Documentation</a> &nbsp; | &nbsp;
<a target="_blank" href="https://demo.waf.chaitin.com:9443/dashboard">🔍Live Demo</a> &nbsp; | &nbsp;
<a target="_blank" href="https://waf-ce.chaitin.cn/">中文版</a>
</p>
SafeLine is a simple, lightweight, locally deployable WAF, it is the best waf for webmaster.
<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> &nbsp;
<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> &nbsp;
<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> &nbsp;
<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>
It serves as a reverse proxy access to protect your website from network attacks that including OWASP attacks, zero-day attacks, web crawlers, vulnerability scanning, vulnerability exploit, http flood and so on.
# Screenshots
- Cumulative installations exceed **130,000** units
- Protecting websites over **1,000,000**
- Processing HTTP requests over **30,000,000,000** times per day
- Intercepting attacks over **50,000,000** times per day
<img src="./images/safeline_en.png" width=600 />
<img src="./images/safeline_en.png" />
# How It Works
<img src="/images/safeline-as-proxy.png" align="right" width=400 />
## Installation
SafeLine is developed based on nginx, it serves as a reverse proxy middleware to detect and cleans web attacks, its core capabilities include:
**中国大陆用户安装国际版可能会导致无法连接云服务,请查看 [中文版安装文档](https://waf-ce.chaitin.cn/docs/guide/install)**
- Defenses for web attacks
- Proactive bot abused defense
- HTML & JS code encryption
- IP-based rate limiting
- Web Access Control List
> Recommended
# Installation
**中国大陆用户安装国际版可能会导致无法连接云服务,请查看** [中文版安装文档](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
> 👍Recommended
Use the following command to start the automated installation of SafeLine. (This process requires root privileges)
@@ -51,11 +58,12 @@ After the command is executed, it means the installation is successfully. Please
to see [Documentation](https://docs.waf.chaitin.com/en/tutorials/install)
## Use Web UI
# 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">
Execute the following command to get administrator account
@@ -78,16 +86,6 @@ Enter the password in the previous step and you will successfully logged into Sa
## Protecting a website
### How SafeLine works
SafeLine is a web application firewall developed based on nginx, designed to help websites defend against network attacks.
Its principle is to act as an http/https reverse proxy, receive network traffic for the original website, then clean the malicious attack traffic and forward the safe and reliable traffic to the original website.
<img src="/images/safeline-as-proxy.png" width=400>
### Proxy a website in SafeLine
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>
@@ -130,59 +128,7 @@ To view the specific details of the attack, click "detail"
<img src="/images/log-detail.png" width=600>
## Core Capabilities
#### Defenses For OWASP Attacks
SafeLine use as an important tool to defense against OWASP Top 10 Attack, such as SQL injection, XSS, Insecure deserialization etc.
#### Defenses For 0-Day Attacks
SafeLine use intelligent rule-free detection algorithm to against 0-Day attacks with unknown attack signatures.
#### Proactive Bot defense
SafeLine uses advanced algorithms to send capthcha challenge for suspicious users to against automated robot attacks.
#### In-Browser Code Encryption
SafeLine can dynamically encrypt and obfuscate static code in the browser (such as HTML, JavaScript) to against reverse engineering.
#### Web Authentication
SafeLine prompting the user for authentication to web apps that lacks valid authentication credentials, Illegal users will be blocked.
#### Web Access Control List
SafeLine offering fine-grained control over traffic allows you to define a set of rules that determine which requests are allowed or denied.
## Features
#### Easy To Use
Deployed by Docker, one command can complete the installation, and you can get started at 0 cost.
The security configuration is ready to use, no manual maintenance is required, and safe lying management can be achieved.
#### High Security Efficacy
The first intelligent semantic analysis algorithm in the industry, accurate detection, low false alarm, and difficult to bypass.
The semantic analysis algorithm has no rules, and you are no longer at a loss when facing 0-day attacks with unknown features.
#### High Performance
Ruleless engine, linear security detection algorithm, average request detection delay at 1 millisecond level.
Strong concurrency, single core easily detects 2000+ TPS, as long as the hardware is strong enough, there is no upper limit to the traffic scale that can be supported.
#### High Availability
The traffic processing engine is developed based on Nginx, and both performance and stability can be guaranteed.
Built-in complete health check mechanism, service availability is as high as 99.99%.
## Star History <a name="star-history"></a>
## 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">

View File

@@ -6,6 +6,46 @@ title: "版本更新记录"
[版本升级方法](/guide/upgrade)
### [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
#### 新增
* 专业版站点详情新增访问日志、错误日志。且支持设置日志大小上限,达到上限后自动清理旧文件
![](/images/docs/about_changelog/6.1.0-1.png)
* 动态防护单站点允许防护的资源数增加到 2 个,专业版增加到 20 个
#### 优化
* 人机验证通过后,若访问/攻击频率过高(达到 3 倍的 “限频后人机验证” 阈值),则要求重新进行人机验证
* 修复导出日志 csv 中的 “动作” 和控制台页面不一致的问题
* 修复动态防护有时仍额外返回源内容的问题
* 修复部分补充规则配置了防护后也会被放行的问题
* 修复编辑证书后,会自动新建证书而不是更新证书的问题
* 修复上游服务器健康检查时,对正常的上游可能返回异常结果 tls internal error 的问题
* 优化一些 UI 交互细节
### [6.0.3] - 2024-06-06
#### 优化

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

View File

@@ -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:
@@ -92,7 +93,7 @@ services:
- ${SAFELINE_DIR}/resources/nginx:/etc/nginx
- ${SAFELINE_DIR}/resources/detector:/resources/detector
- ${SAFELINE_DIR}/resources/chaos:/resources/chaos
- ${SAFELINE_DIR}/logs/nginx:/var/log/nginx
- ${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

744
release/latest/get-docker.sh Executable file
View 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

View File

@@ -9,7 +9,6 @@ echo "
"
export STREAM=${STREAM:-0}
export CDN=${CDN:-1}
qrcode() {
echo "█████████████████████████████████████████"
@@ -104,6 +103,148 @@ local_ips() {
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 "用户手动结束安装"
}
check_depend
docker network rm safeline-ce 2>/dev/null
ips=`local_ips`
subnets="172.22.222 169.254.222 192.168.222"
@@ -114,92 +255,8 @@ for subnet in $subnets; do
fi
done
start_docker() {
systemctl start docker && systemctl enable docker
}
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
cat /proc/cpuinfo | grep ssse3 > /dev/null 2>&1
if [ $support_ssse3 -eq "0" -a $? -ne "0" ]; then
abort "雷池需要运行在支持 ssse3 指令集的 CPU 上,虚拟机请自行配置开启 CPU ssse3 指令集支持"
fi
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
@@ -255,6 +312,15 @@ 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=$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"
else

View File

@@ -9,7 +9,6 @@ echo "
"
export STREAM=${STREAM:-0}
export CDN=${CDN:-1}
echo $1
@@ -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,78 +104,145 @@ 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)
@@ -195,11 +262,6 @@ 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
@@ -209,7 +271,6 @@ curl "https://waf-ce.chaitin.cn/release/latest/compose.yaml" -sSLk -o $compose_n
curl "https://waf-ce.chaitin.cn/release/latest/reset_tengine.sh" -sSLk -o reset_tengine.sh
if [ $? -ne "0" ]; then
mv $compose_name.old $compose_name || true
abort "下载 compose.yaml 脚本失败"
fi
info "下载 compose.yaml 脚本成功"
@@ -232,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"
@@ -251,7 +320,6 @@ info "即将开始下载新版本 Docker 镜像"
$compose_command pull
if [ $? -ne "0" ]; then
mv $compose_name.old $compose_name || true
abort "下载新版本 Docker 镜像失败"
fi
info "下载新版本 Docker 镜像成功"
@@ -263,7 +331,6 @@ docker rm -f safeline-redis &>/dev/null
$compose_command down --remove-orphans && $compose_command up -d
if [ $? -ne "0" ]; then
mv $compose_name.old $compose_name || true
abort "替换 Docker 容器失败"
fi

View File

@@ -1,4 +1,4 @@
{
"latest_version": "v6.0.3",
"rec_version": "v6.0.3"
"latest_version": "v6.1.3",
"rec_version": "v6.1.3"
}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -8,7 +8,7 @@ const LINKS = [
items: [
{
label: "技术文档",
to: "/docs",
to: "https://docs.waf-ce.chaitin.cn/zh/home",
},
{
label: "教学视频",
@@ -16,11 +16,11 @@ const LINKS = [
},
{
label: "学习资料",
to: "/docs",
to: "https://docs.waf-ce.chaitin.cn/zh/home",
},
{
label: "更新日志",
to: "/docs/about/changelog",
to: "https://docs.waf-ce.chaitin.cn/zh/%E7%89%88%E6%9C%AC%E6%9B%B4%E6%96%B0%E8%AE%B0%E5%BD%95",
},
],
},

View File

@@ -14,8 +14,6 @@ import {
ListItemText,
Stack,
IconButton,
MenuItem,
Select,
} from "@mui/material";
import Image from "next/image";
import dynamic from "next/dynamic";
@@ -27,9 +25,9 @@ import usePopupState, {
} from "@/components/Popover/usePopupState";
const navs = [
{ to: "/docs", label: "帮助文档", target: "_blank" },
{ to: "/community", label: "开发计划", target: "_self" },
{ to: "/version", label: "付费版本", target: "_self" },
{ to: "https://docs.waf-ce.chaitin.cn/zh/home", label: "帮助文档", target: "_blank", new: true },
{ to: "/community", label: "开发计划", target: "_self", new: false },
{ to: "/version", label: "付费版本", target: "_self", new: false },
];
const menus = [
@@ -38,11 +36,13 @@ const menus = [
to: "https://github.com/chaitin/SafeLine",
label: "GitHub",
target: "_blank",
new: false,
},
{
to: "https://demo.waf-ce.chaitin.cn:9443/dashboard",
label: "演示 Demo",
target: "_blank",
new: false,
},
];
@@ -56,17 +56,7 @@ const HoverPopover = dynamic(
export default function NavBar() {
const [isSticky, setIsSticky] = useState(false);
const [open, setOpen] = useState(false);
const [langOpen, setLangOpen] = useState(false);
const handleOpen = () => {
setLangOpen(true);
};
const handleClose = () => {
setLangOpen(false);
};
const handleChange = () => {
window.open("https://waf.chaitin.com/");
};
const popoverState = usePopupState({
popupId: "wechat-qrcode-popover",
});
@@ -87,79 +77,7 @@ export default function NavBar() {
window.removeEventListener("scroll", handleScroll);
};
}, []);
const langRender = () => (
<Select
value={"cn"}
label=""
onChange={handleChange}
size="small"
open={langOpen}
onMouseEnter={handleOpen}
onClose={handleClose}
onOpen={handleOpen}
MenuProps={{
PaperProps: {
onMouseLeave: handleClose,
},
}}
renderValue={() => {
return (
<Stack
direction="row"
alignItems="center"
spacing={1}
sx={{ ml: "auto" }}
>
<Box display={{ xs: "none", md: "flex" }}>
<svg
className="icon_svg"
style={{ width: "16px", height: "16px" }}
>
<use xlinkHref="#icon-diqiuyangshi1" />
</svg>
</Box>
<Box></Box>
</Stack>
);
}}
sx={{
border: "none",
fontFamily: "GilroyBold",
px: "4px",
ml: { sx: "auto", md: 1 },
"& fieldset": {
border: langOpen
? "2px solid rgba(15,198,194,0.1)!important"
: "none",
},
"& .MuiSelect-select": { px: "12px" },
}}
className="lang_select"
>
<MenuItem
value="en"
sx={{
"&.Mui-selected": {
bgcolor: "rgba(15,198,194,0.1)!important",
},
"&:hover": { bgcolor: "rgba(15,198,194,0.1)" },
}}
>
English
</MenuItem>
<MenuItem
value="cn"
sx={{
"&.Mui-selected": {
bgcolor: "rgba(15,198,194,0.1)!important",
},
"&:hover": { bgcolor: "rgba(15,198,194,0.1)" },
}}
>
</MenuItem>
</Select>
);
return (
<>
<AppBar
@@ -182,19 +100,19 @@ export default function NavBar() {
>
<Grid container justifyContent="space-around">
<Grid item xs={10} md={6} display="flex">
<Box display="flex" alignItems="center" sx={{ width: "100%" }}>
<Box display="flex" alignItems="center">
<SafelineTitle />
{langRender()}
<Box display={{ xs: "none", md: "flex" }} alignItems="center">
{navs.map((nav, index) => (
<Box component="span" key={index} mr={3.5}>
<Link
key={index}
href={nav.to}
sx={{ color: "common.black" }}
sx={{ color: "common.black",lineHeight: '45px' }}
target={nav.target}
>
{nav.label}
{nav.new && <Icon type="icon-new" sx={{ ml: '4px', fontSize: '26px' }} />}
</Link>
</Box>
))}
@@ -221,9 +139,24 @@ export default function NavBar() {
}}
mr={3.5}
>
<Icon type="icon-discord1" sx={{ mr: 1 }} />
<Icon type="icon-icon-17" sx={{ mr: 1 }} />
Discord
</Link>
<Link
href="https://x.com/safeline_waf"
target="_blank"
sx={{
color: "common.black",
display: "flex",
"&:hover": {
color: "primary.main",
},
}}
mr={3.5}
>
<Icon type="icon-tuite3" sx={{ mr: 1, fontSize: '16px' }} />
X
</Link>
<Link
href="https://github.com/chaitin/SafeLine"
target="_blank"
@@ -280,10 +213,7 @@ export default function NavBar() {
<Button
variant="contained"
target="_blank"
sx={{
width: { xs: "100%", sm: "auto" },
textTransform: "none",
}}
sx={{ width: { xs: "100%", sm: "auto" } }}
href="https://demo.waf-ce.chaitin.cn:9443/dashboard"
>
Demo
@@ -362,27 +292,27 @@ export const SafelineTitle: React.FC = () => {
flexDirection="row"
display="flex"
spacing={2}
sx={{ marginTop: "0px", flexWrap: "nowrap" }}
sx={{ marginTop: "0px", minWidth: "192px" }}
>
<Box
width={{ xs: "30px", md: "24px" }}
height={{ xs: "33px", md: "26px" }}
width={{ xs: "40px", md: "24px" }}
height={{ xs: "43px", md: "26px" }}
position="relative"
>
<Image
src="/images/safeline.svg"
alt="SafeLine Logo"
layout="responsive"
width={30}
height={33}
width={40}
height={43}
/>
</Box>
<Typography
variant="h6"
sx={{
ml: { xs: "4px", md: 1 },
mr: { xs: 0, md: 0 },
fontSize: { xs: "20px", md: "16px" },
ml: { xs: 2, md: 1 },
mr: { xs: 0, md: 7 },
fontSize: { xs: "24px", md: "16px" },
display: "flex",
alignItems: "center",
fontFamily: "AlimamaShuHeiTi-Bold",

View File

@@ -27,7 +27,7 @@ const VERSION_LIST = [
my: 4,
boxShadow: "0px 15px 25px 0px rgba(15,198,194,0.3)",
}}
href="/docs/guide/install"
href="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"
>
</Button>
@@ -49,7 +49,7 @@ const VERSION_LIST = [
fee: "¥1799",
fee_desc: "/年",
desc: (
<Stack direction="row" justifyContent="center">
<Stack direction="row" justifyContent="center" sx={{position: 'relative'}}>
<Typography
variant="subtitle2"
mr={1}
@@ -62,10 +62,17 @@ const VERSION_LIST = [
¥3600 /
</Typography>
<Image
src="/images/discount.svg"
src="/images/discount_end_tip.png"
alt="限时特惠"
width={76}
height={20}
width={106}
height={22}
/>
<Image
src="/images/discount_end_balloon.png"
alt="限时特惠"
width={60}
height={50}
style={{position: 'absolute',right: -34, top: -55}}
/>
</Stack>
),

View File

@@ -6,22 +6,22 @@ import Icon from "@/components/Icon";
const ABILITY_LIST = [
{
title: "人机验证",
href: "/docs/about/challenge",
href: "https://docs.waf-ce.chaitin.cn/zh/%E4%B8%8A%E6%89%8B%E6%8C%87%E5%8D%97/%E5%BF%AB%E9%80%9F%E9%85%8D%E7%BD%AE",
img: "/images/ability/ability_verification.png",
},
{
title: "百川网站监控联动",
href: "/docs/practice/monitor",
href: "https://docs.waf-ce.chaitin.cn/%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5/%E7%99%BE%E5%B7%9D%E7%BD%91%E7%AB%99%E7%9B%91%E6%B5%8B",
img: "/images/ability/ability_rivers.png",
},
{
title: "APISIX 插件集成",
href: "/docs/practice/apisix",
href: "https://docs.waf-ce.chaitin.cn/zh/%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5/%E8%81%94%E5%8A%A8APISIX",
img: "/images/ability/ability_apisix.svg",
},
{
title: "长亭社区恶意 IP 情报",
href: "/docs/practice/IpIntelligence",
href: "https://docs.waf-ce.chaitin.cn/",
img: "/images/ability/ability_maliciousip.svg",
},
{

View File

@@ -42,7 +42,7 @@ const FEATURE_LIST = [
mb: { xs: 2, sm: 0 },
fontSize: { xs: "24px", sm: "14px" },
}}
href="/docs/about/syntaxanalysis"
href="https://docs.waf-ce.chaitin.cn/"
>
</Button>

View File

@@ -217,7 +217,7 @@ export default function Home({ total, starCount }: { total: number, starCount: n
fontSize: { xs: "32px", sm: "20px" },
boxShadow: "0px 15px 25px 0px rgba(15,198,194,0.3)",
}}
href="/docs/guide/install"
href="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"
>
</Button>