mirror of
https://github.com/Li4n0/revsuit.git
synced 2026-09-21 22:30:46 +08:00
feat: add domain and external ip configuration items (#18)
This commit is contained in:
+1
-1
@@ -7,7 +7,7 @@ revsuit.db-shm
|
||||
revsuit.db-wal
|
||||
|
||||
# local config
|
||||
config.yaml
|
||||
config.yaml*
|
||||
|
||||
# binary
|
||||
revsuit
|
||||
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
.custom-icons-list[data-v-05a908c2] .anticon{margin-right:6px}body[data-v-171364ce],html[data-v-171364ce]{height:100%;margin:0}.fade-transform-enter-active[data-v-171364ce],.fade-transform-leave-active[data-v-171364ce]{transition:all .3s;opacity:0}.fade-transform-enter[data-v-171364ce],.fade-transform-leave[data-v-171364ce]{opacity:0}.fade-transform-enter-to[data-v-171364ce]{opacity:0}.ant-menu-item>span>a[data-v-171364ce]{color:hsla(0,0%,100%,.65)}.ant-menu-item-selected>span>a[data-v-171364ce]{color:#fff}#nav[data-v-171364ce]{height:100%}#nav .trigger[data-v-171364ce]{font-size:18px;line-height:64px;padding:0 24px;cursor:pointer;transition:color .3s}#nav .trigger[data-v-171364ce]:hover{color:#1890ff}#nav .logo[data-v-171364ce]{height:32px;background:#0a1d2d;margin:16px;text-align:center;font-size:1.2rem;color:#fff;padding-bottom:5px;border-bottom:2px solid #b6befa}.copyright[data-v-171364ce]{color:#888;text-align:right;margin-right:1rem}
|
||||
.custom-icons-list[data-v-05a908c2] .anticon{margin-right:6px}body[data-v-4ae4fda9],html[data-v-4ae4fda9]{height:100%;margin:0}.fade-transform-enter-active[data-v-4ae4fda9],.fade-transform-leave-active[data-v-4ae4fda9]{transition:all .3s;opacity:0}.fade-transform-enter[data-v-4ae4fda9],.fade-transform-leave[data-v-4ae4fda9]{opacity:0}.fade-transform-enter-to[data-v-4ae4fda9]{opacity:0}.ant-menu-item>span>a[data-v-4ae4fda9]{color:hsla(0,0%,100%,.65)}.ant-menu-item-selected>span>a[data-v-4ae4fda9]{color:#fff}#nav[data-v-4ae4fda9]{height:100%}#nav .trigger[data-v-4ae4fda9]{font-size:18px;line-height:64px;padding:0 24px;cursor:pointer;transition:color .3s}#nav .trigger[data-v-4ae4fda9]:hover{color:#1890ff}#nav .logo[data-v-4ae4fda9]{height:32px;background:#0a1d2d;margin:16px;text-align:center;font-size:1.2rem;color:#fff;padding-bottom:5px;border-bottom:2px solid #b6befa}.copyright[data-v-4ae4fda9]{color:#888;text-align:right;margin-right:1rem}
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
#add-rule[data-v-2586daf9]{margin-bottom:10px}
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
#add-rule[data-v-487bb706]{margin-bottom:10px}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
#add-rule[data-v-ae6501fc]{margin-bottom:10px}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
#add-rule[data-v-5aa75eae]{margin-bottom:10px}
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
#add-rule[data-v-f1cd719a]{margin-bottom:10px}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
#add-rule[data-v-4bcc6b83]{margin-bottom:10px}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
#add-rule[data-v-79ad429e]{margin-bottom:10px}.full-screen-icon[data-v-79ad429e]{position:absolute;z-index:5;color:#9e9e9e;right:1px;font-size:1rem;cursor:pointer;transition:font-size .1s}.full-screen-icon[data-v-79ad429e]:hover{font-size:1.1rem;transition:font-size .1s}
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
#add-rule[data-v-376729b6]{margin-bottom:10px}
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
#add-rule[data-v-169b853c]{margin-bottom:10px}.full-screen-icon[data-v-169b853c]{position:absolute;z-index:5;color:#9e9e9e;right:1px;font-size:1rem;cursor:pointer;transition:font-size .1s}.full-screen-icon[data-v-169b853c]:hover{font-size:1.1rem;transition:font-size .1s}
|
||||
Vendored
-1
@@ -1 +0,0 @@
|
||||
#add-rule[data-v-98f944a6]{margin-bottom:10px}
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>RevSuit Control Panel</title><link href="css/chunk-0155152b.css" rel="prefetch"><link href="css/chunk-1da7f23b.css" rel="prefetch"><link href="css/chunk-2e835d68.css" rel="prefetch"><link href="css/chunk-330a7e95.css" rel="prefetch"><link href="css/chunk-3d13e56e.css" rel="prefetch"><link href="css/chunk-5840ae94.css" rel="prefetch"><link href="css/chunk-d4730ae2.css" rel="prefetch"><link href="css/chunk-e00d17cc.css" rel="prefetch"><link href="css/chunk-e039e75a.css" rel="prefetch"><link href="css/chunk-fef965c2.css" rel="prefetch"><link href="js/chunk-0155152b.js" rel="prefetch"><link href="js/chunk-08f9fbe8.js" rel="prefetch"><link href="js/chunk-1da7f23b.js" rel="prefetch"><link href="js/chunk-2e835d68.js" rel="prefetch"><link href="js/chunk-330a7e95.js" rel="prefetch"><link href="js/chunk-3d13e56e.js" rel="prefetch"><link href="js/chunk-5840ae94.js" rel="prefetch"><link href="js/chunk-b241c712.js" rel="prefetch"><link href="js/chunk-d4730ae2.js" rel="prefetch"><link href="js/chunk-e00d17cc.js" rel="prefetch"><link href="js/chunk-e039e75a.js" rel="prefetch"><link href="js/chunk-fef965c2.js" rel="prefetch"><link href="css/app.css" rel="preload" as="style"><link href="css/chunk-vendors.css" rel="preload" as="style"><link href="js/app.js" rel="preload" as="script"><link href="js/chunk-vendors.js" rel="preload" as="script"><link href="css/chunk-vendors.css" rel="stylesheet"><link href="css/app.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but revsuit-frontend doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.js"></script><script src="js/app.js"></script></body></html>
|
||||
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>RevSuit Control Panel</title><link href="css/chunk-1da7f23b.css" rel="prefetch"><link href="css/chunk-330a7e95.css" rel="prefetch"><link href="css/chunk-36391b77.css" rel="prefetch"><link href="css/chunk-3d13e56e.css" rel="prefetch"><link href="css/chunk-42105840.css" rel="prefetch"><link href="css/chunk-65a35ecf.css" rel="prefetch"><link href="css/chunk-7bcb83e6.css" rel="prefetch"><link href="css/chunk-b8f538aa.css" rel="prefetch"><link href="css/chunk-e039e75a.css" rel="prefetch"><link href="css/chunk-fef965c2.css" rel="prefetch"><link href="js/chunk-08f9fbe8.js" rel="prefetch"><link href="js/chunk-1da7f23b.js" rel="prefetch"><link href="js/chunk-330a7e95.js" rel="prefetch"><link href="js/chunk-36391b77.js" rel="prefetch"><link href="js/chunk-3d13e56e.js" rel="prefetch"><link href="js/chunk-42105840.js" rel="prefetch"><link href="js/chunk-65a35ecf.js" rel="prefetch"><link href="js/chunk-7bcb83e6.js" rel="prefetch"><link href="js/chunk-b241c712.js" rel="prefetch"><link href="js/chunk-b8f538aa.js" rel="prefetch"><link href="js/chunk-e039e75a.js" rel="prefetch"><link href="js/chunk-fef965c2.js" rel="prefetch"><link href="css/app.css" rel="preload" as="style"><link href="css/chunk-vendors.css" rel="preload" as="style"><link href="js/app.js" rel="preload" as="script"><link href="js/chunk-vendors.js" rel="preload" as="script"><link href="css/chunk-vendors.css" rel="stylesheet"><link href="css/app.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but revsuit-frontend doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.js"></script><script src="js/app.js"></script></body></html>
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -179,7 +179,6 @@ export default {
|
||||
} else {
|
||||
this.timing()
|
||||
}
|
||||
localStorage.setItem('autoRefresh', val)
|
||||
},
|
||||
refreshInterval(val) {
|
||||
clearInterval(this.timer)
|
||||
@@ -193,8 +192,11 @@ export default {
|
||||
store.pageSize = val
|
||||
localStorage.setItem('pageSize', val)
|
||||
},
|
||||
'store.authed'() {
|
||||
'store.authed'(val) {
|
||||
if (val) {
|
||||
this.$refs.content.fetch()
|
||||
this.GetVersion()
|
||||
}
|
||||
},
|
||||
'store.pageSize'() {
|
||||
this.$refs.content.pagination.pageSize = store.pageSize
|
||||
|
||||
@@ -5,9 +5,6 @@ export function auth(token) {
|
||||
url: '/auth',
|
||||
method: 'get',
|
||||
headers: {"Token": token},
|
||||
validateStatus: function (status) {
|
||||
return status >= 200 && status < 300
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -15,8 +12,5 @@ export function getVersion() {
|
||||
return request({
|
||||
url: '/version',
|
||||
method: 'get',
|
||||
validateStatus: function (status) {
|
||||
return status >= 200 && status < 300
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -1,9 +1,13 @@
|
||||
import axios from 'axios'
|
||||
import {store} from "@/main";
|
||||
|
||||
const service = axios.create({
|
||||
baseURL: '/revsuit/api/', // api的base_url
|
||||
timeout: 5000, // request timeout
|
||||
validateStatus: function (status) {
|
||||
if (status === 403) {
|
||||
store.authed = false
|
||||
}
|
||||
return status >= 200 && status < 300 // 默认的
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import request from './index'
|
||||
|
||||
export function getHttpConfig() {
|
||||
export function getPlatformConfig() {
|
||||
return request({
|
||||
url: '/setting/getHttpConfig',
|
||||
url: '/setting/getPlatformConfig',
|
||||
})
|
||||
}
|
||||
|
||||
export function updateHttpConfig(data) {
|
||||
export function updatePlatformConfig(data) {
|
||||
return request({
|
||||
url: '/setting/updateHttpConfig',
|
||||
url: '/setting/updatePlatformConfig',
|
||||
method: "post",
|
||||
data: data
|
||||
})
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<a-input
|
||||
v-model="form.flag_format"
|
||||
style="width: 100%"
|
||||
placeholder="please enter flag format"
|
||||
placeholder="Please enter flag format"
|
||||
:readOnly="readOnly"
|
||||
/>
|
||||
</a-form-model-item>
|
||||
|
||||
@@ -139,12 +139,14 @@ export default {
|
||||
this.pagination = pagination;
|
||||
this.loading = false
|
||||
}).catch(e => {
|
||||
if (e.response.status === 403) {
|
||||
store.authed = false
|
||||
return []
|
||||
} else {
|
||||
console.error(e)
|
||||
}
|
||||
this.$notification.error({
|
||||
message: 'Unknown error: ' + e.response.status,
|
||||
style: {
|
||||
width: '100px',
|
||||
marginLeft: `${335 - 600}px`,
|
||||
},
|
||||
duration: 4
|
||||
});
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
@@ -228,12 +228,14 @@ export default {
|
||||
this.pagination = pagination;
|
||||
this.loading = false
|
||||
}).catch(e => {
|
||||
if (e.response.status === 403) {
|
||||
store.authed = false
|
||||
return []
|
||||
} else {
|
||||
console.error(e)
|
||||
}
|
||||
this.$notification.error({
|
||||
message: 'Unknown error: ' + e.response.status,
|
||||
style: {
|
||||
width: '100px',
|
||||
marginLeft: `${335 - 600}px`,
|
||||
},
|
||||
duration: 4
|
||||
});
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
@@ -173,12 +173,14 @@ export default {
|
||||
this.pagination = pagination;
|
||||
this.loading = false
|
||||
}).catch(e => {
|
||||
if (e.response.status === 403) {
|
||||
store.authed = false
|
||||
return []
|
||||
} else {
|
||||
console.error(e)
|
||||
}
|
||||
this.$notification.error({
|
||||
message: 'Unknown error: ' + e.response.status,
|
||||
style: {
|
||||
width: '100px',
|
||||
marginLeft: `${335 - 600}px`,
|
||||
},
|
||||
duration: 4
|
||||
});
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
@@ -216,12 +216,14 @@ export default {
|
||||
this.pagination = pagination;
|
||||
this.loading = false
|
||||
}).catch(e => {
|
||||
if (e.response.status === 403) {
|
||||
store.authed = false
|
||||
return []
|
||||
} else {
|
||||
console.error(e)
|
||||
}
|
||||
this.$notification.error({
|
||||
message: 'Unknown error: ' + e.response.status,
|
||||
style: {
|
||||
width: '100px',
|
||||
marginLeft: `${335 - 600}px`,
|
||||
},
|
||||
duration: 4
|
||||
});
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
@@ -140,12 +140,14 @@ export default {
|
||||
this.pagination = pagination;
|
||||
this.loading = false
|
||||
}).catch(e => {
|
||||
if (e.response.status === 403) {
|
||||
store.authed = false
|
||||
return []
|
||||
} else {
|
||||
console.error(e)
|
||||
}
|
||||
this.$notification.error({
|
||||
message: 'Unknown error: ' + e.response.status,
|
||||
style: {
|
||||
width: '100px',
|
||||
marginLeft: `${335 - 600}px`,
|
||||
},
|
||||
duration: 4
|
||||
});
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
@@ -332,10 +332,6 @@ export default {
|
||||
this.pagination = pagination;
|
||||
this.loading = false
|
||||
}).catch(e => {
|
||||
if (e.response.status === 403) {
|
||||
store.authed = false
|
||||
return []
|
||||
} else {
|
||||
this.$notification.error({
|
||||
message: 'Unknown error: ' + e.response.status,
|
||||
style: {
|
||||
@@ -344,7 +340,6 @@ export default {
|
||||
},
|
||||
duration: 4
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
clickSwitch(record, prop) {
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<a-input
|
||||
v-model="form.pasv_address"
|
||||
style="width: 100%"
|
||||
placeholder="use default value in the config"
|
||||
placeholder="Use external IP by default"
|
||||
:readOnly="formReadOnly"
|
||||
/>
|
||||
</a-form-model-item>
|
||||
@@ -267,10 +267,6 @@ export default {
|
||||
this.pagination = pagination;
|
||||
this.loading = false
|
||||
}).catch(e => {
|
||||
if (e.response.status === 403) {
|
||||
store.authed = false
|
||||
return []
|
||||
} else {
|
||||
this.$notification.error({
|
||||
message: 'Unknown error: ' + e.response.status,
|
||||
style: {
|
||||
@@ -279,7 +275,6 @@ export default {
|
||||
},
|
||||
duration: 4
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
clickSwitch(record, prop) {
|
||||
|
||||
@@ -374,10 +374,6 @@ export default {
|
||||
this.pagination = pagination;
|
||||
this.loading = false
|
||||
}).catch(e => {
|
||||
if (e.response.status === 403) {
|
||||
store.authed = false
|
||||
return []
|
||||
} else {
|
||||
this.$notification.error({
|
||||
message: 'Unknown error: ' + e.response.status,
|
||||
style: {
|
||||
@@ -386,7 +382,6 @@ export default {
|
||||
},
|
||||
duration: 4
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
clickSwitch(record, prop) {
|
||||
|
||||
@@ -297,10 +297,6 @@ export default {
|
||||
this.pagination = pagination;
|
||||
this.loading = false
|
||||
}).catch(e => {
|
||||
if (e.response.status === 403) {
|
||||
store.authed = false
|
||||
return []
|
||||
} else {
|
||||
this.$notification.error({
|
||||
message: 'Unknown error: ' + e.response.status,
|
||||
style: {
|
||||
@@ -309,7 +305,6 @@ export default {
|
||||
},
|
||||
duration: 4
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
clickSwitch(record, prop) {
|
||||
|
||||
@@ -225,10 +225,6 @@ export default {
|
||||
this.pagination = pagination;
|
||||
this.loading = false
|
||||
}).catch(e => {
|
||||
if (e.response.status === 403) {
|
||||
store.authed = false
|
||||
return []
|
||||
} else {
|
||||
this.$notification.error({
|
||||
message: 'Unknown error: ' + e.response.status,
|
||||
style: {
|
||||
@@ -237,7 +233,6 @@ export default {
|
||||
},
|
||||
duration: 4
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
clickSwitch(record, prop) {
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getHttpConfig, updateHttpConfig} from "@/api/settings"
|
||||
import {getPlatformConfig, updatePlatformConfig} from "@/api/settings"
|
||||
import SettingForm from "@/components/SettingForm";
|
||||
|
||||
export default {
|
||||
@@ -37,7 +37,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
getConfig() {
|
||||
getHttpConfig().then(res => {
|
||||
getPlatformConfig().then(res => {
|
||||
this.form = res.data
|
||||
}).catch(e => {
|
||||
this.$notification.error({
|
||||
@@ -55,10 +55,10 @@ export default {
|
||||
updateConfig() {
|
||||
this.spinning = true
|
||||
let targetConfig = JSON.stringify(this.form)
|
||||
updateHttpConfig(this.form).then(
|
||||
updatePlatformConfig(this.form).then(
|
||||
() => {
|
||||
setTimeout(() => {
|
||||
getHttpConfig().then((res) => {
|
||||
getPlatformConfig().then((res) => {
|
||||
this.spinning = false
|
||||
let nowConfig = JSON.stringify(res.data)
|
||||
if (nowConfig !== targetConfig) {
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
:active-tab-key="tabKey"
|
||||
@tabChange="key => this.tabKey = key"
|
||||
style="width: 100%;">
|
||||
<http v-if="tabKey==='HTTP'"></http>
|
||||
<dns v-else-if="tabKey==='DNS'"></dns>
|
||||
<rmi v-else-if="tabKey==='RMI'"></rmi>
|
||||
<mysql v-else-if="tabKey==='MYSQL'"></mysql>
|
||||
<ftp v-else-if="tabKey==='FTP'"></ftp>
|
||||
<notice v-else-if="tabKey==='NOTICE'"></notice>
|
||||
<rules v-else-if="tabKey==='RULES'"></rules>
|
||||
<http ref="settings" v-if="tabKey==='HTTP'"></http>
|
||||
<dns ref="settings" v-else-if="tabKey==='DNS'"></dns>
|
||||
<rmi ref="settings" v-else-if="tabKey==='RMI'"></rmi>
|
||||
<mysql ref="settings" v-else-if="tabKey==='MYSQL'"></mysql>
|
||||
<ftp ref="settings" v-else-if="tabKey==='FTP'"></ftp>
|
||||
<notice ref="settings" v-else-if="tabKey==='NOTICE'"></notice>
|
||||
<rules ref="settings" v-else-if="tabKey==='RULES'"></rules>
|
||||
</a-card>
|
||||
</div>
|
||||
</template>
|
||||
@@ -42,7 +42,11 @@ export default {
|
||||
}
|
||||
}
|
||||
,
|
||||
methods: {},
|
||||
methods: {
|
||||
fetch() {
|
||||
this.$refs.settings.getConfig();
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Http,
|
||||
Dns,
|
||||
|
||||
+12
-1
@@ -47,10 +47,21 @@ func Start() {
|
||||
configFile = c.Path("config")
|
||||
}
|
||||
conf := &server.Config{}
|
||||
tpl := &server.Config{}
|
||||
_ = yaml.Unmarshal(configTemplate, tpl)
|
||||
if content, err := os.ReadFile(configFile); err == nil {
|
||||
if err := yaml.Unmarshal(content, conf); err != nil {
|
||||
return err
|
||||
}
|
||||
if conf.Version != tpl.Version {
|
||||
backup := fmt.Sprintf("%s_%.1f", configFile, conf.Version)
|
||||
log.Warn("Old version of configuration file detected, new configuration file being generated, old configuration backed up to %s", backup)
|
||||
if err := os.WriteFile(backup, content, 0644); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(configFile, configTemplate, 0644)
|
||||
}
|
||||
|
||||
} else if os.IsNotExist(err) && configFile == "config.yaml" {
|
||||
log.Warn("Generate default configurations to config.yaml, please configure and run again.")
|
||||
return os.WriteFile("config.yaml", configTemplate, 0644)
|
||||
@@ -69,13 +80,13 @@ func Start() {
|
||||
if c.String("log") != "" {
|
||||
conf.Database = c.String("log")
|
||||
}
|
||||
fmt.Printf(banner, server.VERSION)
|
||||
server.New(conf).Run()
|
||||
return nil
|
||||
},
|
||||
}
|
||||
sort.Sort(cli.FlagsByName(app.Flags))
|
||||
sort.Sort(cli.CommandsByName(app.Commands))
|
||||
fmt.Printf(banner, server.VERSION)
|
||||
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
version: 4.0
|
||||
version: 1.0
|
||||
addr: :10000
|
||||
token:
|
||||
domain:
|
||||
external_ip: # You need to make sure that your target can access the server through this ip.
|
||||
database: revsuit.db
|
||||
log_level: info
|
||||
|
||||
@@ -18,7 +20,6 @@ mysql:
|
||||
ftp:
|
||||
enable: true
|
||||
addr: :21
|
||||
pasv_ip: 127.0.0.1 # your public network ip
|
||||
pasv_port: 2020
|
||||
notice:
|
||||
dingtalk: https://oapi.dingtalk.com/robot/send?access_token={token}
|
||||
|
||||
+52
-8
@@ -17,6 +17,8 @@ import (
|
||||
|
||||
type Server struct {
|
||||
Config
|
||||
serverDomain string
|
||||
serverIP string
|
||||
rules []*Rule
|
||||
rulesLock sync.RWMutex
|
||||
livingLock sync.Mutex
|
||||
@@ -35,6 +37,16 @@ func GetServer() *Server {
|
||||
return server
|
||||
}
|
||||
|
||||
func (s *Server) SetServerDomain(serverDomain string) *Server {
|
||||
s.serverDomain = serverDomain
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Server) SetServerIP(serverIP string) *Server {
|
||||
s.serverIP = serverIP
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Server) getRules() []*Rule {
|
||||
defer s.rulesLock.RUnlock()
|
||||
s.rulesLock.RLock()
|
||||
@@ -53,6 +65,7 @@ func newSet(_rule *Rule, name, value, ip string, _type newdns.Type) []newdns.Set
|
||||
{
|
||||
Name: name,
|
||||
Type: _type,
|
||||
TTL: _rule.TTL * time.Second,
|
||||
Records: func() []newdns.Record {
|
||||
switch _rule.Type {
|
||||
case newdns.TXT:
|
||||
@@ -82,12 +95,20 @@ func newSet(_rule *Rule, name, value, ip string, _type newdns.Type) []newdns.Set
|
||||
return []newdns.Record{{Address: value}}
|
||||
}
|
||||
}(),
|
||||
TTL: _rule.TTL * time.Second,
|
||||
},
|
||||
}
|
||||
return set
|
||||
}
|
||||
|
||||
func getZoneName(domain string) string {
|
||||
frags := strings.Split(domain, ".")
|
||||
zoneName := domain
|
||||
if len(frags) >= 2 {
|
||||
zoneName = strings.Join(frags[len(frags)-2:], ".") + "."
|
||||
}
|
||||
return zoneName
|
||||
}
|
||||
|
||||
// newZone creates new dns zone with root domain
|
||||
func (s *Server) newZone(name string) *newdns.Zone {
|
||||
defer func() {
|
||||
@@ -97,13 +118,8 @@ func (s *Server) newZone(name string) *newdns.Zone {
|
||||
}()
|
||||
|
||||
domain := strings.TrimSuffix(name, ".")
|
||||
frags := strings.Split(domain, ".")
|
||||
zoneName := name
|
||||
if len(frags) >= 2 {
|
||||
zoneName = strings.Join(frags[len(frags)-2:], ".") + "."
|
||||
}
|
||||
zone := &newdns.Zone{
|
||||
Name: zoneName,
|
||||
Name: getZoneName(domain),
|
||||
MasterNameServer: "ns1.hostmaster.com.",
|
||||
AllNameServers: []string{
|
||||
"ns1.hostmaster.com.",
|
||||
@@ -175,6 +191,12 @@ func (s *Server) Stop() {
|
||||
s.livingLock.Unlock()
|
||||
}
|
||||
|
||||
func (s *Server) Restart() {
|
||||
s.Stop()
|
||||
time.Sleep(time.Second * 2)
|
||||
go s.Run()
|
||||
}
|
||||
|
||||
func (s *Server) Run() {
|
||||
s.Enable = true
|
||||
s.livingLock.Lock()
|
||||
@@ -195,12 +217,34 @@ func (s *Server) Run() {
|
||||
// create server
|
||||
server := newdns.NewServer(newdns.Config{
|
||||
Handler: func(name string) (*newdns.Zone, error) {
|
||||
if name == s.serverDomain+"." {
|
||||
return &newdns.Zone{
|
||||
Name: getZoneName(s.serverDomain),
|
||||
MasterNameServer: "ns1.hostmaster.com.",
|
||||
AllNameServers: []string{
|
||||
"ns1.hostmaster.com.",
|
||||
"ns2.hostmaster.com.",
|
||||
"ns3.hostmaster.com.",
|
||||
},
|
||||
Handler: func(_, remoteAddr string) ([]newdns.Set, error) {
|
||||
return []newdns.Set{
|
||||
{
|
||||
Name: name,
|
||||
Type: newdns.A,
|
||||
TTL: 10,
|
||||
Records: []newdns.Record{
|
||||
{
|
||||
Address: s.serverIP,
|
||||
},
|
||||
}}}, nil
|
||||
}}, nil
|
||||
}
|
||||
return s.newZone(name), nil
|
||||
},
|
||||
})
|
||||
|
||||
// run server
|
||||
log.Info("Starting DNS Server at :53")
|
||||
log.Info("Starting DNS Server at :53, resolve %s to %s", s.serverDomain, s.serverIP)
|
||||
go func() {
|
||||
s.livingLock.Lock()
|
||||
if !s.Enable {
|
||||
|
||||
@@ -3,6 +3,5 @@ package ftp
|
||||
type Config struct {
|
||||
Enable bool
|
||||
Addr string
|
||||
PasvIP string `yaml:"pasv_ip"`
|
||||
PasvPort int `yaml:"pasv_port"`
|
||||
}
|
||||
|
||||
+9
-3
@@ -22,6 +22,7 @@ import (
|
||||
|
||||
type Server struct {
|
||||
Config
|
||||
pasvIP string
|
||||
rules []*Rule
|
||||
rulesLock sync.RWMutex
|
||||
livingLock sync.Mutex
|
||||
@@ -55,6 +56,11 @@ func GetServer() *Server {
|
||||
return server
|
||||
}
|
||||
|
||||
func (s *Server) SetPasvIP(ip string) *Server {
|
||||
s.pasvIP = ip
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Server) getRules() []*Rule {
|
||||
defer s.rulesLock.RUnlock()
|
||||
s.rulesLock.RLock()
|
||||
@@ -194,10 +200,10 @@ loop:
|
||||
_, _ = connBuf.WriteString(UserLogged)
|
||||
|
||||
if pasvAddress = s.getPasvAddressFromCache(ip, _rule.PasvAddress); pasvAddress == "" {
|
||||
pasvAddress = fmt.Sprintf("%s:%d", s.PasvIP, s.PasvPort)
|
||||
pasvAddress = fmt.Sprintf("%s:%d", s.pasvIP, s.PasvPort)
|
||||
}
|
||||
|
||||
isRedirect = rule.CompileTpl(pasvAddress, vars) != fmt.Sprintf("%s:%d", s.PasvIP, s.PasvPort)
|
||||
isRedirect = rule.CompileTpl(pasvAddress, vars) != fmt.Sprintf("%s:%d", s.pasvIP, s.PasvPort)
|
||||
case "SIZE":
|
||||
path += strings.TrimLeft(args, "/")
|
||||
if _rule == nil || isRedirect || len(_rule.Data) == 0 {
|
||||
@@ -312,7 +318,7 @@ func (s *Server) handlePasvConnection(conn net.Conn, data map[string]interface{}
|
||||
// run pasv server
|
||||
func (s *Server) runPasvServer() (net.Listener, error) {
|
||||
pasvAddress := fmt.Sprintf("%s:%d", strings.Split(s.Addr, ":")[0], s.PasvPort)
|
||||
log.Info("Start to listen FTP PASV port at %v, PasvIP is %v", pasvAddress, s.PasvIP)
|
||||
log.Info("Start to listen FTP PASV port at %v, PasvIP is %v", pasvAddress, s.pasvIP)
|
||||
listener, err := net.Listen("tcp", pasvAddress)
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -16,8 +16,11 @@ type noticeConfig struct {
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Version float64
|
||||
Addr string
|
||||
Token string
|
||||
Domain string
|
||||
ExternalIP string `yaml:"external_ip"`
|
||||
Database string
|
||||
LogLevel string `yaml:"log_level"`
|
||||
Notice noticeConfig
|
||||
|
||||
@@ -59,8 +59,8 @@ func (revsuit *Revsuit) registerHttpRouter() {
|
||||
settingsGroup := revsuit.http.ApiGroup.Group("setting")
|
||||
settingsGroup.GET("/exportRules", exportRules)
|
||||
settingsGroup.POST("/importRules", importRules)
|
||||
settingsGroup.GET("/getHttpConfig", revsuit.getHttpConfig)
|
||||
settingsGroup.POST("/updateHttpConfig", revsuit.updateHttpConfig)
|
||||
settingsGroup.GET("/getPlatformConfig", revsuit.getPlatformConfig)
|
||||
settingsGroup.POST("/updatePlatformConfig", revsuit.updatePlatformConfig)
|
||||
settingsGroup.GET("/getDnsConfig", revsuit.getDnsConfig)
|
||||
settingsGroup.POST("/updateDnsConfig", revsuit.updateDnsConfig)
|
||||
settingsGroup.GET("/getRmiConfig", revsuit.getRmiConfig)
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
log "unknwon.dev/clog/v2"
|
||||
)
|
||||
|
||||
const VERSION = "0.1.1-beta"
|
||||
const VERSION = "0.1.2-beta"
|
||||
|
||||
type Revsuit struct {
|
||||
config *Config
|
||||
@@ -181,6 +181,13 @@ func New(c *Config) *Revsuit {
|
||||
if c.IpHeader != "" {
|
||||
s.http.SetIpHeader(c.IpHeader)
|
||||
}
|
||||
if c.Domain != "" {
|
||||
s.dns.SetServerDomain(c.Domain)
|
||||
}
|
||||
if c.ExternalIP != "" {
|
||||
s.dns.SetServerIP(c.ExternalIP)
|
||||
s.ftp.SetPasvIP(c.ExternalIP)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
|
||||
+32
-7
@@ -138,10 +138,12 @@ func importRules(c *gin.Context) {
|
||||
})
|
||||
}
|
||||
|
||||
func (revsuit *Revsuit) getHttpConfig(c *gin.Context) {
|
||||
func (revsuit *Revsuit) getPlatformConfig(c *gin.Context) {
|
||||
var res = make(map[string]string)
|
||||
res["Addr"] = revsuit.config.Addr
|
||||
res["Token"] = revsuit.config.Token
|
||||
res["Domain"] = revsuit.config.Domain
|
||||
res["ExternalIP"] = revsuit.config.ExternalIP
|
||||
res["Database"] = revsuit.config.Database
|
||||
res["LogLevel"] = revsuit.config.LogLevel
|
||||
res["IpHeader"] = revsuit.config.IpHeader
|
||||
@@ -149,7 +151,7 @@ func (revsuit *Revsuit) getHttpConfig(c *gin.Context) {
|
||||
c.JSON(200, res)
|
||||
}
|
||||
|
||||
func (revsuit *Revsuit) updateHttpConfig(c *gin.Context) {
|
||||
func (revsuit *Revsuit) updatePlatformConfig(c *gin.Context) {
|
||||
var form = make(map[string]string)
|
||||
|
||||
if err := c.ShouldBindJSON(&form); err != nil {
|
||||
@@ -188,6 +190,34 @@ func (revsuit *Revsuit) updateHttpConfig(c *gin.Context) {
|
||||
log.Info("Update http config [ip_header] to %s", form["IpHeader"])
|
||||
}
|
||||
|
||||
if form["Domain"] != revsuit.config.Domain {
|
||||
revsuit.config.Domain = form["Domain"]
|
||||
revsuit.dns.SetServerDomain(form["Domain"])
|
||||
log.Info("Update platform config [domain] to %s", form["Domain"])
|
||||
if revsuit.dns.Enable {
|
||||
revsuit.dns.Restart()
|
||||
}
|
||||
}
|
||||
|
||||
if form["ExternalIP"] != revsuit.config.ExternalIP {
|
||||
revsuit.config.ExternalIP = form["ExternalIP"]
|
||||
revsuit.dns.SetServerIP(form["ExternalIP"])
|
||||
revsuit.ftp.SetPasvIP(form["ExternalIP"])
|
||||
log.Info("Update platform config [ExternalIP] to %s", form["ExternalIP"])
|
||||
if revsuit.dns.Enable {
|
||||
revsuit.dns.Restart()
|
||||
}
|
||||
if revsuit.ftp.Enable {
|
||||
revsuit.ftp.Restart()
|
||||
}
|
||||
}
|
||||
|
||||
if form["Token"] != revsuit.config.Token {
|
||||
revsuit.config.Token = form["Token"]
|
||||
revsuit.http.SetToken(form["Token"])
|
||||
log.Info("Update platform config [token] to %s", form["Token"])
|
||||
}
|
||||
|
||||
c.JSON(200, gin.H{
|
||||
"status": "succeed",
|
||||
"error": nil,
|
||||
@@ -216,11 +246,6 @@ func (revsuit *Revsuit) updateFtpConfig(c *gin.Context) {
|
||||
log.Info("Update ftp config [addr] to %s", form.Addr)
|
||||
}
|
||||
|
||||
if form.PasvIP != revsuit.ftp.PasvIP {
|
||||
revsuit.ftp.PasvIP = form.PasvIP
|
||||
log.Info("Update ftp config [pasv_ip] to %s", form.PasvIP)
|
||||
}
|
||||
|
||||
if form.PasvPort != revsuit.ftp.PasvPort {
|
||||
revsuit.ftp.PasvPort = form.PasvPort
|
||||
log.Info("Update ftp config [pasv_port] to %d", form.PasvPort)
|
||||
|
||||
Reference in New Issue
Block a user