fix8: усилить rollback reconfigure, идемпотентность firewall и prod-hardening baseline

This commit is contained in:
2026-04-29 02:25:07 +05:00
parent 5455e41fc1
commit 0545990968
7 changed files with 65 additions and 121 deletions
+14 -113
View File
@@ -43,6 +43,13 @@
</el-form>
</div>
<el-alert
title="Managed by hy2xs-orchestrator reconfigure"
type="info"
:closable="false"
style="margin-bottom: 12px"
/>
<el-card shadow="never">
<el-form
ref="dataFormRef"
@@ -54,6 +61,7 @@
<el-input
v-model="dataForm.huiWebPort"
:placeholder="$t('config.huiWebPort')"
disabled
clearable
/>
</el-form-item>
@@ -61,6 +69,7 @@
<el-input
v-model="dataForm.huiWebContext"
:placeholder="$t('config.huiWebContext')"
disabled
clearable
/>
</el-form-item>
@@ -75,7 +84,7 @@
/>
</el-form-item>
<el-form-item :label="$t('config.huiHttps')" prop="huiHttps">
<el-select v-model="huiHttps" style="width: 50%" ref="huiHttpsRef">
<el-select v-model="huiHttps" style="width: 50%" ref="huiHttpsRef" disabled>
<el-option
v-for="item in huiHttpsList"
:key="item.key"
@@ -83,9 +92,6 @@
:value="item.value"
/>
</el-select>
<el-button v-if="huiHttps" @click="setCertPath"
>{{ t("config.useHysteria2Cert") }}
</el-button>
</el-form-item>
<el-form-item
v-if="huiHttps"
@@ -96,27 +102,9 @@
v-model="dataForm.huiCrtPath"
:placeholder="$t('config.huiCrtPath')"
style="width: 50%"
disabled
clearable
/>
<el-upload
style="height: 32px"
ref="uploadCrtFile"
action=""
:file-list="crtFileList"
:http-request="uploadCertFile"
accept=".crt"
:before-upload="
() => {
crtFileList = [];
}
"
:show-file-list="false"
:limit="1"
>
<template #trigger>
<el-button>{{ t("config.uploadCrtFile") }}</el-button>
</template>
</el-upload>
</el-form-item>
<el-form-item
v-if="huiHttps"
@@ -127,27 +115,9 @@
v-model="dataForm.huiKeyPath"
:placeholder="$t('config.huiKeyPath')"
style="width: 50%"
disabled
clearable
/>
<el-upload
style="height: 32px"
ref="uploadKeyFile"
action=""
:file-list="keyFileList"
:http-request="uploadCertFile"
accept=".key"
:before-upload="
() => {
keyFileList = [];
}
"
:show-file-list="false"
:limit="1"
>
<template #trigger>
<el-button>{{ t("config.uploadKeyFile") }}</el-button>
</template>
</el-upload>
</el-form-item>
<el-tooltip
:content="$t('config.resetTrafficCronTip')"
@@ -189,12 +159,10 @@ export default {
import { Select } from "@element-plus/icons-vue";
import {
exportConfigApi,
hysteria2AcmePathApi,
importConfigApi,
listConfigApi,
restartServerApi,
updateConfigsApi,
uploadCertFileApi,
} from "@/api/config";
import { ConfigsUpdateDto } from "@/api/config/types";
import {
@@ -204,7 +172,6 @@ import {
} from "element-plus/lib/components";
import { useI18n } from "vue-i18n";
import { useRoute } from "vue-router";
import { UploadUserFile } from "element-plus";
const { t } = useI18n();
const route = useRoute();
@@ -278,50 +245,19 @@ const state = reactive({
resetTrafficCron: "",
},
huiHttps: 0,
fileList: [] as UploadUserFile[],
crtFileList: [] as UploadUserFile[],
keyFileList: [] as UploadUserFile[],
fileList: [] as UploadFile[],
});
const { dataForm, huiHttps, fileList, crtFileList, keyFileList } =
toRefs(state);
const { dataForm, huiHttps, fileList } = toRefs(state);
const submitForm = () => {
dataFormRef.value.validate((valid: boolean) => {
if (valid) {
if (state.huiHttps) {
if (!state.dataForm.huiCrtPath || !state.dataForm.huiKeyPath) {
ElMessage.error("crt and key required");
return;
}
}
if (!state.huiHttps) {
state.dataForm.huiCrtPath = "";
state.dataForm.huiKeyPath = "";
}
let configs: ConfigsUpdateDto[] = [
{
key: huiWebPortKey,
value: state.dataForm.huiWebPort,
},
{
key: huiWebContext,
value: state.dataForm.huiWebContext,
},
{
key: hysteria2TrafficTimeKey,
value: state.dataForm.hysteria2TrafficTime,
},
{
key: huiCrtPathKey,
value: state.dataForm.huiCrtPath,
},
{
key: huiKeyPathKey,
value: state.dataForm.huiKeyPath,
},
{
key: resetTrafficCronKey,
value: state.dataForm.resetTrafficCron,
@@ -415,41 +351,6 @@ const handleExport = async () => {
}
};
const setCertPath = async () => {
try {
const { data } = await hysteria2AcmePathApi();
const { crtPath, keyPath } = data;
state.dataForm.huiCrtPath = crtPath;
state.dataForm.huiKeyPath = keyPath;
} catch (e) {
/* empty */
}
};
const uploadCertFile = async (params: UploadRequestOptions) => {
try {
if (
!params.file.name.endsWith(".crt") &&
!params.file.name.endsWith(".key")
) {
ElMessage.error("file format not supported");
}
if (params.file.size > 1024 * 1024) {
ElMessage.error("the file is too big");
}
let formData = new FormData();
formData.append("file", params.file);
const { data } = await uploadCertFileApi(formData);
if (params.file.name.endsWith(".crt")) {
state.dataForm.huiCrtPath = data;
} else if (params.file.name.endsWith(".key")) {
state.dataForm.huiKeyPath = data;
}
} catch (e) {
/* empty */
}
};
const handleRestartServer = async () => {
try {
ElMessageBox.confirm("Are you sure to restart panel?", "Warning", {