diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml index 319d908..c0a596e 100644 --- a/.github/workflows/ci-test.yml +++ b/.github/workflows/ci-test.yml @@ -57,7 +57,7 @@ jobs: BUILDTIME=$(date +'%Y%m%d') go build \ -ldflags="-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RUNTIME_WIN7_VERSION=false -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=${BUILDTIME} -X SamWaf/global.GWAF_RELEASE_VERSION=v1.0.0-beta.1 -s -w -extldflags '-static'" \ - -o ./SamWafLinux64 main.go + -o ./SamWafLinux64 ./cmd/samwaf/main.go - name: Test Linux binary timeout-minutes: 2 @@ -152,7 +152,7 @@ jobs: BUILDTIME=$(date +'%Y%m%d') go build \ -ldflags="-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RUNTIME_WIN7_VERSION=false -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=${BUILDTIME} -X SamWaf/global.GWAF_RELEASE_VERSION=v1.0.0-beta.1 -s -w -extldflags '-static'" \ - -o ./SamWaf64.exe main.go + -o ./SamWaf64.exe ./cmd/samwaf/main.go - name: Check Windows binary run: | diff --git a/.github/workflows/goreleaser.yml b/.github/workflows/goreleaser.yml index 822a470..f527e1e 100644 --- a/.github/workflows/goreleaser.yml +++ b/.github/workflows/goreleaser.yml @@ -192,13 +192,13 @@ jobs: echo "Building macOS AMD64..." GOOS=darwin GOARCH=amd64 go build \ -ldflags="-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RUNTIME_WIN7_VERSION=false -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=${BUILDTIME} -X SamWaf/global.GWAF_RELEASE_VERSION=${CURRENT_TAG} -s -w" \ - -o ./dist/SamWafDarwinAmd64 main.go + -o ./dist/SamWafDarwinAmd64 ./cmd/samwaf/main.go # 编译 ARM64 版本 (Apple Silicon) echo "Building macOS ARM64..." GOOS=darwin GOARCH=arm64 go build \ -ldflags="-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RUNTIME_WIN7_VERSION=false -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=${BUILDTIME} -X SamWaf/global.GWAF_RELEASE_VERSION=${CURRENT_TAG} -s -w" \ - -o ./dist/SamWafDarwinArm64 main.go + -o ./dist/SamWafDarwinArm64 ./cmd/samwaf/main.go # 创建压缩包 mkdir -p release @@ -307,7 +307,7 @@ jobs: BUILDTIME: ${{ env.BUILDTIME }} CURRENT_TAG: ${{ env.CURRENT_TAG }} run: | - go build -ldflags="-X SamWaf/global.GWAF_RUNTIME_WIN7_VERSION=true -X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=${BUILDTIME} -X SamWaf/global.GWAF_RELEASE_VERSION=${CURRENT_TAG} -s -w -extldflags '-static'" -o ./release/SamWaf64ForWin7Win8Win2008.exe main.go + go build -ldflags="-X SamWaf/global.GWAF_RUNTIME_WIN7_VERSION=true -X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=${BUILDTIME} -X SamWaf/global.GWAF_RELEASE_VERSION=${CURRENT_TAG} -s -w -extldflags '-static'" -o ./release/SamWaf64ForWin7Win8Win2008.exe ./cmd/samwaf/main.go - name: Archive artifacts if: steps.check_win7_build.outputs.skip_win7_build != 'true' diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 6f38b01..bd96f69 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -24,6 +24,7 @@ builds: # 正式发布版本 (Release builds) - id: "samwaf_linux" binary: "SamWafLinux64" + main: ./cmd/samwaf env: - CGO_ENABLED=1 - CC=x86_64-linux-musl-gcc @@ -43,6 +44,7 @@ builds: - -extldflags "-static" - id: "samwaf_win" binary: "SamWaf64" + main: ./cmd/samwaf env: - CGO_ENABLED=1 - CC=x86_64-w64-mingw32-gcc @@ -61,6 +63,7 @@ builds: - -extldflags "-static" - id: "samwaf_linux_arm64" binary: "SamWafLinuxArm64" + main: ./cmd/samwaf env: - CGO_ENABLED=1 - CC=aarch64-linux-gnu-gcc @@ -81,6 +84,7 @@ builds: # Debug版本 (Debug builds for troubleshooting only) - id: "samwaf_linux_debug" binary: "SamWafLinux64-DEBUG-SYMBOLS" + main: ./cmd/samwaf env: - CGO_ENABLED=1 - CC=x86_64-linux-musl-gcc @@ -99,6 +103,7 @@ builds: - -extldflags "-static" - id: "samwaf_win_debug" binary: "SamWaf64-DEBUG-SYMBOLS" + main: ./cmd/samwaf env: - CGO_ENABLED=1 - CC=x86_64-w64-mingw32-gcc @@ -116,6 +121,7 @@ builds: - -extldflags "-static" - id: "samwaf_linux_arm64_debug" binary: "SamWafLinuxArm64-DEBUG-SYMBOLS" + main: ./cmd/samwaf env: - CGO_ENABLED=1 - CC=aarch64-linux-gnu-gcc diff --git a/build-releases-mac-amd.bat b/build-releases-mac-amd.bat index 2c18ea1..047cfe8 100644 --- a/build-releases-mac-amd.bat +++ b/build-releases-mac-amd.bat @@ -2,4 +2,4 @@ SET CGO_ENABLED=1 SET GOOS=darwin SET GOARCH=amd64 SET GIN_MODE=release -go build -ldflags="-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=20251216 -X SamWaf/global.GWAF_RELEASE_VERSION=v1.3.18 -s -w" -o %cd%/release/SamWafDarwinAmd64.exe main.go \ No newline at end of file +go build -ldflags="-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=20251216 -X SamWaf/global.GWAF_RELEASE_VERSION=v1.3.18 -s -w" -o %cd%/release/SamWafDarwinAmd64.exe ./cmd/samwaf/main.go \ No newline at end of file diff --git a/build-releases-mac-arm.bat b/build-releases-mac-arm.bat index 9fbe50d..82ce11a 100644 --- a/build-releases-mac-arm.bat +++ b/build-releases-mac-arm.bat @@ -2,4 +2,4 @@ SET CGO_ENABLED=1 SET GOOS=darwin SET GOARCH=arm64 SET GIN_MODE=release -go build -ldflags="-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=20251216 -X SamWaf/global.GWAF_RELEASE_VERSION=v1.3.18 -s -w" -o %cd%/release/SamWafDarwinArm64.exe main.go \ No newline at end of file +go build -ldflags="-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=20251216 -X SamWaf/global.GWAF_RELEASE_VERSION=v1.3.18 -s -w" -o %cd%/release/SamWafDarwinArm64.exe ./cmd/samwaf/main.go \ No newline at end of file diff --git a/build-releases-win-upx.bat b/build-releases-win-upx.bat index 461ccce..31648e1 100644 --- a/build-releases-win-upx.bat +++ b/build-releases-win-upx.bat @@ -2,4 +2,4 @@ SET CGO_ENABLED=1 SET GOOS=windows SET GOARCH=amd64 SET GIN_MODE=release -go build -ldflags="-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=20251216 -X SamWaf/global.GWAF_RELEASE_VERSION=v1.3.18 -s -w" -o %cd%/release/SamWaf64.exe main.go \ No newline at end of file +go build -ldflags="-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=20251216 -X SamWaf/global.GWAF_RELEASE_VERSION=v1.3.18 -s -w" -o %cd%/release/SamWaf64.exe ./cmd/samwaf/main.go \ No newline at end of file diff --git a/build-releases-win7-upx.bat b/build-releases-win7-upx.bat index 8842305..3a2f201 100644 --- a/build-releases-win7-upx.bat +++ b/build-releases-win7-upx.bat @@ -2,4 +2,4 @@ SET CGO_ENABLED=1 SET GOOS=windows SET GOARCH=amd64 SET GIN_MODE=release -go build -ldflags="-X SamWaf/global.GWAF_RUNTIME_WIN7_VERSION=true -X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=20251216 -X SamWaf/global.GWAF_RELEASE_VERSION=v1.3.18 -s -w" -o %cd%/release/SamWaf64.exe main.go && %cd%/upx/win64/upx -9 %cd%/release/SamWaf64.exe \ No newline at end of file +go build -ldflags="-X SamWaf/global.GWAF_RUNTIME_WIN7_VERSION=true -X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=20251216 -X SamWaf/global.GWAF_RELEASE_VERSION=v1.3.18 -s -w" -o %cd%/release/SamWaf64.exe ./cmd/samwaf/main.go && %cd%/upx/win64/upx -9 %cd%/release/SamWaf64.exe \ No newline at end of file diff --git a/build_docker_release_linux.bat b/build_docker_release_linux.bat index c5e7076..557caa1 100644 --- a/build_docker_release_linux.bat +++ b/build_docker_release_linux.bat @@ -1 +1 @@ -docker run --rm -v C:/huawei/goproject/SamWaf:/src -w /src -e CGO_ENABLED=1 -e GOOS=linux -e GOARCH=amd64 -e GOPROXY=https://goproxy.cn,direct golang:1.24.7 sh -c "go build -v -ldflags='-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=20251216 -X SamWaf/global.GWAF_RELEASE_VERSION=v1.3.18 -s -w -extldflags \"-static\"' -o /src/release/SamWafLinux64 main.go" \ No newline at end of file +docker run --rm -v C:/huawei/goproject/SamWaf:/src -w /src -e CGO_ENABLED=1 -e GOOS=linux -e GOARCH=amd64 -e GOPROXY=https://goproxy.cn,direct golang:1.24.7 sh -c "go build -v -ldflags='-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=20251216 -X SamWaf/global.GWAF_RELEASE_VERSION=v1.3.18 -s -w -extldflags \"-static\"' -o /src/release/SamWafLinux64 ./cmd/samwaf/main.go" \ No newline at end of file diff --git a/exedata/GeoLite2-Country.mmdb b/cmd/samwaf/exedata/GeoLite2-Country.mmdb similarity index 100% rename from exedata/GeoLite2-Country.mmdb rename to cmd/samwaf/exedata/GeoLite2-Country.mmdb diff --git a/cmd/samwaf/exedata/TEMPLATE_VERSION.md b/cmd/samwaf/exedata/TEMPLATE_VERSION.md new file mode 100644 index 0000000..a939ce7 --- /dev/null +++ b/cmd/samwaf/exedata/TEMPLATE_VERSION.md @@ -0,0 +1,53 @@ +# 模板版本记录 + +## 说明 +此文件用于记录HTML模板的版本信息,**不要在HTML文件中添加版本注释**,以免泄露系统信息。 + +## 版本历史 + +### Captcha 传统验证码模板 +- **当前版本**: 1.0.3 +- **更新日期**: 2026-01-05 +- **文件**: exedata/captcha/index.html +- **更新内容**: + - 移除版本注释以隐藏系统特征 + - 路径由后端动态替换 + +### CapJs 工作量证明验证码模板 +- **当前版本**: 1.0.2 +- **更新日期**: 2026-01-05 +- **文件**: exedata/capjs/index.html +- **更新内容**: + - 移除版本注释以隐藏系统特征 + - 路径由后端动态替换 + +### HTTP认证登录模板 +- **当前版本**: 1.0.20260105 +- **更新日期**: 2026-01-05 +- **文件**: exedata/httpauth/login.html +- **更新内容**: + - 移除版本注释以隐藏系统特征 + - 路径由后端动态替换 + +## 重要提醒 + +⚠️ **永远不要在HTML模板中添加以下内容:** +- 版本号注释 +- "SamWAF" 字样 +- 技术实现说明 +- 任何可能暴露系统特征的信息 + +✅ **版本信息记录在:** +- `version` 文件(纯文本,不对外暴露) +- 本文档(内部文档) +- Git提交记录 + +## 安全检查清单 + +在修改HTML模板时,请确保: +- [ ] 没有HTML注释包含敏感信息 +- [ ] 没有明显的系统特征标识 +- [ ] 路径使用占位符(如 /samwaf_xxx/)等待后端替换 +- [ ] CSS/JS类名不包含 "samwaf" 等特征 +- [ ] 错误消息不泄露技术细节 + diff --git a/exedata/capjs/cap_wasm.min.js b/cmd/samwaf/exedata/capjs/cap_wasm.min.js similarity index 100% rename from exedata/capjs/cap_wasm.min.js rename to cmd/samwaf/exedata/capjs/cap_wasm.min.js diff --git a/exedata/capjs/cap_wasm_bg.wasm b/cmd/samwaf/exedata/capjs/cap_wasm_bg.wasm similarity index 100% rename from exedata/capjs/cap_wasm_bg.wasm rename to cmd/samwaf/exedata/capjs/cap_wasm_bg.wasm diff --git a/exedata/capjs/capversion b/cmd/samwaf/exedata/capjs/capversion similarity index 100% rename from exedata/capjs/capversion rename to cmd/samwaf/exedata/capjs/capversion diff --git a/exedata/capjs/index.html b/cmd/samwaf/exedata/capjs/index.html similarity index 100% rename from exedata/capjs/index.html rename to cmd/samwaf/exedata/capjs/index.html diff --git a/exedata/capjs/version b/cmd/samwaf/exedata/capjs/version similarity index 100% rename from exedata/capjs/version rename to cmd/samwaf/exedata/capjs/version diff --git a/exedata/capjs/widget.js b/cmd/samwaf/exedata/capjs/widget.js similarity index 100% rename from exedata/capjs/widget.js rename to cmd/samwaf/exedata/capjs/widget.js diff --git a/exedata/captcha/css/gocaptcha.global.css b/cmd/samwaf/exedata/captcha/css/gocaptcha.global.css similarity index 100% rename from exedata/captcha/css/gocaptcha.global.css rename to cmd/samwaf/exedata/captcha/css/gocaptcha.global.css diff --git a/exedata/captcha/css/toastify.css b/cmd/samwaf/exedata/captcha/css/toastify.css similarity index 100% rename from exedata/captcha/css/toastify.css rename to cmd/samwaf/exedata/captcha/css/toastify.css diff --git a/exedata/captcha/favicon.ico b/cmd/samwaf/exedata/captcha/favicon.ico similarity index 100% rename from exedata/captcha/favicon.ico rename to cmd/samwaf/exedata/captcha/favicon.ico diff --git a/exedata/captcha/index.html b/cmd/samwaf/exedata/captcha/index.html similarity index 100% rename from exedata/captcha/index.html rename to cmd/samwaf/exedata/captcha/index.html diff --git a/exedata/captcha/js/axios.js b/cmd/samwaf/exedata/captcha/js/axios.js similarity index 100% rename from exedata/captcha/js/axios.js rename to cmd/samwaf/exedata/captcha/js/axios.js diff --git a/exedata/captcha/js/gocaptcha.global.js b/cmd/samwaf/exedata/captcha/js/gocaptcha.global.js similarity index 100% rename from exedata/captcha/js/gocaptcha.global.js rename to cmd/samwaf/exedata/captcha/js/gocaptcha.global.js diff --git a/exedata/captcha/js/qs.js b/cmd/samwaf/exedata/captcha/js/qs.js similarity index 100% rename from exedata/captcha/js/qs.js rename to cmd/samwaf/exedata/captcha/js/qs.js diff --git a/exedata/captcha/js/toastify.js b/cmd/samwaf/exedata/captcha/js/toastify.js similarity index 100% rename from exedata/captcha/js/toastify.js rename to cmd/samwaf/exedata/captcha/js/toastify.js diff --git a/exedata/captcha/version b/cmd/samwaf/exedata/captcha/version similarity index 100% rename from exedata/captcha/version rename to cmd/samwaf/exedata/captcha/version diff --git a/exedata/httpauth/lock.txt.example b/cmd/samwaf/exedata/httpauth/lock.txt.example similarity index 100% rename from exedata/httpauth/lock.txt.example rename to cmd/samwaf/exedata/httpauth/lock.txt.example diff --git a/exedata/httpauth/login.html b/cmd/samwaf/exedata/httpauth/login.html similarity index 100% rename from exedata/httpauth/login.html rename to cmd/samwaf/exedata/httpauth/login.html diff --git a/exedata/httpauth/version b/cmd/samwaf/exedata/httpauth/version similarity index 100% rename from exedata/httpauth/version rename to cmd/samwaf/exedata/httpauth/version diff --git a/exedata/ip2region.xdb b/cmd/samwaf/exedata/ip2region.xdb similarity index 100% rename from exedata/ip2region.xdb rename to cmd/samwaf/exedata/ip2region.xdb diff --git a/exedata/ldpconfig.yml b/cmd/samwaf/exedata/ldpconfig.yml similarity index 100% rename from exedata/ldpconfig.yml rename to cmd/samwaf/exedata/ldpconfig.yml diff --git a/exedata/owasp/coraza.conf b/cmd/samwaf/exedata/owasp/coraza.conf similarity index 100% rename from exedata/owasp/coraza.conf rename to cmd/samwaf/exedata/owasp/coraza.conf diff --git a/exedata/owasp/coreruleset/crs-setup.conf b/cmd/samwaf/exedata/owasp/coreruleset/crs-setup.conf similarity index 100% rename from exedata/owasp/coreruleset/crs-setup.conf rename to cmd/samwaf/exedata/owasp/coreruleset/crs-setup.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example diff --git a/exedata/owasp/coreruleset/rules/REQUEST-901-INITIALIZATION.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-901-INITIALIZATION.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-901-INITIALIZATION.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-901-INITIALIZATION.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-905-COMMON-EXCEPTIONS.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-905-COMMON-EXCEPTIONS.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-905-COMMON-EXCEPTIONS.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-905-COMMON-EXCEPTIONS.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-911-METHOD-ENFORCEMENT.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-911-METHOD-ENFORCEMENT.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-911-METHOD-ENFORCEMENT.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-911-METHOD-ENFORCEMENT.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-913-SCANNER-DETECTION.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-913-SCANNER-DETECTION.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-913-SCANNER-DETECTION.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-913-SCANNER-DETECTION.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-920-PROTOCOL-ENFORCEMENT.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-921-PROTOCOL-ATTACK.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-921-PROTOCOL-ATTACK.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-921-PROTOCOL-ATTACK.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-921-PROTOCOL-ATTACK.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-922-MULTIPART-ATTACK.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-922-MULTIPART-ATTACK.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-922-MULTIPART-ATTACK.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-922-MULTIPART-ATTACK.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-930-APPLICATION-ATTACK-LFI.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-931-APPLICATION-ATTACK-RFI.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-932-APPLICATION-ATTACK-RCE.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-933-APPLICATION-ATTACK-PHP.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-934-APPLICATION-ATTACK-GENERIC.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-934-APPLICATION-ATTACK-GENERIC.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-934-APPLICATION-ATTACK-GENERIC.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-934-APPLICATION-ATTACK-GENERIC.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-941-APPLICATION-ATTACK-XSS.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-942-APPLICATION-ATTACK-SQLI.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-943-APPLICATION-ATTACK-SESSION-FIXATION.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-944-APPLICATION-ATTACK-JAVA.conf diff --git a/exedata/owasp/coreruleset/rules/REQUEST-949-BLOCKING-EVALUATION.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-949-BLOCKING-EVALUATION.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/REQUEST-949-BLOCKING-EVALUATION.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/REQUEST-949-BLOCKING-EVALUATION.conf diff --git a/exedata/owasp/coreruleset/rules/RESPONSE-950-DATA-LEAKAGES.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-950-DATA-LEAKAGES.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/RESPONSE-950-DATA-LEAKAGES.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-950-DATA-LEAKAGES.conf diff --git a/exedata/owasp/coreruleset/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-951-DATA-LEAKAGES-SQL.conf diff --git a/exedata/owasp/coreruleset/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-952-DATA-LEAKAGES-JAVA.conf diff --git a/exedata/owasp/coreruleset/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-953-DATA-LEAKAGES-PHP.conf diff --git a/exedata/owasp/coreruleset/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-954-DATA-LEAKAGES-IIS.conf diff --git a/exedata/owasp/coreruleset/rules/RESPONSE-955-WEB-SHELLS.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-955-WEB-SHELLS.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/RESPONSE-955-WEB-SHELLS.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-955-WEB-SHELLS.conf diff --git a/exedata/owasp/coreruleset/rules/RESPONSE-959-BLOCKING-EVALUATION.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-959-BLOCKING-EVALUATION.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/RESPONSE-959-BLOCKING-EVALUATION.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-959-BLOCKING-EVALUATION.conf diff --git a/exedata/owasp/coreruleset/rules/RESPONSE-980-CORRELATION.conf b/cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-980-CORRELATION.conf similarity index 100% rename from exedata/owasp/coreruleset/rules/RESPONSE-980-CORRELATION.conf rename to cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-980-CORRELATION.conf diff --git a/exedata/owasp/coreruleset/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example b/cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example similarity index 100% rename from exedata/owasp/coreruleset/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example rename to cmd/samwaf/exedata/owasp/coreruleset/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf.example diff --git a/exedata/owasp/coreruleset/rules/iis-errors.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/iis-errors.data similarity index 100% rename from exedata/owasp/coreruleset/rules/iis-errors.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/iis-errors.data diff --git a/exedata/owasp/coreruleset/rules/java-classes.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/java-classes.data similarity index 100% rename from exedata/owasp/coreruleset/rules/java-classes.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/java-classes.data diff --git a/exedata/owasp/coreruleset/rules/java-code-leakages.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/java-code-leakages.data similarity index 100% rename from exedata/owasp/coreruleset/rules/java-code-leakages.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/java-code-leakages.data diff --git a/exedata/owasp/coreruleset/rules/java-errors.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/java-errors.data similarity index 100% rename from exedata/owasp/coreruleset/rules/java-errors.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/java-errors.data diff --git a/exedata/owasp/coreruleset/rules/lfi-os-files.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/lfi-os-files.data similarity index 100% rename from exedata/owasp/coreruleset/rules/lfi-os-files.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/lfi-os-files.data diff --git a/exedata/owasp/coreruleset/rules/php-config-directives.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/php-config-directives.data similarity index 100% rename from exedata/owasp/coreruleset/rules/php-config-directives.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/php-config-directives.data diff --git a/exedata/owasp/coreruleset/rules/php-errors-pl2.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/php-errors-pl2.data similarity index 100% rename from exedata/owasp/coreruleset/rules/php-errors-pl2.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/php-errors-pl2.data diff --git a/exedata/owasp/coreruleset/rules/php-errors.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/php-errors.data similarity index 100% rename from exedata/owasp/coreruleset/rules/php-errors.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/php-errors.data diff --git a/exedata/owasp/coreruleset/rules/php-function-names-933150.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/php-function-names-933150.data similarity index 100% rename from exedata/owasp/coreruleset/rules/php-function-names-933150.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/php-function-names-933150.data diff --git a/exedata/owasp/coreruleset/rules/php-function-names-933151.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/php-function-names-933151.data similarity index 100% rename from exedata/owasp/coreruleset/rules/php-function-names-933151.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/php-function-names-933151.data diff --git a/exedata/owasp/coreruleset/rules/php-variables.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/php-variables.data similarity index 100% rename from exedata/owasp/coreruleset/rules/php-variables.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/php-variables.data diff --git a/exedata/owasp/coreruleset/rules/restricted-files.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/restricted-files.data similarity index 100% rename from exedata/owasp/coreruleset/rules/restricted-files.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/restricted-files.data diff --git a/exedata/owasp/coreruleset/rules/restricted-upload.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/restricted-upload.data similarity index 100% rename from exedata/owasp/coreruleset/rules/restricted-upload.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/restricted-upload.data diff --git a/exedata/owasp/coreruleset/rules/scanners-user-agents.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/scanners-user-agents.data similarity index 100% rename from exedata/owasp/coreruleset/rules/scanners-user-agents.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/scanners-user-agents.data diff --git a/exedata/owasp/coreruleset/rules/sql-errors.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/sql-errors.data similarity index 100% rename from exedata/owasp/coreruleset/rules/sql-errors.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/sql-errors.data diff --git a/exedata/owasp/coreruleset/rules/ssrf.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/ssrf.data similarity index 100% rename from exedata/owasp/coreruleset/rules/ssrf.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/ssrf.data diff --git a/exedata/owasp/coreruleset/rules/unix-shell.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/unix-shell.data similarity index 100% rename from exedata/owasp/coreruleset/rules/unix-shell.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/unix-shell.data diff --git a/exedata/owasp/coreruleset/rules/web-shells-php.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/web-shells-php.data similarity index 100% rename from exedata/owasp/coreruleset/rules/web-shells-php.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/web-shells-php.data diff --git a/exedata/owasp/coreruleset/rules/windows-powershell-commands.data b/cmd/samwaf/exedata/owasp/coreruleset/rules/windows-powershell-commands.data similarity index 100% rename from exedata/owasp/coreruleset/rules/windows-powershell-commands.data rename to cmd/samwaf/exedata/owasp/coreruleset/rules/windows-powershell-commands.data diff --git a/exedata/owasp/lock.txt.example b/cmd/samwaf/exedata/owasp/lock.txt.example similarity index 100% rename from exedata/owasp/lock.txt.example rename to cmd/samwaf/exedata/owasp/lock.txt.example diff --git a/exedata/owasp/readme.txt b/cmd/samwaf/exedata/owasp/readme.txt similarity index 100% rename from exedata/owasp/readme.txt rename to cmd/samwaf/exedata/owasp/readme.txt diff --git a/exedata/owasp/version b/cmd/samwaf/exedata/owasp/version similarity index 100% rename from exedata/owasp/version rename to cmd/samwaf/exedata/owasp/version diff --git a/exedata/public_key.pem b/cmd/samwaf/exedata/public_key.pem similarity index 100% rename from exedata/public_key.pem rename to cmd/samwaf/exedata/public_key.pem diff --git a/exedata/spiderbot/baidubot.json b/cmd/samwaf/exedata/spiderbot/baidubot.json similarity index 100% rename from exedata/spiderbot/baidubot.json rename to cmd/samwaf/exedata/spiderbot/baidubot.json diff --git a/exedata/spiderbot/bingbot.json b/cmd/samwaf/exedata/spiderbot/bingbot.json similarity index 100% rename from exedata/spiderbot/bingbot.json rename to cmd/samwaf/exedata/spiderbot/bingbot.json diff --git a/exedata/spiderbot/bytedancebot.json b/cmd/samwaf/exedata/spiderbot/bytedancebot.json similarity index 100% rename from exedata/spiderbot/bytedancebot.json rename to cmd/samwaf/exedata/spiderbot/bytedancebot.json diff --git a/exedata/spiderbot/googleadsbot.json b/cmd/samwaf/exedata/spiderbot/googleadsbot.json similarity index 100% rename from exedata/spiderbot/googleadsbot.json rename to cmd/samwaf/exedata/spiderbot/googleadsbot.json diff --git a/exedata/spiderbot/googlebot.json b/cmd/samwaf/exedata/spiderbot/googlebot.json similarity index 100% rename from exedata/spiderbot/googlebot.json rename to cmd/samwaf/exedata/spiderbot/googlebot.json diff --git a/exedata/spiderbot/googleusertriggeredbot.json b/cmd/samwaf/exedata/spiderbot/googleusertriggeredbot.json similarity index 100% rename from exedata/spiderbot/googleusertriggeredbot.json rename to cmd/samwaf/exedata/spiderbot/googleusertriggeredbot.json diff --git a/exedata/spiderbot/index.json b/cmd/samwaf/exedata/spiderbot/index.json similarity index 100% rename from exedata/spiderbot/index.json rename to cmd/samwaf/exedata/spiderbot/index.json diff --git a/cmd/samwaf/main.go b/cmd/samwaf/main.go new file mode 100644 index 0000000..686ef63 --- /dev/null +++ b/cmd/samwaf/main.go @@ -0,0 +1,853 @@ +package main + +import ( + "SamWaf/cache" + "SamWaf/common/gwebsocket" + "SamWaf/common/zlog" + "SamWaf/enums" + "SamWaf/global" + "SamWaf/globalobj" + "SamWaf/model" + "SamWaf/model/wafenginmodel" + "SamWaf/plugin" + "SamWaf/utils" + "SamWaf/wafconfig" + "SamWaf/wafdb" + "SamWaf/wafenginecore" + "SamWaf/wafenginecore/wafcaptcha" + "SamWaf/wafinit" + "SamWaf/wafipban" + "SamWaf/wafmangeweb" + "SamWaf/wafnotify" + "SamWaf/wafowasp" + "SamWaf/wafqueue" + "SamWaf/wafreg" + "SamWaf/wafsafeclear" + "SamWaf/wafsnowflake" + "SamWaf/waftask" + "SamWaf/waftunnelengine" + "crypto/tls" + "embed" + _ "embed" + "fmt" + "io/ioutil" + "log" + "net" + "net/http" + "os" + "os/exec" + "os/signal" + "path/filepath" + "runtime" + "runtime/debug" + "strconv" + "strings" + "sync" + "syscall" + "time" + _ "time/tzdata" + + dlp "github.com/bytedance/godlp" + "github.com/kardianos/service" + "go.uber.org/zap" + "gorm.io/gorm" +) + +//go:embed exedata/ip2region.xdb +var Ip2regionBytes []byte // 当前目录,解析为[]byte类型 + +//go:embed exedata/GeoLite2-Country.mmdb +var Ipv6CountryBytes []byte // IPv6国家解析 + +//go:embed exedata/ldpconfig.yml +var ldpConfig string //隐私防护ldp + +//go:embed exedata/public_key.pem +var publicKey string //公钥key + +//go:embed exedata/owasp +var owaspAssets embed.FS + +//go:embed exedata/spiderbot +var spiderBotAssets embed.FS + +//go:embed exedata/captcha +var captchaAssets embed.FS + +//go:embed exedata/capjs +var capjs embed.FS + +//go:embed exedata/httpauth +var httpauth embed.FS + +// wafSystenService 实现了 service.Service 接口 +type wafSystenService struct{} + +var webmanager *wafmangeweb.WafWebManager // web管理端 + +// Start 是服务启动时调用的方法 +func (m *wafSystenService) Start(s service.Service) error { + zlog.Info("服务启动形式-----Start") + go m.run() + return nil +} + +// Stop 是服务停止时调用的方法 +func (m *wafSystenService) Stop(s service.Service) error { + zlog.Info("服务形式的 -----stop") + wafsafeclear.SafeClear() + m.stopSamWaf() + return nil +} + +// 守护协程 +func NeverExit(name string, f func()) { + defer func() { + if v := recover(); v != nil { + zlog.Error(fmt.Sprintf("协程%s崩溃了,准备重启一个。 : %v, Stack Trace: %s", name, v, debug.Stack())) + if global.GWAF_RELEASE == "false" { + debug.PrintStack() + } + + go NeverExit(name, f) // 重启一个同功能协程 + } + }() + zlog.Info(name + " start") + f() +} + +// run 是服务的主要逻辑 +func (m *wafSystenService) run() { + + // 先尝试监听端口,检查是否被占用 + listener, err := net.Listen("tcp", ":"+strconv.Itoa(global.GWAF_LOCAL_SERVER_PORT)) + defer func() { + if listener != nil { + err := listener.Close() + if err != nil { + return + } + } + }() + if err != nil { + errMsg := fmt.Sprintf("管理界面端口 %d 已被占用,请检查并修改配置(conf/config.yml local_port字段)或关闭占用该端口的程序: %s", + global.GWAF_LOCAL_SERVER_PORT, err.Error()) + zlog.Error(errMsg) + panic(errMsg) + return + } + if listener != nil { + listener.Close() + } + // 获取当前执行文件的路径 + executablePath, err := os.Executable() + if err != nil { + fmt.Println("Error:", err) + return + } + + zlog.Info("执行位置:", executablePath) + global.GWAF_RUNTIME_CURRENT_EXEPATH = executablePath + //初始化步骤[加载ip数据库] + // 从嵌入的文件中读取内容 + + // 拼接文件路径 + ip2RegionFilePath := filepath.Join(utils.GetCurrentDir(), "data", "ip2region.xdb") + // 检查文件是否存在 + if _, err := os.Stat(ip2RegionFilePath); os.IsNotExist(err) { + global.GCACHE_IP_CBUFF = Ip2regionBytes + } else { + // 读取文件内容 + fileBytes, err := ioutil.ReadFile(ip2RegionFilePath) + if err != nil { + log.Fatalf("Failed to read IP database file ip2region.xdb: %v", err) + } + global.GCACHE_IP_CBUFF = fileBytes + // 检查是否成功读取 + zlog.Info("IP database ip2region.xdb loaded into cache, size: ", len(global.GCACHE_IP_CBUFF), ip2RegionFilePath) + } + + //检测是否存在IPV6得数据包 + ipv6RegionFilePath := filepath.Join(utils.GetCurrentDir(), "data", "GeoLite2-Country.mmdb") + // 检查文件是否存在 + if _, err := os.Stat(ipv6RegionFilePath); os.IsNotExist(err) { + global.GCACHE_IP_V6_COUNTRY_CBUFF = Ipv6CountryBytes + } else { + // 读取文件内容 + fileBytes, err := ioutil.ReadFile(ipv6RegionFilePath) + if err != nil { + log.Fatalf("Failed to read IPv6 database file GeoLite2-Country.mmdb: %v", err) + } + global.GCACHE_IP_V6_COUNTRY_CBUFF = fileBytes + // 检查是否成功读取 + zlog.Info("IPv6 database file GeoLite2-Country.mmdb loaded into cache, size: ", len(global.GCACHE_IP_V6_COUNTRY_CBUFF), ipv6RegionFilePath) + } + global.GWAF_DLP_CONFIG = ldpConfig + global.GWAF_REG_PUBLIC_KEY = publicKey + + //owasp资源 释放 + err = wafinit.CheckAndReleaseDataset(owaspAssets, utils.GetCurrentDir()+"/data/owasp", "owasp") + if err != nil { + zlog.Error("owasp", err.Error()) + } + + // 验证码资源释放 + err = wafinit.CheckAndReleaseDataset(captchaAssets, utils.GetCurrentDir()+"/data/captcha", "captcha") + if err != nil { + zlog.Error("captcha", err.Error()) + } + // 验证码工作量证明资源释放 + err = wafinit.CheckAndReleaseDataset(capjs, utils.GetCurrentDir()+"/data/capjs", "capjs") + if err != nil { + zlog.Error("capJs", err.Error()) + } + + // HTTP认证登录页面资源释放 + err = wafinit.CheckAndReleaseDataset(httpauth, utils.GetCurrentDir()+"/data/httpauth", "httpauth") + if err != nil { + zlog.Error("httpauth", err.Error()) + } + //TODO 准备释放最新spider bot + + //初始化cache + global.GCACHE_WAFCACHE = cache.InitWafCache() + //初始化验证码服务 + wafcaptcha.InitCaptchaService(global.GCACHE_WAFCACHE) + //初始化锁写不锁度 + global.GWAF_MEASURE_PROCESS_DEQUEENGINE = cache.InitWafOnlyLockWrite() + // 创建 Snowflake 实例 + global.GWAF_SNOWFLAKE_GEN = wafsnowflake.NewSnowflake(1609459200000, 1, 1) // 设置epoch时间、机器ID和数据中心ID + + // 创建owasp + global.GWAF_OWASP = wafowasp.NewWafOWASP(true, utils.GetCurrentDir()) + + // 初始化ip ban + wafipban.InitIPBanManager(global.GCACHE_WAFCACHE) + + //提前初始化 + global.GDATA_CURRENT_LOG_DB_MAP = map[string]*gorm.DB{} + rversion := "初始化系统 编译器版本:" + runtime.Version() + " 程序版本号:" + global.GWAF_RELEASE_VERSION_NAME + "(" + global.GWAF_RELEASE_VERSION + ")" + if global.GWAF_RELEASE == "false" { + rversion = rversion + " 调试版本" + } else { + rversion = rversion + " 发行版本" + } + if runtime.GOOS == "linux" { + rversion = rversion + " linux" + } else if runtime.GOOS == "windows" { + rversion = rversion + " windows" + if utils.IsSupportedWindows7Version() { + zlog.Info("Now your system is win7 or win2008r2.") + } + if global.GWAF_RUNTIME_WIN7_VERSION == "true" && utils.IsSupportedWindows7Version() == false { + zlog.Error("Now your use is win7 or win2008r2 special version,We recommend you download normal version") + } + } else { + rversion = rversion + " " + runtime.GOOS + } + if global.GWAF_RUNTIME_WIN7_VERSION == "true" { + rversion = rversion + " Win7内核版本" + } + rversion = rversion + " plat:" + runtime.GOOS + "-" + runtime.GOARCH + zlog.Info(rversion) + zlog.Info("OutIp", global.GWAF_RUNTIME_IP) + + if global.GWAF_RELEASE == "false" { + global.GUPDATE_VERSION_URL = "http://127.0.0.1:8111/" + } + + //初始化本地数据库 + wafdb.InitCoreDb("") + wafdb.InitLogDb("") + wafdb.InitStatsDb("") + + //初始化插件系统(从配置文件加载) + if err := plugin.InitPluginSystem(); err != nil { + zlog.Error("初始化插件系统失败", "error", err) + // 插件系统初始化失败不影响主程序启动 + } + + //初始化队列引擎 + wafqueue.InitDequeEngine() + //启动队列消费 + go NeverExit("ProcessCoreDequeEngine", wafqueue.ProcessCoreDequeEngine) + go NeverExit("ProcessMessageDequeEngine", wafqueue.ProcessMessageDequeEngine) + go NeverExit("ProcessStatDequeEngine", wafqueue.ProcessStatDequeEngine) + go NeverExit("ProcessLogDequeEngine", wafqueue.ProcessLogDequeEngine) + + //初始化一次系统参数信息 + waftask.TaskLoadSetting(true) + //启动通知相关程序 + global.GNOTIFY_KAKFA_SERVICE = wafnotify.InitNotifyKafkaEngine(global.GCONFIG_RECORD_KAFKA_ENABLE, global.GCONFIG_RECORD_KAFKA_URL, global.GCONFIG_RECORD_KAFKA_TOPIC) //kafka + //启动waf + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE = &wafenginecore.WafEngine{ + HostTarget: map[string]*wafenginmodel.HostSafe{}, + //主机和code的关系 + HostCode: map[string]string{}, + HostTargetNoPort: map[string]string{}, + HostTargetMoreDomain: map[string]string{}, + ServerOnline: wafenginmodel.NewSafeServerMap(), + //所有证书情况 对应端口 可能多个端口都是https 443,或者其他非标准端口也要实现https证书 + AllCertificate: wafenginecore.AllCertificate{ + Mux: sync.Mutex{}, + Map: map[string]*tls.Certificate{}, + }, + EngineCurrentStatus: 0, // 当前waf引擎状态 + Sensitive: make([]model.Sensitive, 0), + PluginManager: globalobj.GWAF_RUNTIME_OBJ_PLUGIN_MANAGER, // 设置插件管理器 + } + http.Handle("/", globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.StartWaf() + + //启动隧道 + globalobj.GWAF_RUNTIME_OBJ_TUNNEL_ENGINE = waftunnelengine.NewWafTunnelEngine() + globalobj.GWAF_RUNTIME_OBJ_TUNNEL_ENGINE.StartTunnel() + //启动管理界面 + webmanager = &wafmangeweb.WafWebManager{LogName: "WebManager"} + go func() { + webmanager.StartLocalServer() + }() + + //启动websocket + global.GWebSocket = gwebsocket.InitWafWebSocket() + //定时取规则并更新(考虑后期定时拉取公共规则 待定,可能会影响实际生产) + + // 创建任务调度器 + + global.GWAF_LAST_UPDATE_TIME = time.Now() + + //开始 需要添加到任务注册器里面的 + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry = waftask.NewTaskRegistry() + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_RUNTIME_QPS_CLEAN, waftask.TaskLogQpsClean) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_HOST_QPS_CLEAN, waftask.TaskHostQpsClean) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_SHARE_DB, waftask.TaskShareDbInfo) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_COUNTER, waftask.TaskCounter) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_DELAY_INFO, waftask.TaskDelayInfo) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_LOAD_CONFIG, waftask.TaskLoadSettingCron) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_REFLUSH_WECHAT_ACCESS_TOKEN, waftask.TaskWechatAccessToken) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_DELETE_HISTORY_INFO, waftask.TaskDeleteHistoryInfo) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_DELETE_HISTORY_DOWNLOAD_FILE, waftask.TaskHistoryDownload) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_SSL_ORDER_RENEW, waftask.SSLOrderReload) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_SSL_PATH_LOAD, waftask.SSLReload) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_BATCH, waftask.BatchTask) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_SSL_EXPIRE_CHECK, waftask.SSLExpireCheck) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_NOTICE, waftask.TaskStatusNotify) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_HEALTH, waftask.TaskHealth) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_CLEAR_CC_WINDOWS, waftask.TaskCC) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_CLEAR_WEBCACHE, waftask.TaskClearWebcache) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_GC, waftask.TaskGC) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_STATS_PUSH, waftask.TaskStatsPush) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_DB_MONITOR, waftask.TaskDatabaseMonitor) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry.RegisterTask(enums.TASK_FIREWALL_CLEAN_EXPIRED, waftask.TaskFirewallCleanExpired) + + go waftask.TaskShareDbInfo() + + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskScheduler = waftask.NewTaskScheduler(globalobj.GWAF_RUNTIME_OBJ_WAF_TaskRegistry) + taskDbList := waftask.InitTaskDb() + for _, task := range taskDbList { + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskScheduler.ScheduleTask(task.TaskUnit, task.TaskValue, task.TaskAt, task.TaskMethod, task.TaskDaysOfTheWeek) + } + //结束 需要添加到任务注册器里面的 + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskScheduler.Start() + + //脱敏处理初始化 + global.GWAF_DLP, _ = dlp.NewEngine("wafDlp") + err = global.GWAF_DLP.ApplyConfig(ldpConfig) + if err != nil { + zlog.Info("ldp init error", err) + } else { + // 注册自定义脱敏规则 + global.GWAF_DLP.RegisterMasker("LoginSensitiveInfoMaskRule", func(in string) (string, error) { + + // 分割成键值对 + pairs := strings.Split(in, "&") + // 遍历每个键值对,对值进行脱敏处理 + for i, pair := range pairs { + keyValue := strings.SplitN(pair, "=", 2) + if len(keyValue) != 2 { + continue + } + value := keyValue[1] + if len(value) > 2 { + value = value[:1] + strings.Repeat("*", len(value)-2) + value[len(value)-1:] + } + pairs[i] = keyValue[0] + "=" + value + } + // 将处理后的键值对重新组合成字符串 + return "【已脱敏】" + strings.Join(pairs, "&"), nil + }) + + } + //加载授权信息 + verifyResult, info, err := wafreg.VerifyServerRegByDefaultFile() + if verifyResult { + global.GWAF_REG_INFO = info + zlog.Debug("授权信息 调试信息", info) + expiryDay, isExpiry := wafreg.CheckExpiry(info.ExpiryDate) + if isExpiry { + global.GWAF_REG_INFO.IsExpiry = true + zlog.Info("授权信息已经过期") + } else { + global.GWAF_REG_INFO.IsExpiry = false + zlog.Info("授权信息还剩余:" + strconv.Itoa(expiryDay) + "天") + } + } else { + zlog.Info("regInfo", err) + } + + zlog.Info("SamWaf has started successfully.You can open http://127.0.0.1:" + strconv.Itoa(global.GWAF_LOCAL_SERVER_PORT) + " in your Browser") + for { + select { + case msg := <-global.GWAF_CHAN_MSG: + if globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]] != nil && globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode] != "" { + switch msg.Type { + case enums.ChanTypeAllowIP: + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Lock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].IPWhiteLists = msg.Content.([]model.IPAllowList) + zlog.Debug("远程配置", zap.Any("IPWhiteLists", msg.Content.([]model.IPAllowList))) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock() + break + case enums.ChanTypeAllowURL: + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Lock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].UrlWhiteLists = msg.Content.([]model.URLAllowList) + zlog.Debug("远程配置", zap.Any("UrlWhiteLists", msg.Content.([]model.URLAllowList))) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock() + break + case enums.ChanTypeBlockIP: + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Lock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].IPBlockLists = msg.Content.([]model.IPBlockList) + zlog.Debug("远程配置", zap.Any("IPBlockLists", msg)) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock() + break + case enums.ChanTypeBlockURL: + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Lock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].UrlBlockLists = msg.Content.([]model.URLBlockList) + zlog.Debug("远程配置", zap.Any("UrlBlockLists", msg.Content.([]model.URLBlockList))) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock() + break + case enums.ChanTypeLdp: + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Lock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].LdpUrlLists = msg.Content.([]model.LDPUrl) + zlog.Debug("远程配置", zap.Any("LdpUrlLists", msg.Content.([]model.LDPUrl))) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock() + break + case enums.ChanTypeRule: + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Lock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].RuleData = msg.Content.([]model.Rules) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Rule.LoadRules(msg.Content.([]model.Rules)) + zlog.Debug("远程配置", zap.Any("Rule", msg.Content.([]model.Rules))) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock() + break + case enums.ChanTypeAnticc: + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.ApplyAntiCCConfig(msg.HostCode, msg.Content.(model.AntiCC)) + break + case enums.ChanTypeHttpauth: + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Lock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].HttpAuthBases = msg.Content.([]model.HttpAuthBase) + zlog.Debug("远程配置", zap.Any("Http Auth", msg.Content.([]model.HttpAuthBase))) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock() + break + case enums.ChanTypeHost: + hosts := msg.Content.([]model.Hosts) + if len(hosts) == 1 { + //情况1,端口是新的,域名也是新的 + //情况2,端口不变,域名也不变,就是重新加载数据 + //情况3,端口从A切换到B了,域名是旧的 ;端口更改后当前这个端口下没有域名了,应该是关闭了,并移除数据 + + //情况1 + if msg.OldContent == nil { + zlog.Debug("主机处理情况1 端口是新的,域名也是新的") + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.LoadHost(hosts[0]) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.StartAllProxyServer() + } else { + hostsOld := msg.OldContent.(model.Hosts) + if hosts[0].Host == hostsOld.Host && hosts[0].Port == hostsOld.Port { + //情况2 + zlog.Debug("主机处理情况2 端口不变,域名也不变,就是重新加载数据") + if globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[hosts[0].Host+":"+strconv.Itoa(hosts[0].Port)] != nil && + len(globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[hosts[0].Host+":"+strconv.Itoa(hosts[0].Port)].LoadBalanceRuntime.RevProxies) > 0 { + //设置空代理 + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[hosts[0].Host+":"+strconv.Itoa(hosts[0].Port)].LoadBalanceRuntime.RevProxies = nil + zlog.Debug("主机重新代理", hosts[0].Host+":"+strconv.Itoa(hosts[0].Port)) + } + //如果本次是关闭,那么应该关闭主机 + if hosts[0].START_STATUS == 1 { + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.RemoveHost(hosts[0]) + } + //如果本次ssl和上次ssl不同 + if hosts[0].Ssl != hostsOld.Ssl || hosts[0].Keyfile != hostsOld.Keyfile || hosts[0].Certfile != hostsOld.Certfile { + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.RemoveHost(hosts[0]) + } + //绑定更多域名变更了 + if hosts[0].BindMoreHost != hostsOld.BindMoreHost { + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.RemoveHost(hosts[0]) + } + // 远程 IP 或端口变化,需重载 + if hosts[0].Remote_ip != hostsOld.Remote_ip || hosts[0].Remote_port != hostsOld.Remote_port { + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.RemoveHost(hosts[0]) + } + // 负载状态或策略变化,需重载 + if hosts[0].IsEnableLoadBalance != hostsOld.IsEnableLoadBalance || hosts[0].LoadBalanceStage != hostsOld.LoadBalanceStage { + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.RemoveHost(hosts[0]) + } + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.LoadHost(hosts[0]) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.StartAllProxyServer() + } else if hosts[0].Host == hostsOld.Host && hosts[0].Port != hostsOld.Port { + //情况3 + zlog.Debug("主机处理情况3 端口从A切换到B了,域名是旧的 ;端口更改后当前这个端口下没有域名了,应该是关闭了,并移除数据") + if globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[hostsOld.Host+":"+strconv.Itoa(hostsOld.Port)] != nil && + len(globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[hostsOld.Host+":"+strconv.Itoa(hostsOld.Port)].LoadBalanceRuntime.RevProxies) > 0 { + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[hostsOld.Host+":"+strconv.Itoa(hostsOld.Port)].LoadBalanceRuntime.RevProxies = nil + } + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.RemoveHost(hostsOld) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.LoadHost(hosts[0]) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.StartAllProxyServer() + } + } + + } + break + case enums.ChanTypeDelHost: + host := msg.Content.(model.Hosts) + if host.Id != "" { + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.RemoveHost(host) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.EnumAllPortProxyServer() + } + break + case enums.ChanTypeLoadBalance: + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.ClearProxy(msg.HostCode) + break + case enums.ChanTypeSSL: + host := msg.Content.(model.Hosts) + zlog.Info(fmt.Sprintf("服务端准备为 %s 主机刷新 SSL证书 ,证书信息:%v", host.Host, utils.PrintSSLCert(host.Certfile))) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.RemoveHost(host) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.LoadHost(host) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.StartAllProxyServer() + break + case enums.ChanTypeBlockingPage: + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Lock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].BlockingPage = msg.Content.(map[string]model.BlockingPage) + zlog.Debug("远程配置", zap.Any("配置自定义拦截界面信息", msg.Content.(map[string]model.BlockingPage))) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock() + break + case enums.ChanTypeCacheRule: + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Lock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].CacheRule = msg.Content.([]model.CacheRule) + zlog.Debug("远程配置", zap.Any("配置缓存规则", msg.Content.([]model.CacheRule))) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock() + break + } + + //end switch + } else { + //新增 + switch msg.Type { + case enums.ChanTypeHost: + hosts := msg.Content.([]model.Hosts) + if len(hosts) == 1 { + hostRunTimeBean := globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.LoadHost(hosts[0]) + for _, runTime := range hostRunTimeBean { + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.StartProxyServer(runTime) + } + } + break + } + } + break + case common := <-global.GWAF_CHAN_COMMON_MSG: + if common.Type == enums.ChanComTypeTunnel { + //隧道类型 + switch common.OpType { + case enums.OP_TYPE_NEW: + tunnelNew := common.Content.(model.Tunnel) + netRunTimes := globalobj.GWAF_RUNTIME_OBJ_TUNNEL_ENGINE.LoadTunnel(tunnelNew) + for _, netRunTime := range netRunTimes { + globalobj.GWAF_RUNTIME_OBJ_TUNNEL_ENGINE.StartTunnelServer(netRunTime) + } + break + case enums.OP_TYPE_UPDATE: + // 获取修改前的隧道信息 + tunnelOld := common.OldContent.(model.Tunnel) + // 获取修改后的隧道信息 + tunnelNew := common.Content.(model.Tunnel) + netRunTimes := globalobj.GWAF_RUNTIME_OBJ_TUNNEL_ENGINE.EditTunnel(tunnelOld, tunnelNew) + for _, netRunTime := range netRunTimes { + globalobj.GWAF_RUNTIME_OBJ_TUNNEL_ENGINE.StartTunnelServer(netRunTime) + } + break + case enums.OP_TYPE_DELETE: + tunnelDelete := common.OldContent.(model.Tunnel) + globalobj.GWAF_RUNTIME_OBJ_TUNNEL_ENGINE.RemoveTunnel(tunnelDelete) + break + } + } + case engineStatus := <-global.GWAF_CHAN_ENGINE: + if engineStatus == 1 { + zlog.Info("准备关闭WAF引擎") + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.CloseWaf() + zlog.Info("准备启动WAF引擎") + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.StartWaf() + + zlog.Info("准备关闭隧道引擎") + globalobj.GWAF_RUNTIME_OBJ_TUNNEL_ENGINE.CloseTunnel() + zlog.Info("准备启动隧道引擎") + globalobj.GWAF_RUNTIME_OBJ_TUNNEL_ENGINE.StartTunnel() + + } + break + case host := <-global.GWAF_CHAN_HOST: + if globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[host.Host+":"+strconv.Itoa(host.Port)] != nil { + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[host.Host+":"+strconv.Itoa(host.Port)].Host.GUARD_STATUS = host.GUARD_STATUS + + } + zlog.Debug("规则", zap.Any("主机", host)) + break + case update := <-global.GWAF_CHAN_UPDATE: + if update == 1 { + global.GWAF_RUNTIME_SERVER_TYPE = !service.Interactive() + //需要重新启动 + if global.GWAF_RUNTIME_SERVER_TYPE == true { + zlog.Info("服务形式重启") + m.stopSamWaf() + + // 只启动一次新进程 + cmd := exec.Command(global.GWAF_RUNTIME_CURRENT_EXEPATH, "restart") + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Start(); err != nil { + zlog.Error("启动新进程失败:", err) + os.Exit(0) + } + time.Sleep(2 * time.Second) + os.Exit(0) + } else { + m.stopSamWaf() + cmd := exec.Command(global.GWAF_RUNTIME_CURRENT_EXEPATH) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Start(); err != nil { + zlog.Error("启动新进程失败:", err) + os.Exit(0) + } + time.Sleep(2 * time.Second) + os.Exit(0) + } + } + break + + case sensitive := <-global.GWAF_CHAN_SENSITIVE: + zlog.Debug("远程配置", sensitive) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.ReLoadSensitive() + break + case sslOrderChan := <-global.GWAF_CHAN_SSLOrder: + zlog.Debug("ssl证书申请", sslOrderChan) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.ApplySSLOrder(sslOrderChan.Type, sslOrderChan.Content.(model.SslOrder)) + break + case sslExpireCheck := <-global.GWAF_CHAN_SSL_EXPIRE_CHECK: + zlog.Debug("ssl证书到期检测", sslExpireCheck) + waftask.SSLExpireCheck() + break + case syncHostToSslExpire := <-global.GWAF_CHAN_SYNC_HOST_TO_SSL_EXPIRE: + zlog.Debug("同步已存在主机到SSL证书检测任务里", syncHostToSslExpire) + waftask.SyncHostToSslCheck() + break + case taskMethod := <-global.GWAF_CHAN_TASK: + zlog.Debug("需要执行的方法", taskMethod) + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskScheduler.RunManual(taskMethod) + break + case taskReload := <-global.GWAF_CHAN_TASK_RELOAD: + zlog.Info("任务重新加载", "taskName", taskReload.TaskName, "taskMethod", taskReload.TaskMethod) + err := globalobj.GWAF_RUNTIME_OBJ_WAF_TaskScheduler.RescheduleTask( + taskReload.TaskUnit, + taskReload.TaskValue, + taskReload.TaskAt, + taskReload.TaskMethod, + taskReload.TaskDaysOfTheWeek, + ) + if err != nil { + zlog.Error("任务重新加载失败", "error", err.Error(), "taskName", taskReload.TaskName) + } else { + zlog.Info("任务重新加载成功", "taskName", taskReload.TaskName) + } + break + case clearCcWindows := <-global.GWAF_CHAN_CLEAR_CC_WINDOWS: + zlog.Debug("定时清空CCwindows", clearCcWindows) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.ClearCcWindows() + break + case clearCcWindowsIp := <-global.GWAF_CHAN_CLEAR_CC_IP: + zlog.Debug("定时清空CCip", clearCcWindowsIp) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.ClearCcWindowsForIP(clearCcWindowsIp) + break + } + + } + zlog.Info("normal program close") +} + +// 停止要提前关闭的 是服务的主要逻辑 +func (m *wafSystenService) stopSamWaf() { + zlog.Info("Shutdown SamWaf Engine...") + if globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE != nil { + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.CloseWaf() + zlog.Info("Shutdown SamWaf Engine finished") + } else { + zlog.Warn("WAF Engine is nil, skipping shutdown") + } + + zlog.Info("Shutdown SamWaf Tunnel Engine...") + if globalobj.GWAF_RUNTIME_OBJ_TUNNEL_ENGINE != nil { + globalobj.GWAF_RUNTIME_OBJ_TUNNEL_ENGINE.CloseTunnel() + zlog.Info("Shutdown SamWaf Tunnel Engine finished") + } else { + zlog.Warn("Tunnel Engine is nil, skipping shutdown") + } + + zlog.Info("Shutdown SamWaf Queue Processors...") + // 关闭信号通道,通知所有队列处理协程退出 + close(global.GWAF_QUEUE_SHUTDOWN_SIGNAL) + // 等待一段时间,让队列处理协程有时间完成当前工作并退出 + time.Sleep(500 * time.Millisecond) + zlog.Info("Shutdown SamWaf Queue Processors finished") + + // 设置任务停止标志 + zlog.Info("Notifying SamWaf Tasks to shutdown...") + global.GWAF_SHUTDOWN_SIGNAL = true + // 给任务一些时间完成当前工作 + time.Sleep(200 * time.Millisecond) + zlog.Info("SamWaf Tasks notified") + + zlog.Info("Shutdown SamWaf Cron...") + globalobj.GWAF_RUNTIME_OBJ_WAF_TaskScheduler.Stop() + zlog.Info("Shutdown SamWaf Cron finished") + + zlog.Info("Shutdown SamWaf WebManager...") + webmanager.Shutdown() + zlog.Info("Shutdown SamWaf WebManager finished") + + zlog.Info("Shutdown SamWaf IPDatabase...") + utils.CloseIPDatabase() + zlog.Info("Shutdown SamWaf IPDatabase finished") + + // 关闭插件系统 + zlog.Info("Shutdown SamWaf Plugin System...") + if globalobj.GWAF_RUNTIME_OBJ_PLUGIN_MANAGER != nil { + if err := globalobj.GWAF_RUNTIME_OBJ_PLUGIN_MANAGER.Shutdown(); err != nil { + zlog.Error("Shutdown Plugin System failed", zap.Error(err)) + } else { + zlog.Info("Shutdown SamWaf Plugin System finished") + } + } else { + zlog.Warn("Plugin Manager is nil, skipping shutdown") + } + +} + +// 优雅升级 +func (m *wafSystenService) Graceful() { + //https://github.com/pengge/uranus/blob/main/main.go 预备参考 +} + +func main() { + fmt.Println(` +========================================== + SamWaf Web Application Firewall ` + global.GWAF_RELEASE_VERSION + ` + Version Name: ` + global.GWAF_RELEASE_VERSION_NAME + ` +========================================== +`) + //加载配置 + wafconfig.LoadAndInitConfig() + //初始化日志 + zlog.InitZLog(global.GWAF_LOG_DEBUG_ENABLE, global.GWAF_LOG_OUTPUT_FORMAT) + if v := recover(); v != nil { + zlog.Error("主流程上被异常了") + } + pid := os.Getpid() + zlog.Debug("SamWaf Current PID:" + strconv.Itoa(pid)) + //获取外网IP + global.GWAF_RUNTIME_IP = utils.GetExternalIp() + + option := service.KeyValue{} + //windows + //OnFailure:"restart", + if runtime.GOOS == "windows" { + option["OnFailure"] = "restart" + option["OnFailureDelayDuration"] = "1s" + option["OnFailureResetPeriod"] = "10" + } else { + option["Restart"] = "always" + } + + // 创建服务对象 + svcConfig := &service.Config{ + Name: "SamWafService", + DisplayName: "SamWaf Service", + Description: "SamWaf is a Web Application Firewall (WAF) By SamWaf.com", + Option: option, + } + prg := &wafSystenService{} + s, err := service.New(prg, svcConfig) + if err != nil { + log.Fatal(err) + } + + // 设置服务控制信号处理程序 + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, os.Interrupt, os.Kill, syscall.SIGTERM) + + if len(os.Args) > 1 { + command := os.Args[1] + switch command { + + case "install", "start", "stop", "uninstall", "restart": // 以服务方式运行 + err := service.Control(s, command) + if err != nil { + log.Fatal(err) + } + fmt.Printf("Samwaf has successfully executed the '%s' command.\n", command) + break + case "resetpwd": //重制密码 + wafdb.InitCoreDb("") + wafdb.ResetAdminPwd() + case "resetotp": //重置安全码 + wafdb.InitCoreDb("") + wafdb.ResetAdminOTP() + case "repairdb": //修复数据库 + fmt.Println("\n⚠️ 数据库修复工具") + fmt.Println("如果您遇到数据库损坏错误") + fmt.Println("可以使用此工具尝试修复。\n") + wafdb.RepairAllDatabases("") + case "execsql": //执行SQL语句 + fmt.Println("\n💻 SQL 执行工具") + fmt.Println("可以在指定数据库上执行 SQL 语句\n") + wafdb.ExecuteSQLCommand("") + default: + fmt.Printf("Command '%s' is not recognized.\n", command) + fmt.Println("\n可用命令:") + fmt.Println(" install - 安装为系统服务") + fmt.Println(" start - 启动服务") + fmt.Println(" stop - 停止服务") + fmt.Println(" restart - 重启服务") + fmt.Println(" uninstall - 卸载服务") + fmt.Println(" resetpwd - 重置管理员密码") + fmt.Println(" resetotp - 重置安全码") + fmt.Println(" repairdb - 修复损坏的数据库") + fmt.Println(" execsql - 执行SQL语句(支持SELECT/UPDATE/DELETE等)") + fmt.Println("") + } + return + } + + if service.Interactive() { + zlog.Info("main server under service manager") + global.GWAF_RUNTIME_SERVER_TYPE = service.Interactive() + } else { + zlog.Info("main server not under service manager") + global.GWAF_RUNTIME_SERVER_TYPE = service.Interactive() + } + // 以常规方式运行 + err = s.Run() + if err != nil { + log.Fatal(err) + } + +}