add tls
This commit is contained in:
@@ -0,0 +1,252 @@
|
||||
<template>
|
||||
<v-card subtitle="ACME" style="background-color: inherit;">
|
||||
<v-row>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-switch color="primary" :label="$t('enable')" v-model="enabled" hide-details></v-switch>
|
||||
</v-col>
|
||||
<v-col cols="12" md="8" v-if="enabled">
|
||||
<v-text-field
|
||||
:label="$t('rule.domain') + ' ' + $t('commaSeparated')"
|
||||
hide-details
|
||||
v-model="domains">
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<template v-if="enabled">
|
||||
<v-row>
|
||||
<v-col cols="12" sm="6" md="4" v-if="optionDir">
|
||||
<v-text-field
|
||||
:label="$t('tls.acme.dataDir')"
|
||||
hide-details
|
||||
v-model="acme.data_directory">
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4" v-if="optionDefault">
|
||||
<v-combobox
|
||||
v-model="acme.default_server_name"
|
||||
:items="acme.domain"
|
||||
:label="$t('tls.acme.defaultDomain')"
|
||||
hide-details
|
||||
></v-combobox>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4" v-if="optionEmail">
|
||||
<v-text-field
|
||||
:label="$t('email')"
|
||||
hide-details
|
||||
v-model="acme.email">
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-if="optionChallenge">
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-switch color="primary" :label="$t('tls.acme.httpChallenge')" v-model="acme.disable_http_challenge" hide-details></v-switch>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-switch color="primary" :label="$t('tls.acme.tlsChallenge')" v-model="acme.disable_tls_alpn_challenge" hide-details></v-switch>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-if="optionPorts">
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-text-field
|
||||
:label="$t('tls.acme.altHport')"
|
||||
hide-details
|
||||
type="number"
|
||||
min=1
|
||||
max="65532"
|
||||
v-model.number="acme.alternative_http_port">
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-text-field
|
||||
:label="$t('tls.acme.altTport')"
|
||||
hide-details
|
||||
type="number"
|
||||
min=1
|
||||
max="65532"
|
||||
v-model.number="acme.alternative_tls_port">
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-if="optionProvider">
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-select
|
||||
v-model="caProvider"
|
||||
:items="providerList"
|
||||
:label="$t('tls.acme.caProvider')"
|
||||
hide-details
|
||||
></v-select>
|
||||
</v-col>
|
||||
<v-col cols="12" md="8" v-if="caProvider == ''">
|
||||
<v-text-field
|
||||
:label="$t('tls.acme.customCa')"
|
||||
hide-details
|
||||
v-model="acme.provider">
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-if="acme.external_account != undefined">
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-text-field
|
||||
label="Key ID"
|
||||
hide-details
|
||||
v-model="acme.external_account.key_id">
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-text-field
|
||||
label="MAC Key"
|
||||
hide-details
|
||||
v-model="acme.external_account.mac_key">
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-if="acme.dns01_challenge != undefined">
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-select
|
||||
:label="$t('tls.acme.dns01Provider')"
|
||||
hide-details
|
||||
:items="dnsProviders.map(d => d.provider)"
|
||||
@update:model-value="acme.dns01_challenge = { provider: $event }"
|
||||
v-model="acme.dns01_challenge.provider">
|
||||
</v-select>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4"
|
||||
v-for="item in dnsProviders.filter(d => d.provider == acme.dns01_challenge?.provider)[0]?.params"
|
||||
:key="item">
|
||||
<v-text-field
|
||||
:label="item"
|
||||
hide-details
|
||||
v-model="acme.dns01_challenge[item]">
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-menu v-model="menu" :close-on-content-click="false" location="start">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn v-bind="props" hide-details>{{ $t('tls.acme.options') }}</v-btn>
|
||||
</template>
|
||||
<v-card>
|
||||
<v-list>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionDir" color="primary" :label="$t('tls.acme.dataDir')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionDefault" color="primary" :label="$t('tls.acme.defaultDomain')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionEmail" color="primary" :label="$t('email')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionChallenge" color="primary" :label="$t('tls.acme.disableChallenges')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionPorts" color="primary" :label="$t('tls.acme.altPorts')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionProvider" color="primary" :label="$t('tls.acme.caProvider')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionExt" color="primary" :label="$t('tls.acme.extAcc')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionDns01" color="primary" :label="$t('tls.acme.dns01')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
</v-card-actions>
|
||||
</template>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { acme } from '@/types/inTls'
|
||||
|
||||
export default {
|
||||
props: ['tls'],
|
||||
data() {
|
||||
return {
|
||||
menu: false,
|
||||
providerList: [
|
||||
{ title: "Let's Encrypt", value: "letsencrypt" },
|
||||
{ title: "ZeroSSL", value: "zerossl" },
|
||||
{ title: "Custom", value: "" }
|
||||
],
|
||||
dnsProviders: [
|
||||
{ provider: "cloudflare", params: [ "api_token" ] },
|
||||
{ provider: "alidns", params: [ "access_key_id","access_key_secret","region_id" ] }
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
acme() {
|
||||
return <acme>this.$props.tls.acme
|
||||
},
|
||||
enabled: {
|
||||
get() { return this.acme != undefined },
|
||||
set(v: boolean) { this.$props.tls.acme = v ? { domain: [] } : undefined }
|
||||
},
|
||||
domains: {
|
||||
get() { return this.acme?.domain ? this.acme.domain.join(',') : "" },
|
||||
set(v: string) {
|
||||
if(!v.endsWith(',')) {
|
||||
this.acme.domain = v.length > 0 ? v.split(',') : []
|
||||
}
|
||||
}
|
||||
},
|
||||
caProvider: {
|
||||
get() { return this.acme?.provider && ['letsencrypt','zerossl'].includes(this.acme.provider) ? this.acme?.provider : '' },
|
||||
set(v: string) { this.acme.provider = ['letsencrypt','zerossl'].includes(v) ? v : 'https://' }
|
||||
},
|
||||
optionDir: {
|
||||
get(): boolean { return this.acme?.data_directory != undefined },
|
||||
set(v:boolean) { this.acme.data_directory = v ? '' : undefined }
|
||||
},
|
||||
optionDefault: {
|
||||
get(): boolean { return this.acme?.default_server_name != undefined },
|
||||
set(v:boolean) { this.acme.default_server_name = v ? this.domains.length>0 ? this.domains[0] : '' : undefined }
|
||||
},
|
||||
optionEmail: {
|
||||
get(): boolean { return this.acme?.email != undefined },
|
||||
set(v:boolean) { this.acme.email = v ? '' : undefined }
|
||||
},
|
||||
optionChallenge: {
|
||||
get(): boolean { return this.acme?.disable_http_challenge != undefined || this.acme?.disable_tls_alpn_challenge != undefined },
|
||||
set(v:boolean) {
|
||||
if (v) {
|
||||
this.acme.disable_http_challenge = false
|
||||
this.acme.disable_tls_alpn_challenge = false
|
||||
} else {
|
||||
delete this.acme.disable_http_challenge
|
||||
delete this.acme.disable_tls_alpn_challenge
|
||||
}
|
||||
}
|
||||
},
|
||||
optionPorts: {
|
||||
get(): boolean { return this.acme?.alternative_http_port != undefined || this.acme?.alternative_tls_port != undefined },
|
||||
set(v:boolean) {
|
||||
if (v) {
|
||||
this.acme.alternative_http_port = 80
|
||||
this.acme.alternative_tls_port = 443
|
||||
} else {
|
||||
delete this.acme.alternative_http_port
|
||||
delete this.acme.alternative_tls_port
|
||||
}
|
||||
}
|
||||
},
|
||||
optionProvider: {
|
||||
get(): boolean { return this.acme?.provider != undefined },
|
||||
set(v:boolean) { this.acme.provider = v ? 'letsencrypt' : undefined }
|
||||
},
|
||||
optionExt: {
|
||||
get(): boolean { return this.acme?.external_account != undefined },
|
||||
set(v:boolean) { this.acme.external_account = v ? { key_id: '', mac_key: '' } : undefined }
|
||||
},
|
||||
optionDns01: {
|
||||
get(): boolean { return this.acme?.dns01_challenge != undefined },
|
||||
set(v:boolean) { this.acme.dns01_challenge = v ? { provider: 'cloudflare' } : undefined }
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<v-card subtitle="ECH" style="background-color: inherit;">
|
||||
<v-row>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-switch color="primary" :label="$t('enable')" v-model="enabled" hide-details></v-switch>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<template v-if="enabled">
|
||||
<v-row>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-switch color="primary" label="Post-Quantum Schemes" v-model="ech.pq_signature_schemes_enabled" hide-details></v-switch>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-switch color="primary" label="Disable Adaptive Size" v-model="ech.dynamic_record_sizing_disabled" hide-details></v-switch>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col cols="auto">
|
||||
<v-btn-toggle v-model="useEchPath"
|
||||
class="rounded-xl"
|
||||
density="compact"
|
||||
variant="outlined"
|
||||
shaped
|
||||
mandatory>
|
||||
<v-btn
|
||||
@click="delete ech.key"
|
||||
>{{ $t('tls.usePath') }}</v-btn>
|
||||
<v-btn
|
||||
@click="delete ech.key_path"
|
||||
>{{ $t('tls.useText') }}</v-btn>
|
||||
</v-btn-toggle>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-if="useEchPath == 0">
|
||||
<v-col cols="12" sm="6">
|
||||
<v-text-field
|
||||
:label="$t('tls.keyPath')"
|
||||
hide-details
|
||||
v-model="ech.key_path">
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-else>
|
||||
<v-col cols="12" sm="6">
|
||||
<v-textarea
|
||||
:label="$t('tls.key')"
|
||||
hide-details
|
||||
v-model="echKeyText">
|
||||
</v-textarea>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col cols="12" sm="6">
|
||||
<v-textarea
|
||||
:label="$t('tls.cert')"
|
||||
hide-details
|
||||
v-model="echConfigText">
|
||||
</v-textarea>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
</v-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { ech } from '@/types/inTls'
|
||||
|
||||
export default {
|
||||
props: ['iTls','oTls'],
|
||||
data() {
|
||||
return {
|
||||
useEchPath: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
ech() {
|
||||
return <ech>this.$props.iTls.ech
|
||||
},
|
||||
enabled: {
|
||||
get() { return this.ech?.enabled?? false },
|
||||
set(v: boolean) {
|
||||
this.$props.iTls.ech = v ? { enabled: true } : undefined
|
||||
this.$props.oTls.ech = v ? {} : undefined
|
||||
}
|
||||
},
|
||||
echKeyText: {
|
||||
get(): string { return this.ech?.key ? this.ech.key.join('\n') : '' },
|
||||
set(newValue:string) { this.ech.key = newValue.split('\n') }
|
||||
},
|
||||
echConfigText: {
|
||||
get(): string { return this.oTls.ech?.config ? this.oTls.ech.config.join('\n') : '' },
|
||||
set(newValue:string) { this.oTls.ech.config = newValue.split('\n') }
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,11 +1,20 @@
|
||||
<template>
|
||||
<v-card :subtitle="$t('objects.tls')">
|
||||
<v-row v-if="tlsOptional">
|
||||
<v-col cols="auto">
|
||||
<v-row>
|
||||
<v-col cols="12" sm="6" md="4" v-if="tlsOptional">
|
||||
<v-switch color="primary" :label="$t('tls.enable')" v-model="tlsEnable" hide-details></v-switch>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4" v-if="tls.enabled">
|
||||
<v-select
|
||||
hide-details
|
||||
label="Preset"
|
||||
:items="tlsItems"
|
||||
@update:model-value="changeTlsItem($event)"
|
||||
v-model="tlsId">
|
||||
</v-select>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<template v-if="tls.enabled">
|
||||
<template v-if="tls.enabled && tlsId == 0">
|
||||
<v-row>
|
||||
<v-col cols="auto">
|
||||
<v-btn-toggle v-model="usePath"
|
||||
@@ -103,32 +112,32 @@
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
<v-card-actions v-if="tls.enabled">
|
||||
<v-card-actions v-if="tls.enabled && tlsId == 0">
|
||||
<v-spacer></v-spacer>
|
||||
<v-menu v-model="menu" :close-on-content-click="false" location="start" v-if="tls.enabled">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn v-bind="props" hide-details>{{ $t('tls.options') }}</v-btn>
|
||||
</template>
|
||||
<v-card>
|
||||
<v-list>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionSNI" color="primary" label="SNI" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionALPN" color="primary" label="ALPN" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionMinV" color="primary" :label="$t('tls.minVer')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionMaxV" color="primary" :label="$t('tls.maxVer')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionCS" color="primary" :label="$t('tls.cs')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn v-bind="props" hide-details>{{ $t('tls.options') }}</v-btn>
|
||||
</template>
|
||||
<v-card>
|
||||
<v-list>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionSNI" color="primary" label="SNI" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionALPN" color="primary" label="ALPN" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionMinV" color="primary" :label="$t('tls.minVer')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionMaxV" color="primary" :label="$t('tls.maxVer')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionCS" color="primary" :label="$t('tls.cs')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</template>
|
||||
@@ -136,11 +145,11 @@
|
||||
<script lang="ts">
|
||||
import { iTls, defaultInTls } from '@/types/inTls'
|
||||
export default {
|
||||
props: ['inbound'],
|
||||
props: ['inbound', 'tlsConfigs', 'tls_id'],
|
||||
data() {
|
||||
return {
|
||||
menu: false,
|
||||
usePath: 0,
|
||||
usePath: this.$props.inbound.tls.key == undefined ? 0 : 1,
|
||||
defaults: defaultInTls,
|
||||
alpn: [
|
||||
{ title: "H3", value: 'h3' },
|
||||
@@ -173,8 +182,15 @@ export default {
|
||||
tls(): iTls {
|
||||
return <iTls> this.$props.inbound.tls
|
||||
},
|
||||
tlsItems(): any[] {
|
||||
return [ { title: '', value: 0 }, ...this.$props.tlsConfigs?.map((t:any) => { return { title: t.name, value: t.id } } )]
|
||||
},
|
||||
tlsId: {
|
||||
get() { return this.tls_id.value?? 0 },
|
||||
set(newValue: boolean) { this.$props.tls_id.value = newValue }
|
||||
},
|
||||
tlsEnable: {
|
||||
get() { return Object.hasOwn(this.$props.inbound.tls, 'enabled') ? this.tls.enabled : false },
|
||||
get() { return this.tls.enabled?? false },
|
||||
set(newValue: boolean) { this.$props.inbound.tls = newValue ? { enabled: true } : {} }
|
||||
},
|
||||
tlsOptional(): boolean {
|
||||
@@ -190,23 +206,33 @@ export default {
|
||||
},
|
||||
optionSNI: {
|
||||
get(): boolean { return this.tls.server_name != undefined },
|
||||
set(v:boolean) { this.$props.inbound.tls.server_name = v ? '' : undefined }
|
||||
set(v:boolean) { this.tls.server_name = v ? '' : undefined }
|
||||
},
|
||||
optionALPN: {
|
||||
get(): boolean { return this.tls.alpn != undefined },
|
||||
set(v:boolean) { this.$props.inbound.tls.alpn = v ? defaultInTls.alpn : undefined }
|
||||
set(v:boolean) { this.tls.alpn = v ? defaultInTls.alpn : undefined }
|
||||
},
|
||||
optionMinV: {
|
||||
get(): boolean { return this.tls.min_version != undefined },
|
||||
set(v:boolean) { this.$props.inbound.tls.min_version = v ? defaultInTls.min_version : undefined }
|
||||
set(v:boolean) { this.tls.min_version = v ? defaultInTls.min_version : undefined }
|
||||
},
|
||||
optionMaxV: {
|
||||
get(): boolean { return this.tls.max_version != undefined },
|
||||
set(v:boolean) { this.$props.inbound.tls.max_version = v ? defaultInTls.max_version : undefined }
|
||||
set(v:boolean) { this.tls.max_version = v ? defaultInTls.max_version : undefined }
|
||||
},
|
||||
optionCS: {
|
||||
get(): boolean { return this.tls.cipher_suites != undefined },
|
||||
set(v:boolean) { this.$props.inbound.tls.cipher_suites = v ? defaultInTls.cipher_suites : undefined }
|
||||
set(v:boolean) { this.tls.cipher_suites = v ? defaultInTls.cipher_suites : undefined }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeTlsItem(id: number){
|
||||
if (id>0) {
|
||||
const tlsConfig = this.$props.tlsConfigs?.findLast((t:any) => t.id == id)
|
||||
if (tlsConfig) this.$props.inbound.tls = tlsConfig.server
|
||||
} else {
|
||||
this.$props.inbound.tls = { enabled: this.tls.enabled }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<v-row v-if="Inbound.handshake_for_server_name != undefined">
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-text-field
|
||||
:label="$t('types.shdwTls.adHS')"
|
||||
:label="$t('types.shdwTls.addHS')"
|
||||
hide-details
|
||||
append-icon="mdi-plus"
|
||||
@click:append="addHandshakeServer()"
|
||||
|
||||
Reference in New Issue
Block a user