mirror of
https://github.com/Li4n0/revsuit.git
synced 2026-09-23 23:21:54 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac44c7e30b | ||
|
|
bf8a43fa87 | ||
|
|
284db90c16 | ||
|
|
223c14ab33 | ||
|
|
c53ec79ccd | ||
|
|
7dde3936d1 | ||
|
|
a4ffaa7350 | ||
|
|
eee9c7be70 | ||
|
|
b76757da33 | ||
|
|
b33de11ba8 | ||
|
|
1572171448 | ||
|
|
5e80591c85 | ||
|
|
48f55c5327 |
@@ -23,6 +23,10 @@ jobs:
|
|||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
- name: create dist directory
|
- name: create dist directory
|
||||||
run: mkdir frontend/dist && touch frontend/dist/revsuit
|
run: mkdir frontend/dist && touch frontend/dist/revsuit
|
||||||
|
- name: Install Go
|
||||||
|
uses: actions/setup-go@v2
|
||||||
|
with:
|
||||||
|
go-version: 1.19.x
|
||||||
- name: Run golangci-lint
|
- name: Run golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v3
|
uses: golangci/golangci-lint-action@v3
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -28,15 +28,15 @@ jobs:
|
|||||||
run: echo ::set-output name=VERSION::$(echo $GITHUB_REF | cut -d / -f 3)
|
run: echo ::set-output name=VERSION::$(echo $GITHUB_REF | cut -d / -f 3)
|
||||||
|
|
||||||
- name: compile linux amd64
|
- name: compile linux amd64
|
||||||
run: GOARCH="amd64" go build -ldflags="-s -w -X 'github.com/li4n0/revsuit/pkg/server.VERSION=${{ steps.get_version.outputs.VERSION }}'" -tags netgo -trimpath -o "bin/revsuit_linux_amd64" ./cmd/revsuit/revsuit.go
|
run: CGO_ENABLE=0 GOARCH="amd64" go build -ldflags="-s -w -X 'github.com/li4n0/revsuit/pkg/server.VERSION=${{ steps.get_version.outputs.VERSION }}'" -tags netgo -trimpath -o "bin/revsuit_linux_amd64" ./cmd/revsuit/revsuit.go
|
||||||
- name: compile linux arm64
|
- name: compile linux arm64
|
||||||
run: GOARCH="arm64" go build -ldflags="-s -w -X 'github.com/li4n0/revsuit/pkg/server.VERSION=${{ steps.get_version.outputs.VERSION }}'" -tags netgo -trimpath -o "bin/revsuit_linux_arm64" ./cmd/revsuit/revsuit.go
|
run: CGO_ENABLE=0 GOARCH="arm64" go build -ldflags="-s -w -X 'github.com/li4n0/revsuit/pkg/server.VERSION=${{ steps.get_version.outputs.VERSION }}'" -tags netgo -trimpath -o "bin/revsuit_linux_arm64" ./cmd/revsuit/revsuit.go
|
||||||
- name: compile darwin amd64
|
- name: compile darwin amd64
|
||||||
run: GOOS="darwin" GOARCH="amd64" go build -ldflags="-s -w -X 'github.com/li4n0/revsuit/pkg/server.VERSION=${{ steps.get_version.outputs.VERSION }}'" -trimpath -o "bin/revsuit_darwin_amd64" ./cmd/revsuit/revsuit.go
|
run: CGO_ENABLE=0 GOOS="darwin" GOARCH="amd64" go build -ldflags="-s -w -X 'github.com/li4n0/revsuit/pkg/server.VERSION=${{ steps.get_version.outputs.VERSION }}'" -trimpath -o "bin/revsuit_darwin_amd64" ./cmd/revsuit/revsuit.go
|
||||||
- name: compile darwin arm64
|
- name: compile darwin arm64
|
||||||
run: GOOS="darwin" GOARCH="arm64" go build -ldflags="-s -w -X 'github.com/li4n0/revsuit/pkg/server.VERSION=${{ steps.get_version.outputs.VERSION }}'" -trimpath -o "bin/revsuit_darwin_arm64" ./cmd/revsuit/revsuit.go
|
run: CGO_ENABLE=0 GOOS="darwin" GOARCH="arm64" go build -ldflags="-s -w -X 'github.com/li4n0/revsuit/pkg/server.VERSION=${{ steps.get_version.outputs.VERSION }}'" -trimpath -o "bin/revsuit_darwin_arm64" ./cmd/revsuit/revsuit.go
|
||||||
- name: compile windows amd64
|
- name: compile windows amd64
|
||||||
run: GOOS="windows" GOARCH="amd64" go build -ldflags="-s -w -X 'github.com/li4n0/revsuit/pkg/server.VERSION=${{ steps.get_version.outputs.VERSION }}' " -trimpath -o "bin/revsuit_windows_amd64.exe" ./cmd/revsuit/revsuit.go
|
run: CGO_ENABLE=0 GOOS="windows" GOARCH="amd64" go build -ldflags="-s -w -X 'github.com/li4n0/revsuit/pkg/server.VERSION=${{ steps.get_version.outputs.VERSION }}' " -trimpath -o "bin/revsuit_windows_amd64.exe" ./cmd/revsuit/revsuit.go
|
||||||
|
|
||||||
- name: Upload the artifacts
|
- name: Upload the artifacts
|
||||||
uses: li4n0/upload-release-action@v2
|
uses: li4n0/upload-release-action@v2
|
||||||
|
|||||||
@@ -29,3 +29,6 @@ node_modules/
|
|||||||
|
|
||||||
## frontend dist
|
## frontend dist
|
||||||
dist/
|
dist/
|
||||||
|
|
||||||
|
## received files
|
||||||
|
revsuit-files
|
||||||
|
|||||||
@@ -2,6 +2,40 @@
|
|||||||
|
|
||||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||||
|
|
||||||
|
### [0.7.1](https://github.com/Li4n0/revsuit/compare/v0.7.0...v0.7.1) (2023-06-01)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* fix the error that the maximum length of http rule response body is 191 when using mysql ([bf8a43f](https://github.com/Li4n0/revsuit/commit/bf8a43fa875327c3191499a214c420bfa78334d0))
|
||||||
|
|
||||||
|
## [0.7.0](https://github.com/Li4n0/revsuit/compare/v0.6.0...v0.7.0) (2023-05-23)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add `value` field to the dns log ([#67](https://github.com/Li4n0/revsuit/issues/67)) ([223c14a](https://github.com/Li4n0/revsuit/commit/223c14ab33757e06b0d8177091982582e08e70c4))
|
||||||
|
|
||||||
|
## [0.6.0](https://github.com/Li4n0/revsuit/compare/v0.5.2...v0.6.0) (2023-03-24)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* support for using `Flag-Filter` request headers to filter the flags that the client expects to receive ([#64](https://github.com/Li4n0/revsuit/issues/64)) ([b33de11](https://github.com/Li4n0/revsuit/commit/b33de11ba8f126b03a45ad15cae69331ad59b865)) (Thanks to @whwlsfb)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* fix static resource loading failure after modifying `admin_path_prefix` ([b76757d](https://github.com/Li4n0/revsuit/commit/b76757da331b56f240ec2a0c69d479f3184bc4c2)), closes [#63](https://github.com/Li4n0/revsuit/issues/63)
|
||||||
|
|
||||||
|
### [0.5.2](https://github.com/Li4n0/revsuit/compare/v0.5.1...v0.5.2) (2022-11-16)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* fix bug that the files associated with records still exist after deleting mysql and ftp records ([5e80591](https://github.com/Li4n0/revsuit/commit/5e80591c856a63c851ba5e17812af89373d76cf5))
|
||||||
|
* fix panic when update config ([#62](https://github.com/Li4n0/revsuit/issues/62)) ([48f55c5](https://github.com/Li4n0/revsuit/commit/48f55c53273fcea579c9fdfaf2939c90df3588b1))
|
||||||
|
|
||||||
### [0.5.1](https://github.com/Li4n0/revsuit/compare/v0.5.0...v0.5.1) (2022-09-13)
|
### [0.5.1](https://github.com/Li4n0/revsuit/compare/v0.5.0...v0.5.1) (2022-09-13)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,10 @@ token: # Authentication Token, both the admin pag
|
|||||||
domains: [] # The domain names used by the platform
|
domains: [] # The domain names used by the platform
|
||||||
external_ip: # The external IP of the platform, you need to make sure that the target you want to test can access the platform through this IP
|
external_ip: # The external IP of the platform, you need to make sure that the target you want to test can access the platform through this IP
|
||||||
admin_path_prefix: "/revsuit" # The http path prefix for the admin page, the page will be located at: /admin_path_prefix/admin
|
admin_path_prefix: "/revsuit" # The http path prefix for the admin page, the page will be located at: /admin_path_prefix/admin
|
||||||
database: revsuit.db # Database connection information, support using Sqlite3, MySQL, Postgres
|
# Database connection information, support using MySQL, Postgres, Sqlite3
|
||||||
# database: "mysql://root:password@tcp(127.0.0.1:3306)/revsuit?charset=utf8mb4&parseTime=True&loc=Local"
|
database: "mysql://root:password@tcp(127.0.0.1:3306)/revsuit?charset=utf8mb4&parseTime=True&loc=Local"
|
||||||
# database: "postgres://host=127.0.0.1 user=root password=password dbname=revsuit port=5432 sslmode=disable TimeZone=Asia/Shanghai"
|
# database: "postgres://host=127.0.0.1 user=root password=password dbname=revsuit port=5432 sslmode=disable TimeZone=Asia/Shanghai"
|
||||||
|
#database: revsuit.db # The use of sqlite databases on some systems may cause `SQLITE BUSY` problems in concurrent scenarios, so it is not recommended for use in a formal environment
|
||||||
|
|
||||||
log_level: info # Output log levels, divided into: debug, info, warning, error, fatal
|
log_level: info # Output log levels, divided into: debug, info, warning, error, fatal
|
||||||
check_upgrade: true # Whether to automatically check for updates
|
check_upgrade: true # Whether to automatically check for updates
|
||||||
|
|||||||
+3
-2
@@ -7,9 +7,10 @@ token: # 鉴权Token,管理页面和客户端
|
|||||||
domains: [] # 反连平台绑定的域名
|
domains: [] # 反连平台绑定的域名
|
||||||
external_ip: # 反连平台的外部IP,需要确保你想测试的目标能通过该 IP 访问到平台
|
external_ip: # 反连平台的外部IP,需要确保你想测试的目标能通过该 IP 访问到平台
|
||||||
admin_path_prefix: "/revsuit" # 管理页面的 http path 前缀,管理页面将位于:/admin_path_prefix/admin
|
admin_path_prefix: "/revsuit" # 管理页面的 http path 前缀,管理页面将位于:/admin_path_prefix/admin
|
||||||
database: revsuit.db # 数据库连接信息 支持Sqlite3、MySQL、Postgres
|
# 数据库连接信息 支持MySQL、Postgres、SQLite3
|
||||||
# database: "mysql://root:password@tcp(127.0.0.1:3306)/revsuit?charset=utf8mb4&parseTime=True&loc=Local"
|
database: "mysql://root:password@tcp(127.0.0.1:3306)/revsuit?charset=utf8mb4&parseTime=True&loc=Local"
|
||||||
# database: "postgres://host=127.0.0.1 user=root password=password dbname=revsuit port=5432 sslmode=disable TimeZone=Asia/Shanghai"
|
# database: "postgres://host=127.0.0.1 user=root password=password dbname=revsuit port=5432 sslmode=disable TimeZone=Asia/Shanghai"
|
||||||
|
#database: revsuit.db # 在部分系统上使用 sqlite 数据库时,在并发场景下可能会出现 `SQLITE BUSY` 的问题,因此不推荐在正式环境中使用该类型数据库
|
||||||
|
|
||||||
log_level: info # 输出日志的级别,分为:debug、info、warning、error、fatal
|
log_level: info # 输出日志的级别,分为:debug、info、warning、error、fatal
|
||||||
check_upgrade: false # 是否自动检查更新
|
check_upgrade: false # 是否自动检查更新
|
||||||
|
|||||||
@@ -158,6 +158,11 @@ example.
|
|||||||
As shown above, RevSuit supports multiple clients, and each client **in the connected state** receives a push of `flag`,
|
As shown above, RevSuit supports multiple clients, and each client **in the connected state** receives a push of `flag`,
|
||||||
so distributed scanning can be supported.
|
so distributed scanning can be supported.
|
||||||
|
|
||||||
|
If you don't want every client to receive all `flag` pushes, you can use the `Flag-Filter` request header when creating an sse connection to set the format(regular expressions) of the `flag` you want that client to receive:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
#### Temporary storage queue
|
#### Temporary storage queue
|
||||||
|
|
||||||
RevSuit will store `flag` temporarily in the queue when there is no client connection and send it when the client
|
RevSuit will store `flag` temporarily in the queue when there is no client connection and send it when the client
|
||||||
|
|||||||
@@ -140,6 +140,11 @@ RevSuit
|
|||||||
|
|
||||||
如上一节的图片里所展示的,RevSuit 支持多个客户端,每个在**连接状态**的客户端都会接收到 `flag` 的推送,因此分布式扫描也是支持的。
|
如上一节的图片里所展示的,RevSuit 支持多个客户端,每个在**连接状态**的客户端都会接收到 `flag` 的推送,因此分布式扫描也是支持的。
|
||||||
|
|
||||||
|
如果你不希望每个客户端都收到全部的 `flag` 推送,你可以在创建 sse 连接时,使用 `Flag-Filter` 请求头设置希望该客户端接受的 `flag` 的格式(支持正则表达式),例如:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
#### 暂存队列
|
#### 暂存队列
|
||||||
|
|
||||||
当没有客户端连接的时候,RevSuit 会把 `flag` 暂时存储到队列里,当有客户端连接的时候再进行推送。因此你不必担心因为客户端与 RevSuit 断开连接就错过漏洞。(这对发现延时触发的漏洞尤为有帮助)
|
当没有客户端连接的时候,RevSuit 会把 `flag` 暂时存储到队列里,当有客户端连接的时候再进行推送。因此你不必担心因为客户端与 RevSuit 断开连接就错过漏洞。(这对发现延时触发的漏洞尤为有帮助)
|
||||||
|
|||||||
Executable
BIN
Binary file not shown.
@@ -2,7 +2,7 @@ import axios from 'axios'
|
|||||||
import {store} from "@/main";
|
import {store} from "@/main";
|
||||||
|
|
||||||
const service = axios.create({
|
const service = axios.create({
|
||||||
baseURL: location.pathname.slice(0, -'/admin/'.length) + "/api", // api的base_url
|
baseURL: "../api", // api的base_url
|
||||||
timeout: 5000, // request timeout
|
timeout: 5000, // request timeout
|
||||||
validateStatus: function (status) {
|
validateStatus: function (status) {
|
||||||
if (status === 403) {
|
if (status === 403) {
|
||||||
|
|||||||
@@ -82,6 +82,15 @@ const columns = [
|
|||||||
filterIcon: 'filterIcon',
|
filterIcon: 'filterIcon',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: 'VALUE',
|
||||||
|
dataIndex: 'value',
|
||||||
|
key: 'value',
|
||||||
|
scopedSlots: {
|
||||||
|
filterDropdown: 'filterDropdown',
|
||||||
|
filterIcon: 'filterIcon',
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: 'REMOTE IP',
|
title: 'REMOTE IP',
|
||||||
key: 'remote_ip',
|
key: 'remote_ip',
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
<a-tag
|
<a-tag
|
||||||
v-if="file"
|
v-if="file"
|
||||||
color="#f5222d"
|
color="#f5222d"
|
||||||
><a target="_blank" :href="'/revsuit/api/file/ftp/'+file.id">TRUE</a> </a-tag>
|
><a target="_blank" :href="'../api/file/ftp/'+file.id">TRUE</a> </a-tag>
|
||||||
<a-tag v-else color="#722ed1">
|
<a-tag v-else color="#722ed1">
|
||||||
FALSE
|
FALSE
|
||||||
</a-tag>
|
</a-tag>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
>
|
>
|
||||||
<div v-if="record.files.length" slot="expandedRowRender" slot-scope="record" style="margin: 0">
|
<div v-if="record.files.length" slot="expandedRowRender" slot-scope="record" style="margin: 0">
|
||||||
<b v-if="record.files.length" style="color: gray">FILES:</b><br>
|
<b v-if="record.files.length" style="color: gray">FILES:</b><br>
|
||||||
<a v-for="file in record.files" :key="file.name+record.id" :href="'/revsuit/api/file/mysql/'+file.id"
|
<a v-for="file in record.files" :key="file.name+record.id" :href="'../api/file/mysql/'+file.id"
|
||||||
target="_blank">{{ file.name }} </a>
|
target="_blank">{{ file.name }} </a>
|
||||||
</div>
|
</div>
|
||||||
<div slot="selectDropdown"
|
<div slot="selectDropdown"
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
<a-space size="middle">
|
<a-space size="middle">
|
||||||
<a-upload
|
<a-upload
|
||||||
name="rules"
|
name="rules"
|
||||||
action="/revsuit/api/setting/importRules"
|
action="../api/setting/importRules"
|
||||||
@change="handleChange"
|
@change="handleChange"
|
||||||
:showUploadList="false"
|
:showUploadList="false"
|
||||||
>
|
>
|
||||||
<a-button type="primary" icon="upload">Import</a-button>
|
<a-button type="primary" icon="upload">Import</a-button>
|
||||||
</a-upload>
|
</a-upload>
|
||||||
<a-button type="primary" icon="download" onclick="window.open('/revsuit/api/setting/exportRules')">Export
|
<a-button type="primary" icon="download" onclick="window.open('../api/setting/exportRules')">Export
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
<a-result v-if="status"
|
<a-result v-if="status"
|
||||||
|
|||||||
@@ -10,15 +10,12 @@ module.exports = {
|
|||||||
devServer: {
|
devServer: {
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'http://localhost:10000',
|
target: 'http://127.0.0.1:10000/revsuit/',
|
||||||
pathRewrite: {
|
|
||||||
'^/api': '/revsuit/api'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
productionSourceMap: false,
|
productionSourceMap: false,
|
||||||
runtimeCompiler: true,
|
runtimeCompiler: true,
|
||||||
filenameHashing: false,
|
filenameHashing: false,
|
||||||
publicPath: '/revsuit/admin/',
|
publicPath: '',
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 894 KiB |
@@ -10,7 +10,7 @@ import (
|
|||||||
|
|
||||||
type File struct {
|
type File struct {
|
||||||
ID uint `gorm:"primarykey" form:"id" json:"id"`
|
ID uint `gorm:"primarykey" form:"id" json:"id"`
|
||||||
RecordID uint `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"-"`
|
RecordID uint `json:"-"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Content []byte `json:"-"`
|
Content []byte `json:"-"`
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-14
@@ -126,7 +126,7 @@ func (s *Server) newZone(name string) *newdns.Zone {
|
|||||||
"ns2.hostmaster.com.",
|
"ns2.hostmaster.com.",
|
||||||
"ns3.hostmaster.com.",
|
"ns3.hostmaster.com.",
|
||||||
},
|
},
|
||||||
Handler: func(lookedName, remoteAddr string) ([]newdns.Set, error) {
|
Handler: func(lookedName, remoteAddr string) (set []newdns.Set, err error) {
|
||||||
ip := strings.Split(remoteAddr, ":")[0]
|
ip := strings.Split(remoteAddr, ":")[0]
|
||||||
|
|
||||||
for _, _rule := range s.getRules() {
|
for _, _rule := range s.getRules() {
|
||||||
@@ -135,12 +135,24 @@ func (s *Server) newZone(name string) *newdns.Zone {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := newRecord(_rule, flag, domain, ip, ipinfo.Area(ip))
|
if _rule.Value != "" {
|
||||||
|
_type := _rule.Type
|
||||||
|
if _rule.Type == newdns.REBINDING {
|
||||||
|
_type = newdns.A
|
||||||
|
}
|
||||||
|
set = newSet(_rule, name, rule.CompileTpl(_rule.Value, vars), ip, _type)
|
||||||
|
}
|
||||||
|
|
||||||
|
var value string
|
||||||
|
if len(set) > 0 && len(set[0].Records) > 0 {
|
||||||
|
value = set[0].Records[0].Address
|
||||||
|
}
|
||||||
|
r, err := newRecord(_rule, flag, domain, value, ip, ipinfo.Area(ip))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("DNS record(rule_id:%s) created failed :%s", _rule.Name, err)
|
log.Warn("DNS record(rule_id:%s) created failed :%s", _rule.Name, err)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
log.Info("DNS record[id:%d rule:%s remote_ip:%s] has been created", r.ID, _rule.Name, ip)
|
log.Info("DNS record[id:%d rule:%s remote_ip:%s, value:%s] has been created", r.ID, _rule.Name, ip, value)
|
||||||
|
|
||||||
//only send to client or notify user when this connection recorded first time.
|
//only send to client or notify user when this connection recorded first time.
|
||||||
var count int64
|
var count int64
|
||||||
@@ -168,15 +180,7 @@ func (s *Server) newZone(name string) *newdns.Zone {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if _rule.Value != "" {
|
return set, err
|
||||||
value := rule.CompileTpl(_rule.Value, vars)
|
|
||||||
_type := _rule.Type
|
|
||||||
if _rule.Type == newdns.REBINDING {
|
|
||||||
_type = newdns.A
|
|
||||||
}
|
|
||||||
|
|
||||||
return newSet(_rule, name, value, ip, _type), nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@@ -204,9 +208,9 @@ func (s *Server) Run() {
|
|||||||
defer func() {
|
defer func() {
|
||||||
if s.Enable {
|
if s.Enable {
|
||||||
log.Error("DNS Server exited unexpectedly")
|
log.Error("DNS Server exited unexpectedly")
|
||||||
|
s.Enable = false
|
||||||
|
s.livingLock.Unlock()
|
||||||
}
|
}
|
||||||
s.Enable = false
|
|
||||||
s.livingLock.Unlock()
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := s.UpdateRules(); err != nil {
|
if err := s.UpdateRules(); err != nil {
|
||||||
|
|||||||
+6
-1
@@ -17,6 +17,7 @@ var _ record.Record = (*Record)(nil)
|
|||||||
|
|
||||||
type Record struct {
|
type Record struct {
|
||||||
Domain string `gorm:"index" form:"domain" json:"domain"`
|
Domain string `gorm:"index" form:"domain" json:"domain"`
|
||||||
|
Value string `form:"value" json:"value"`
|
||||||
|
|
||||||
record.BaseRecord
|
record.BaseRecord
|
||||||
Rule Rule `gorm:"foreignKey:RuleName;references:Name;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" form:"-" json:"-" notice:"-"`
|
Rule Rule `gorm:"foreignKey:RuleName;references:Name;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" form:"-" json:"-" notice:"-"`
|
||||||
@@ -30,7 +31,7 @@ func (r Record) Notice() {
|
|||||||
notice.Notice(r)
|
notice.Notice(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRecord(rule *Rule, flag, domain, remoteIp, ipArea string) (r *Record, err error) {
|
func newRecord(rule *Rule, flag, domain, value, remoteIp, ipArea string) (r *Record, err error) {
|
||||||
r = &Record{
|
r = &Record{
|
||||||
BaseRecord: record.BaseRecord{
|
BaseRecord: record.BaseRecord{
|
||||||
Flag: flag,
|
Flag: flag,
|
||||||
@@ -39,6 +40,7 @@ func newRecord(rule *Rule, flag, domain, remoteIp, ipArea string) (r *Record, er
|
|||||||
RequestTime: time.Now(),
|
RequestTime: time.Now(),
|
||||||
},
|
},
|
||||||
Domain: domain,
|
Domain: domain,
|
||||||
|
Value: value,
|
||||||
Rule: *rule,
|
Rule: *rule,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,6 +91,9 @@ func Records(c *gin.Context) {
|
|||||||
if dnsRecord.RuleName != "" {
|
if dnsRecord.RuleName != "" {
|
||||||
db.Where("rule_name = ?", dnsRecord.RuleName)
|
db.Where("rule_name = ?", dnsRecord.RuleName)
|
||||||
}
|
}
|
||||||
|
if dnsRecord.Value != "" {
|
||||||
|
db.Where("address= ?", dnsRecord.Value)
|
||||||
|
}
|
||||||
|
|
||||||
//Delete records
|
//Delete records
|
||||||
if c.Request.Method == http.MethodDelete {
|
if c.Request.Method == http.MethodDelete {
|
||||||
|
|||||||
+2
-2
@@ -359,9 +359,9 @@ func (s *Server) Run() {
|
|||||||
defer func() {
|
defer func() {
|
||||||
if s.Enable {
|
if s.Enable {
|
||||||
log.Error("FTP Server exited unexpectedly")
|
log.Error("FTP Server exited unexpectedly")
|
||||||
|
s.Enable = false
|
||||||
|
s.livingLock.Unlock()
|
||||||
}
|
}
|
||||||
s.Enable = false
|
|
||||||
s.livingLock.Unlock()
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := s.UpdateRules(); err != nil {
|
if err := s.UpdateRules(); err != nil {
|
||||||
|
|||||||
+1
-1
@@ -24,7 +24,7 @@ type Record struct {
|
|||||||
Path string `form:"path" json:"path"`
|
Path string `form:"path" json:"path"`
|
||||||
Method Method `form:"method" json:"method"`
|
Method Method `form:"method" json:"method"`
|
||||||
Status Status `form:"status" json:"status"`
|
Status Status `form:"status" json:"status"`
|
||||||
File *file.FTPFile `form:"file" json:"file" notice:"-"`
|
File *file.FTPFile `gorm:"foreignKey:RecordID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" form:"file" json:"file" notice:"-"`
|
||||||
Rule Rule `gorm:"foreignKey:RuleName;references:Name;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" form:"-" json:"-" notice:"-"`
|
Rule Rule `gorm:"foreignKey:RuleName;references:Name;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" form:"-" json:"-" notice:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -156,9 +156,9 @@ func (s *Server) Run() {
|
|||||||
defer func() {
|
defer func() {
|
||||||
if s.Enable {
|
if s.Enable {
|
||||||
log.Error("LDAP Server exited unexpectedly")
|
log.Error("LDAP Server exited unexpectedly")
|
||||||
|
s.Enable = false
|
||||||
|
s.livingLock.Unlock()
|
||||||
}
|
}
|
||||||
s.Enable = false
|
|
||||||
s.livingLock.Unlock()
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := s.UpdateRules(); err != nil {
|
if err := s.UpdateRules(); err != nil {
|
||||||
|
|||||||
+2
-2
@@ -284,9 +284,9 @@ func (s *Server) Run() {
|
|||||||
defer func() {
|
defer func() {
|
||||||
if s.Enable {
|
if s.Enable {
|
||||||
log.Error("MySQL Server exited unexpectedly")
|
log.Error("MySQL Server exited unexpectedly")
|
||||||
|
s.Enable = false
|
||||||
|
s.livingLock.Unlock()
|
||||||
}
|
}
|
||||||
s.Enable = false
|
|
||||||
s.livingLock.Unlock()
|
|
||||||
}()
|
}()
|
||||||
if err := s.UpdateRules(); err != nil {
|
if err := s.UpdateRules(); err != nil {
|
||||||
log.Error(err.Error())
|
log.Error(err.Error())
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ type Record struct {
|
|||||||
Schema string `gorm:"index" form:"schema" json:"schema" notice:"schema"`
|
Schema string `gorm:"index" form:"schema" json:"schema" notice:"schema"`
|
||||||
ClientOS string `gorm:"index" form:"client_os" json:"client_os" notice:"client_os"`
|
ClientOS string `gorm:"index" form:"client_os" json:"client_os" notice:"client_os"`
|
||||||
LoadLocalData bool `gorm:"index" form:"load_local_data" json:"load_local_data" notice:"load_local_data"`
|
LoadLocalData bool `gorm:"index" form:"load_local_data" json:"load_local_data" notice:"load_local_data"`
|
||||||
Files []file.MySQLFile `form:"-" json:"files" notice:"-"`
|
Files []file.MySQLFile `gorm:"foreignKey:RecordID;constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" form:"-" json:"files" notice:"-" `
|
||||||
Rule Rule `gorm:"foreignKey:RuleName;references:Name;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" form:"-" json:"-" notice:"-"`
|
Rule Rule `gorm:"foreignKey:RuleName;references:Name;constraint:OnUpdate:CASCADE,OnDelete:SET NULL;" form:"-" json:"-" notice:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -15,7 +15,7 @@ type Rule struct {
|
|||||||
rule.BaseRule `yaml:",inline"`
|
rule.BaseRule `yaml:",inline"`
|
||||||
ResponseStatusCode string `gorm:"index;default:200;not null" form:"response_status_code" json:"response_status_code" yaml:"response_status_code"`
|
ResponseStatusCode string `gorm:"index;default:200;not null" form:"response_status_code" json:"response_status_code" yaml:"response_status_code"`
|
||||||
ResponseHeaders database.MapField `form:"response_headers" json:"response_headers" yaml:"response_headers"`
|
ResponseHeaders database.MapField `form:"response_headers" json:"response_headers" yaml:"response_headers"`
|
||||||
ResponseBody string `gorm:"default:Hello RevSuit!" form:"response_body" json:"response_body" yaml:"response_body"`
|
ResponseBody string `gorm:"type:longtext" form:"response_body" json:"response_body" yaml:"response_body"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Rule) TableName() string {
|
func (Rule) TableName() string {
|
||||||
|
|||||||
+2
-2
@@ -165,9 +165,9 @@ func (s *Server) Run() {
|
|||||||
defer func() {
|
defer func() {
|
||||||
if s.Enable {
|
if s.Enable {
|
||||||
log.Error("RMI Server exited unexpectedly")
|
log.Error("RMI Server exited unexpectedly")
|
||||||
|
s.Enable = false
|
||||||
|
s.livingLock.Unlock()
|
||||||
}
|
}
|
||||||
s.Enable = false
|
|
||||||
s.livingLock.Unlock()
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := s.UpdateRules(); err != nil {
|
if err := s.UpdateRules(); err != nil {
|
||||||
|
|||||||
+21
-2
@@ -1,8 +1,10 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"regexp"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/gin-contrib/sse"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/li4n0/revsuit/internal/database"
|
"github.com/li4n0/revsuit/internal/database"
|
||||||
"github.com/li4n0/revsuit/internal/file"
|
"github.com/li4n0/revsuit/internal/file"
|
||||||
@@ -44,6 +46,8 @@ func (revsuit *Revsuit) addClient(c *gin.Context) int {
|
|||||||
|
|
||||||
revsuit.clientID++
|
revsuit.clientID++
|
||||||
revsuit.clients[revsuit.clientID] = c
|
revsuit.clients[revsuit.clientID] = c
|
||||||
|
sse.Event{}.WriteContentType(c.Writer)
|
||||||
|
c.Writer.Flush()
|
||||||
revsuit.clientsNum <- struct{}{}
|
revsuit.clientsNum <- struct{}{}
|
||||||
return revsuit.clientID
|
return revsuit.clientID
|
||||||
}
|
}
|
||||||
@@ -231,8 +235,23 @@ func (revsuit *Revsuit) Run() {
|
|||||||
<-revsuit.clientsNum
|
<-revsuit.clientsNum
|
||||||
revsuit.clientsLock.RLock()
|
revsuit.clientsLock.RLock()
|
||||||
for _, client := range revsuit.clients {
|
for _, client := range revsuit.clients {
|
||||||
client.SSEvent("message", r.GetFlag())
|
pushIt := false
|
||||||
client.Writer.Flush()
|
flag := client.Request.Header.Get("Flag-Filter")
|
||||||
|
if len(flag) == 0 || flag == "*" {
|
||||||
|
pushIt = true
|
||||||
|
} else {
|
||||||
|
if catcher, err := regexp.Compile(flag); err != nil {
|
||||||
|
log.Warn("%s[sse flag:%s]", err, flag)
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
matched := catcher.FindStringSubmatch(r.GetFlag())
|
||||||
|
pushIt = len(matched) > 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if pushIt {
|
||||||
|
client.SSEvent("message", r.GetFlag())
|
||||||
|
client.Writer.Flush()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
revsuit.clientsNum <- struct{}{}
|
revsuit.clientsNum <- struct{}{}
|
||||||
revsuit.clientsLock.RUnlock()
|
revsuit.clientsLock.RUnlock()
|
||||||
|
|||||||
Reference in New Issue
Block a user