mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-01-19 08:19:15 +08:00
parent
b9c5fee411
commit
6b491710c9
@ -48,7 +48,7 @@ func (u *SSHService) GetSSHInfo() (*dto.SSHInfo, error) {
|
||||
Status: constant.StatusEnable,
|
||||
Message: "",
|
||||
Port: "22",
|
||||
ListenAddress: "0.0.0.0",
|
||||
ListenAddress: "",
|
||||
PasswordAuthentication: "yes",
|
||||
PubkeyAuthentication: "yes",
|
||||
PermitRootLogin: "yes",
|
||||
@ -90,7 +90,12 @@ func (u *SSHService) GetSSHInfo() (*dto.SSHInfo, error) {
|
||||
data.Port = strings.ReplaceAll(line, "Port ", "")
|
||||
}
|
||||
if strings.HasPrefix(line, "ListenAddress ") {
|
||||
data.ListenAddress = strings.ReplaceAll(line, "ListenAddress ", "")
|
||||
itemAddr := strings.ReplaceAll(line, "ListenAddress ", "")
|
||||
if len(data.ListenAddress) != 0 {
|
||||
data.ListenAddress += ("," + itemAddr)
|
||||
} else {
|
||||
data.ListenAddress = itemAddr
|
||||
}
|
||||
}
|
||||
if strings.HasPrefix(line, "PasswordAuthentication ") {
|
||||
data.PasswordAuthentication = strings.ReplaceAll(line, "PasswordAuthentication ", "")
|
||||
@ -366,33 +371,34 @@ func sortFileList(fileNames []sshFileItem) []sshFileItem {
|
||||
return fileNames
|
||||
}
|
||||
|
||||
func updateSSHConf(oldFiles []string, param string, value interface{}) []string {
|
||||
hasKey := false
|
||||
func updateSSHConf(oldFiles []string, param string, value string) []string {
|
||||
var valueItems []string
|
||||
if param != "ListenAddress" {
|
||||
valueItems = append(valueItems, value)
|
||||
} else {
|
||||
if value != "" {
|
||||
valueItems = strings.Split(value, ",")
|
||||
}
|
||||
}
|
||||
var newFiles []string
|
||||
for _, line := range oldFiles {
|
||||
if strings.HasPrefix(line, param+" ") {
|
||||
newFiles = append(newFiles, fmt.Sprintf("%s %v", param, value))
|
||||
hasKey = true
|
||||
lineItem := strings.TrimSpace(line)
|
||||
if (strings.HasPrefix(lineItem, param) || strings.HasPrefix(lineItem, fmt.Sprintf("#%s", param))) && len(valueItems) != 0 {
|
||||
newFiles = append(newFiles, fmt.Sprintf("%s %s", param, valueItems[0]))
|
||||
valueItems = valueItems[1:]
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(lineItem, param) && len(valueItems) == 0 {
|
||||
newFiles = append(newFiles, fmt.Sprintf("#%s", line))
|
||||
continue
|
||||
}
|
||||
newFiles = append(newFiles, line)
|
||||
}
|
||||
if !hasKey {
|
||||
newFiles = []string{}
|
||||
for _, line := range oldFiles {
|
||||
if strings.HasPrefix(line, fmt.Sprintf("#%s ", param)) && !hasKey {
|
||||
newFiles = append(newFiles, fmt.Sprintf("%s %v", param, value))
|
||||
hasKey = true
|
||||
continue
|
||||
}
|
||||
newFiles = append(newFiles, line)
|
||||
if len(valueItems) != 0 {
|
||||
for _, item := range valueItems {
|
||||
newFiles = append(newFiles, fmt.Sprintf("%s %s", param, item))
|
||||
}
|
||||
}
|
||||
if !hasKey {
|
||||
newFiles = []string{}
|
||||
newFiles = append(newFiles, oldFiles...)
|
||||
newFiles = append(newFiles, fmt.Sprintf("%s %v", param, value))
|
||||
}
|
||||
return newFiles
|
||||
}
|
||||
|
||||
|
@ -1120,8 +1120,10 @@ const message = {
|
||||
'Modifying the configuration file may cause service availability. Exercise caution when performing this operation. Do you want to continue?',
|
||||
portHelper: 'Specifies the port number monitored by the SSH service. The default port number is 22.',
|
||||
listenAddress: 'Listening address',
|
||||
addressHelper:
|
||||
'Specify the IP address monitored by the SSH service. The default value is 0.0.0.0. That is, all network interfaces are monitored.',
|
||||
allV4V6: '0.0.0.0:{0}(IPv4) and :::{0}(IPv6)',
|
||||
listenHelper:
|
||||
'Canceling IPv4 and IPv6 settings simultaneously will listen on both 0.0.0.0:{0}(IPv4) and :::{0}(IPv6)',
|
||||
addressHelper: 'Specify the IP address on which the SSH service will listen',
|
||||
permitRootLogin: 'root user',
|
||||
rootSettingHelper: 'The default login mode is SSH for user root.',
|
||||
rootHelper1: 'Allow SSH login',
|
||||
|
@ -1066,7 +1066,9 @@ const message = {
|
||||
port: '連接端口',
|
||||
portHelper: '指定 SSH 服務監聽的端口號,默認為 22。',
|
||||
listenAddress: '監聽地址',
|
||||
addressHelper: '指定 SSH 服務監聽的 IP 地址,默認為 0.0.0.0,即所有的網絡接口都會被監聽。',
|
||||
allV4V6: '0.0.0.0:{0}(IPv4)和 :::{0}(IPv6)',
|
||||
listenHelper: '同時取消 IPv4 和 IPv6 設置,將會同時監聽 0.0.0.0:{0}(IPv4) 和 :::{0}(IPv6)',
|
||||
addressHelper: '指定 SSH 服務監聽的 IP 地址',
|
||||
permitRootLogin: 'root 用戶',
|
||||
rootSettingHelper: 'root 用戶 SSH 登錄方式,默認所有 SSH 登錄。',
|
||||
rootHelper1: '允許 SSH 登錄',
|
||||
|
@ -1067,7 +1067,9 @@ const message = {
|
||||
port: '连接端口',
|
||||
portHelper: '指定 SSH 服务监听的端口号,默认为 22。',
|
||||
listenAddress: '监听地址',
|
||||
addressHelper: '指定 SSH 服务监听的 IP 地址,默认为 0.0.0.0,即所有的网络接口都会被监听。',
|
||||
allV4V6: '0.0.0.0:{0}(IPv4) 和 :::{0}(IPv6)',
|
||||
listenHelper: '同时取消 IPv4 和 IPv6 设置,将会同时监听 0.0.0.0:{0}(IPv4) 和 :::{0}(IPv6)',
|
||||
addressHelper: '指定 SSH 服务监听的 IP 地址',
|
||||
permitRootLogin: 'root 用户',
|
||||
rootSettingHelper: 'root 用户 SSH 登录方式,默认所有 SSH 登录。',
|
||||
rootHelper1: '允许 SSH 登录',
|
||||
|
@ -150,7 +150,7 @@ import { ElForm } from 'element-plus';
|
||||
import { createNetwork } from '@/api/modules/container';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { checkIpV6 } from '@/utils/util';
|
||||
import { checkIp, checkIpV6 } from '@/utils/util';
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
@ -214,9 +214,7 @@ function checkGateway(rule: any, value: any, callback: any) {
|
||||
if (value === '') {
|
||||
callback();
|
||||
}
|
||||
const reg =
|
||||
/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
|
||||
if (!reg.test(value) && value !== '') {
|
||||
if (checkIp(value)) {
|
||||
return callback(new Error(i18n.global.t('commons.rule.formatErr')));
|
||||
}
|
||||
callback();
|
||||
@ -225,27 +223,11 @@ function checkGateway(rule: any, value: any, callback: any) {
|
||||
function checkGatewayV6(rule: any, value: any, callback: any) {
|
||||
if (value === '') {
|
||||
callback();
|
||||
} else {
|
||||
const IPv4SegmentFormat = '(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
|
||||
const IPv4AddressFormat = `(${IPv4SegmentFormat}[.]){3}${IPv4SegmentFormat}`;
|
||||
const IPv6SegmentFormat = '(?:[0-9a-fA-F]{1,4})';
|
||||
const IPv6AddressRegExp = new RegExp(
|
||||
'^(' +
|
||||
`(?:${IPv6SegmentFormat}:){7}(?:${IPv6SegmentFormat}|:)|` +
|
||||
`(?:${IPv6SegmentFormat}:){6}(?:${IPv4AddressFormat}|:${IPv6SegmentFormat}|:)|` +
|
||||
`(?:${IPv6SegmentFormat}:){5}(?::${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,2}|:)|` +
|
||||
`(?:${IPv6SegmentFormat}:){4}(?:(:${IPv6SegmentFormat}){0,1}:${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,3}|:)|` +
|
||||
`(?:${IPv6SegmentFormat}:){3}(?:(:${IPv6SegmentFormat}){0,2}:${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,4}|:)|` +
|
||||
`(?:${IPv6SegmentFormat}:){2}(?:(:${IPv6SegmentFormat}){0,3}:${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,5}|:)|` +
|
||||
`(?:${IPv6SegmentFormat}:){1}(?:(:${IPv6SegmentFormat}){0,4}:${IPv4AddressFormat}|(:${IPv6SegmentFormat}){1,6}|:)|` +
|
||||
`(?::((?::${IPv6SegmentFormat}){0,5}:${IPv4AddressFormat}|(?::${IPv6SegmentFormat}){1,7}|:))` +
|
||||
')(%[0-9a-zA-Z-.:]{1,})?$',
|
||||
);
|
||||
if (!IPv6AddressRegExp.test(value) && value !== '') {
|
||||
return callback(new Error(i18n.global.t('commons.rule.formatErr')));
|
||||
}
|
||||
callback();
|
||||
}
|
||||
if (checkIpV6(value)) {
|
||||
return callback(new Error(i18n.global.t('commons.rule.formatErr')));
|
||||
}
|
||||
callback();
|
||||
}
|
||||
|
||||
function checkCidr(rule: any, value: any, callback: any) {
|
||||
|
@ -10,15 +10,40 @@
|
||||
<template #header>
|
||||
<DrawerHeader :header="$t('ssh.listenAddress')" :back="handleClose" />
|
||||
</template>
|
||||
<el-form ref="formRef" label-position="top" :model="form" @submit.prevent v-loading="loading">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
label-position="top"
|
||||
:rules="rules"
|
||||
:model="form"
|
||||
@submit.prevent
|
||||
v-loading="loading"
|
||||
>
|
||||
<el-row type="flex" justify="center">
|
||||
<el-col :span="22">
|
||||
<el-form-item
|
||||
:label="$t('ssh.listenAddress')"
|
||||
prop="listenAddress"
|
||||
:rules="Rules.ipV4V6OrDomain"
|
||||
>
|
||||
<el-input clearable v-model="form.listenAddress" />
|
||||
<el-alert class="common-prompt" :closable="false" type="error">
|
||||
<template #default>
|
||||
<span>
|
||||
{{ $t('ssh.listenHelper', [form.port]) }}
|
||||
</span>
|
||||
</template>
|
||||
</el-alert>
|
||||
<el-form-item label="IPv4" prop="listenAddressV4">
|
||||
<el-checkbox
|
||||
v-model="form.ipv4All"
|
||||
@change="form.listenAddressV4 = form.ipv4All ? '0.0.0.0' : form.listenAddressV4"
|
||||
>
|
||||
{{ $t('setting.bindAll') }}
|
||||
</el-checkbox>
|
||||
<el-input :disabled="form.ipv4All" clearable v-model="form.listenAddressV4"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="IPv6" prop="listenAddressV6">
|
||||
<el-checkbox
|
||||
v-model="form.ipv6All"
|
||||
@change="form.listenAddressV6 = form.ipv6All ? '::' : form.listenAddressV6"
|
||||
>
|
||||
{{ $t('setting.bindAll') }}
|
||||
</el-checkbox>
|
||||
<el-input :disabled="form.ipv6All" clearable v-model="form.listenAddressV6"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -39,26 +64,66 @@ import { reactive, ref } from 'vue';
|
||||
import i18n from '@/lang';
|
||||
import { MsgSuccess } from '@/utils/message';
|
||||
import { ElMessageBox, FormInstance } from 'element-plus';
|
||||
import { Rules } from '@/global/form-rules';
|
||||
import { updateSSH } from '@/api/modules/host';
|
||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||
import { checkIp, checkIpV6 } from '@/utils/util';
|
||||
|
||||
const emit = defineEmits<{ (e: 'search'): void }>();
|
||||
|
||||
interface DialogProps {
|
||||
port: number;
|
||||
address: string;
|
||||
}
|
||||
const drawerVisible = ref();
|
||||
const loading = ref();
|
||||
|
||||
const form = reactive({
|
||||
listenAddress: '0.0.0.0',
|
||||
port: 22,
|
||||
ipv4All: false,
|
||||
ipv6All: false,
|
||||
listenAddressV4: '',
|
||||
listenAddressV6: '',
|
||||
});
|
||||
|
||||
const rules = reactive({
|
||||
listenAddressV4: [{ validator: checkIPv4, trigger: 'blur' }],
|
||||
listenAddressV6: [{ validator: checkIPv6, trigger: 'blur' }],
|
||||
});
|
||||
|
||||
function checkIPv4(rule: any, value: any, callback: any) {
|
||||
if (value === '') {
|
||||
callback();
|
||||
}
|
||||
if (checkIp(value)) {
|
||||
return callback(new Error(i18n.global.t('commons.rule.ip')));
|
||||
}
|
||||
callback();
|
||||
}
|
||||
|
||||
function checkIPv6(rule: any, value: any, callback: any) {
|
||||
if (value === '') {
|
||||
callback();
|
||||
}
|
||||
if (checkIpV6(value)) {
|
||||
return callback(new Error(i18n.global.t('commons.rule.ip')));
|
||||
}
|
||||
callback();
|
||||
}
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
|
||||
const acceptParams = (params: DialogProps): void => {
|
||||
form.listenAddress = params.address;
|
||||
let items = params.address.split(',');
|
||||
for (const item of items) {
|
||||
if (item.indexOf(':') !== -1) {
|
||||
form.listenAddressV6 = item;
|
||||
form.ipv6All = item === '::';
|
||||
continue;
|
||||
}
|
||||
form.listenAddressV4 = item;
|
||||
form.ipv4All = item === '0.0.0.0';
|
||||
}
|
||||
form.port = params.port;
|
||||
drawerVisible.value = true;
|
||||
};
|
||||
|
||||
@ -66,8 +131,19 @@ const onSave = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
formEl.validate(async (valid) => {
|
||||
if (!valid) return;
|
||||
let itemAddr = [];
|
||||
if (form.listenAddressV4 !== '') {
|
||||
itemAddr.push(form.listenAddressV4);
|
||||
}
|
||||
if (form.listenAddressV6 !== '') {
|
||||
itemAddr.push(form.listenAddressV6);
|
||||
}
|
||||
let addr =
|
||||
itemAddr.join(',') === '' || itemAddr.join(',') === '0.0.0.0,::'
|
||||
? i18n.global.t('ssh.allV4V6', [form.port])
|
||||
: itemAddr.join(',');
|
||||
ElMessageBox.confirm(
|
||||
i18n.global.t('ssh.sshChangeHelper', [i18n.global.t('ssh.listenAddress'), form.listenAddress]),
|
||||
i18n.global.t('ssh.sshChangeHelper', [i18n.global.t('ssh.listenAddress'), addr]),
|
||||
i18n.global.t('ssh.sshChange'),
|
||||
{
|
||||
confirmButtonText: i18n.global.t('commons.button.confirm'),
|
||||
@ -79,7 +155,7 @@ const onSave = async (formEl: FormInstance | undefined) => {
|
||||
let params = {
|
||||
key: 'ListenAddress',
|
||||
oldValue: '',
|
||||
newValue: form.listenAddress,
|
||||
newValue: itemAddr.join(','),
|
||||
};
|
||||
loading.value = true;
|
||||
await updateSSH(params)
|
||||
|
@ -71,7 +71,7 @@
|
||||
<span class="input-help">{{ $t('ssh.portHelper') }}</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('ssh.listenAddress')" prop="listenAddress">
|
||||
<el-input disabled v-model="form.listenAddress">
|
||||
<el-input disabled v-model="form.listenAddressItem">
|
||||
<template #append>
|
||||
<el-button @click="onChangeAddress" icon="Setting">
|
||||
{{ $t('commons.button.set') }}
|
||||
@ -184,6 +184,7 @@ const form = reactive({
|
||||
message: '',
|
||||
port: 22,
|
||||
listenAddress: '',
|
||||
listenAddressItem: '',
|
||||
passwordAuthentication: 'yes',
|
||||
pubkeyAuthentication: 'yes',
|
||||
encryptionMode: '',
|
||||
@ -222,7 +223,7 @@ const onChangeRoot = () => {
|
||||
rootsRef.value.acceptParams({ permitRootLogin: form.permitRootLogin });
|
||||
};
|
||||
const onChangeAddress = () => {
|
||||
addressRef.value.acceptParams({ address: form.listenAddress });
|
||||
addressRef.value.acceptParams({ address: form.listenAddress, port: form.port });
|
||||
};
|
||||
|
||||
const onOperate = async (operation: string) => {
|
||||
@ -325,6 +326,10 @@ const search = async () => {
|
||||
form.port = Number(res.data.port);
|
||||
autoStart.value = res.data.autoStart ? 'enable' : 'disable';
|
||||
form.listenAddress = res.data.listenAddress;
|
||||
form.listenAddressItem =
|
||||
form.listenAddress === '' || form.listenAddress === '0.0.0.0,::'
|
||||
? i18n.global.t('ssh.allV4V6', [form.port])
|
||||
: form.listenAddress;
|
||||
form.passwordAuthentication = res.data.passwordAuthentication;
|
||||
form.pubkeyAuthentication = res.data.pubkeyAuthentication;
|
||||
form.permitRootLogin = res.data.permitRootLogin;
|
||||
|
Loading…
x
Reference in New Issue
Block a user