adjustments for singbox 1.11.0
This commit is contained in:
@@ -113,6 +113,11 @@ func moveJsonToDb(db *gorm.DB) error {
|
||||
inbObj["out_json"] = json.RawMessage("{}")
|
||||
inbObj["addrs"] = json.RawMessage("[]")
|
||||
}
|
||||
// Delete deprecated fields
|
||||
delete(inbObj, "sniff")
|
||||
delete(inbObj, "sniff_override_destination")
|
||||
delete(inbObj, "sniff_timeout")
|
||||
delete(inbObj, "domain_strategy")
|
||||
inbJson, _ := json.Marshal(inbObj)
|
||||
|
||||
var newInbound model.Inbound
|
||||
@@ -127,6 +132,9 @@ func moveJsonToDb(db *gorm.DB) error {
|
||||
}
|
||||
delete(oldConfig, "inbounds")
|
||||
|
||||
blockOutboundTags := []string{}
|
||||
dnsOutboundTags := []string{}
|
||||
|
||||
oldOutbounds := oldConfig["outbounds"].([]interface{})
|
||||
db.Migrator().DropTable(&model.Outbound{}, &model.Endpoint{})
|
||||
db.AutoMigrate(&model.Outbound{}, &model.Endpoint{})
|
||||
@@ -149,14 +157,69 @@ func moveJsonToDb(db *gorm.DB) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = db.Create(&newOutbound).Error
|
||||
if err != nil {
|
||||
return err
|
||||
// Delete deprecated fields
|
||||
if newOutbound.Type == "direct" {
|
||||
var options map[string]interface{}
|
||||
json.Unmarshal(newOutbound.Options, &options)
|
||||
delete(options, "override_address")
|
||||
delete(options, "override_port")
|
||||
newOutbound.Options, _ = json.Marshal(options)
|
||||
}
|
||||
|
||||
switch newOutbound.Type {
|
||||
case "dns":
|
||||
dnsOutboundTags = append(dnsOutboundTags, newOutbound.Tag)
|
||||
case "block":
|
||||
blockOutboundTags = append(blockOutboundTags, newOutbound.Tag)
|
||||
default:
|
||||
err = db.Create(&newOutbound).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete(oldConfig, "outbounds")
|
||||
|
||||
// Check routing rules
|
||||
if routingRules, ok := oldConfig["route"].(map[string]interface{}); ok {
|
||||
if rules, hasRules := routingRules["rules"].([]interface{}); hasRules {
|
||||
hasDns := false
|
||||
for index, rule := range rules {
|
||||
ruleObj, _ := rule.(map[string]interface{})
|
||||
isBlock := false
|
||||
isDns := false
|
||||
outboundTag, _ := ruleObj["outbound"].(string)
|
||||
for _, tag := range blockOutboundTags {
|
||||
if tag == outboundTag {
|
||||
isBlock = true
|
||||
delete(ruleObj, "outbound")
|
||||
ruleObj["action"] = "reject"
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, tag := range dnsOutboundTags {
|
||||
if tag == outboundTag {
|
||||
isDns = true
|
||||
hasDns = true
|
||||
delete(ruleObj, "outbound")
|
||||
ruleObj["action"] = "hijack-dns"
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isBlock && !isDns {
|
||||
ruleObj["action"] = "route"
|
||||
}
|
||||
rules[index] = ruleObj
|
||||
}
|
||||
if hasDns {
|
||||
rules = append(rules, map[string]interface{}{"action": "sniff"})
|
||||
}
|
||||
routingRules["rules"] = rules
|
||||
}
|
||||
oldConfig["route"] = routingRules
|
||||
}
|
||||
|
||||
// Remove v2rayapi and clashapi from experimental config
|
||||
experimental := oldConfig["experimental"].(map[string]interface{})
|
||||
delete(experimental, "v2ray_api")
|
||||
|
||||
@@ -29,24 +29,6 @@
|
||||
v-model="inbound.detour">
|
||||
</v-select>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-switch v-model="inbound.sniff" color="primary" :label="$t('listen.sniffing')" hide-details></v-switch>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-if="inbound.sniff">
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-switch v-model="inbound.sniff_override_destination" color="primary" :label="$t('listen.sniffingOverride')" hide-details></v-switch>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-text-field
|
||||
:label="$t('listen.sniffingTimeout')"
|
||||
hide-details
|
||||
type="number"
|
||||
min="50"
|
||||
step="50"
|
||||
:suffix="$t('date.ms')"
|
||||
v-model.number="sniffTimeout"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-if="optionTCP">
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
@@ -70,16 +52,6 @@
|
||||
v-model.number="udpTimeout"></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-if="optionDS">
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-select
|
||||
hide-details
|
||||
:label="$t('listen.domainStrategy')"
|
||||
:items="['prefer_ipv4','prefer_ipv6','ipv4_only','ipv6_only']"
|
||||
v-model="inbound.domain_strategy">
|
||||
</v-select>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-card-actions class="pt-0" v-if="inbound.type != 'tun'">
|
||||
<v-spacer></v-spacer>
|
||||
<v-menu v-model="menu" :close-on-content-click="false" location="start">
|
||||
@@ -97,9 +69,6 @@
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionUDP" color="primary" :label="$t('listen.udpOptions')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-switch v-model="optionDS" color="primary" :label="$t('listen.domainStrategy')" hide-details></v-switch>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-card>
|
||||
</v-menu>
|
||||
@@ -120,10 +89,6 @@ export default {
|
||||
get() { return this.$props.inbound.udp_timeout ? parseInt(this.$props.inbound.udp_timeout.replace('m','')) : 5 },
|
||||
set(newValue:number) { this.$props.inbound.udp_timeout = newValue > 0 ? newValue + 'm' : '5m' }
|
||||
},
|
||||
sniffTimeout: {
|
||||
get() { return this.$props.inbound.sniff_timeout ? parseInt(this.$props.inbound.sniff_timeout.replace('ms','')) : 300 },
|
||||
set(newValue:number) { this.$props.inbound.sniff_timeout = newValue > 0 ? newValue + 'ms' : '300ms' }
|
||||
},
|
||||
optionTCP: {
|
||||
get(): boolean {
|
||||
return this.$props.inbound.tcp_fast_open != undefined &&
|
||||
@@ -147,10 +112,6 @@ export default {
|
||||
optionDetour: {
|
||||
get(): boolean { return this.$props.inbound.detour != undefined },
|
||||
set(v:boolean) { this.$props.inbound.detour = v ? this.inTags[0]?? '' : undefined }
|
||||
},
|
||||
optionDS: {
|
||||
get(): boolean { return this.$props.inbound.domain_strategy != undefined },
|
||||
set(v:boolean) { this.$props.inbound.domain_strategy = v ? 'prefer_ipv4' : undefined }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<v-card subtitle="Direct">
|
||||
<v-row>
|
||||
<v-col cols="12" sm="6" md="4" v-if="direction == 'in'">
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<Network :data="data" />
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
@@ -28,7 +28,7 @@
|
||||
import Network from '@/components/Network.vue'
|
||||
|
||||
export default {
|
||||
props: ['direction','data'],
|
||||
props: ['data'],
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
|
||||
@@ -252,11 +252,6 @@ export default {
|
||||
],
|
||||
fingerprints: [
|
||||
{ title: "Chrome", value: "chrome" },
|
||||
{ title: "Chrome PSK", value: "chrome_psk" },
|
||||
{ title: "Chrome PSK Shuffle", value: "chrome_psk_shuffle" },
|
||||
{ title: "Chrome Padding PSK Shuffle", value: "chrome_padding_psk_shuffle" },
|
||||
{ title: "Chrome Post-Quantum", value: "chrome_pq" },
|
||||
{ title: "Chrome Post-Quantum PSK", value: "chrome_pq_psk" },
|
||||
{ title: "Firefox", value: "firefox" },
|
||||
{ title: "Microsoft Edge", value: "edge" },
|
||||
{ title: "Apple Safari", value: "safari" },
|
||||
|
||||
@@ -70,15 +70,14 @@
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col>
|
||||
<v-combobox
|
||||
<v-select
|
||||
v-model="clientInbounds"
|
||||
:items="inboundTags"
|
||||
:label="$t('client.inboundTags')"
|
||||
:return-object="false"
|
||||
multiple
|
||||
chips
|
||||
hide-details
|
||||
></v-combobox>
|
||||
></v-select>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-window-item>
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
<v-window v-model="side" style="margin-top: 10px;">
|
||||
<v-window-item value="s">
|
||||
<Listen :inbound="inbound" :inTags="inTags" />
|
||||
<Direct v-if="inbound.type == inTypes.Direct" direction="in" :data="inbound" />
|
||||
<Direct v-if="inbound.type == inTypes.Direct" :data="inbound" />
|
||||
<Shadowsocks v-if="inbound.type == inTypes.Shadowsocks" direction="in" :data="inbound" />
|
||||
<Hysteria v-if="inbound.type == inTypes.Hysteria" direction="in" :data="inbound" />
|
||||
<Hysteria2 v-if="inbound.type == inTypes.Hysteria2" direction="in" :data="inbound" />
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<Direct v-if="outbound.type == outTypes.Direct" direction="out" :data="outbound" />
|
||||
<Socks v-if="outbound.type == outTypes.SOCKS" :data="outbound" />
|
||||
<Http v-if="outbound.type == outTypes.HTTP" :data="outbound" />
|
||||
<Shadowsocks v-if="outbound.type == outTypes.Shadowsocks" direction="out" :data="outbound" />
|
||||
@@ -139,8 +138,8 @@ export default {
|
||||
link: "",
|
||||
loading: false,
|
||||
outTypes: OutTypes,
|
||||
NoDial: [OutTypes.Block, OutTypes.DNS, OutTypes.Selector, OutTypes.URLTest],
|
||||
NoServer: [OutTypes.Direct, OutTypes.Block, OutTypes.DNS, OutTypes.Selector, OutTypes.URLTest, OutTypes.Tor],
|
||||
NoDial: [OutTypes.Selector, OutTypes.URLTest],
|
||||
NoServer: [OutTypes.Direct, OutTypes.Selector, OutTypes.URLTest, OutTypes.Tor],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</v-col>
|
||||
<v-spacer></v-spacer>
|
||||
<v-col cols="auto" v-if="logical" justify="center" align="center">
|
||||
<v-btn color="primary" @click="ruleData.rules.push({})" hide-details>{{ $t('actions.add') + " " + $t('objects.rule') }}</v-btn>
|
||||
<v-btn color="primary" @click="ruleData.rules.push(<rule>{})" hide-details>{{ $t('actions.add') + " " + $t('objects.rule') }}</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-card style="background-color: inherit; margin-bottom: 5px;" v-for="(r, index) in ruleData.rules" v-if="ruleData.type == 'logical'">
|
||||
@@ -35,12 +35,12 @@
|
||||
:rsTags="rsTags" />
|
||||
<v-row>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-combobox
|
||||
v-model="ruleData.outbound"
|
||||
:items="outTags"
|
||||
:label="$t('objects.outbound')"
|
||||
<v-select
|
||||
v-model="ruleData.action"
|
||||
:items="actions"
|
||||
:label="$t('admin.action')"
|
||||
hide-details
|
||||
></v-combobox>
|
||||
></v-select>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4" v-if="logical">
|
||||
<v-combobox
|
||||
@@ -54,6 +54,95 @@
|
||||
<v-switch color="primary" v-model="ruleData.invert" :label="$t('rule.invert')" hide-details></v-switch>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-card subtitle="Route" v-if="ruleData.action == 'route'">
|
||||
<v-row>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-select
|
||||
v-model="ruleData.outbound"
|
||||
:items="outTags"
|
||||
:label="$t('objects.outbound')"
|
||||
hide-details
|
||||
></v-select>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card>
|
||||
<v-card subtitle="Route Option" v-if="ruleData.action == 'route-options'">
|
||||
<v-row>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-text-field v-model="ruleData.override_address" :label="$t('types.direct.overrideAddr')" hide-details></v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-text-field
|
||||
v-model.number="ruleData.override_port"
|
||||
type="number"
|
||||
min="0"
|
||||
max="65534"
|
||||
:label="$t('types.direct.overridePort')"
|
||||
hide-details>
|
||||
</v-text-field>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-switch v-model="ruleData.udp_disable_domain_unmapping" :label="$t('rule.udpDisableDomainUnmapping')" hide-details></v-switch>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-switch v-model="ruleData.udp_connect" :label="$t('rule.udpConnect')" hide-details></v-switch>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-text-field v-model="ruleData.udp_timeout" :label="$t('rule.udpTimeout')" hide-details></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card>
|
||||
<v-card subtitle="Reject" v-if="ruleData.action == 'reject'">
|
||||
<v-row>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-select
|
||||
v-model="ruleData.method"
|
||||
:items="[{ title: 'Default', value: 'default' },{ title: 'Drop', value: 'drop'}]"
|
||||
:label="$t('rule.method')"
|
||||
clearable
|
||||
@click:clear="delete ruleData.method"
|
||||
hide-details>
|
||||
</v-select>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-switch v-model="ruleData.no_drop" :label="$t('rule.noDrop')" hide-details></v-switch>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card>
|
||||
<v-card subtitle="Sniff" v-if="ruleData.action == 'sniff'">
|
||||
<v-row>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-select
|
||||
v-model="ruleData.sniff"
|
||||
:items="sniffers"
|
||||
:label="$t('rule.sniffer')"
|
||||
multiple
|
||||
chips
|
||||
hide-details>
|
||||
</v-select>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-text-field v-model="ruleData.timeout" :label="$t('rule.timeout')" hide-details></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card>
|
||||
<v-card subtitle="Resolve" v-if="ruleData.action == 'resolve'">
|
||||
<v-row>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-select
|
||||
v-model="ruleData.strategy"
|
||||
:items="strategies"
|
||||
:label="$t('rule.strategy')"
|
||||
clearable
|
||||
@click:clear="delete ruleData.strategy"
|
||||
hide-details>
|
||||
</v-select>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" md="4">
|
||||
<v-text-field v-model="ruleData.server" :label="$t('basic.dns.server')" hide-details></v-text-field>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
@@ -78,8 +167,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { logicalRule, rule } from '@/types/rules'
|
||||
import { logicalRule, rule, actionKeys } from '@/types/rules'
|
||||
import RuleOptions from '@/components/Rule.vue'
|
||||
import { title } from 'process';
|
||||
export default {
|
||||
props: ['visible', 'data', 'index', 'clients', 'inTags', 'outTags', 'rsTags'],
|
||||
emits: ['close', 'save'],
|
||||
@@ -87,13 +177,39 @@ export default {
|
||||
return {
|
||||
title: 'add',
|
||||
loading: false,
|
||||
ruleData: <logicalRule>{
|
||||
ruleData: <any>{
|
||||
type: 'logical',
|
||||
mode: 'and',
|
||||
rules: <rule[]>[{}],
|
||||
invert: false,
|
||||
action: 'route',
|
||||
outbound: 'direct',
|
||||
}
|
||||
},
|
||||
actions: [
|
||||
{ title: 'Route', value: 'route'},
|
||||
{ title: 'Route Options', value: 'route-options'},
|
||||
{ title: 'Reject', value: 'reject'},
|
||||
{ title: 'Hijack DNS', value: 'hijack-dns'},
|
||||
{ title: 'Sniff', value: 'sniff'},
|
||||
{ title: 'Resolve', value: 'resolve'}
|
||||
],
|
||||
sniffers: [
|
||||
{ title: 'HTTP', value: 'http' },
|
||||
{ title: 'TLS', value: 'tls' },
|
||||
{ title: 'QUIC', value: 'quic' },
|
||||
{ title: 'STUN', value: 'stun' },
|
||||
{ title: 'DNS', value: 'dns' },
|
||||
{ title: 'BitTorrent', value: 'bittorrent' },
|
||||
{ title: 'DTLS', value: 'dtls' },
|
||||
{ title: 'SSH', value: 'ssh' },
|
||||
{ title: 'RDP', value: 'rdp' },
|
||||
],
|
||||
strategies: [
|
||||
{ title: 'Prefer IPv4', value: 'prefer_ipv4' },
|
||||
{ title: 'Prefer IPv6', value: 'prefer_ipv6' },
|
||||
{ title: 'IPv4 Only', value: 'ipv4_only' },
|
||||
{ title: 'IPv6 Only', value: 'ipv6_only' },
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -103,13 +219,18 @@ export default {
|
||||
if (newData.type) {
|
||||
this.ruleData = newData
|
||||
} else {
|
||||
this.ruleData = <logicalRule>{
|
||||
this.ruleData = {
|
||||
type: 'simple',
|
||||
mode: 'and',
|
||||
rules: <rule[]>[{...newData}],
|
||||
invert: newData.invert,
|
||||
outbound: newData.outbound,
|
||||
rules: <rule[]>[{}],
|
||||
}
|
||||
Object.keys(newData).forEach(key => {
|
||||
if (actionKeys.includes(key)) {
|
||||
this.ruleData[key] = newData[key]
|
||||
} else {
|
||||
this.ruleData.rules[0][key] = newData[key]
|
||||
}
|
||||
})
|
||||
}
|
||||
this.title = 'edit'
|
||||
}
|
||||
@@ -119,6 +240,7 @@ export default {
|
||||
mode: 'and',
|
||||
rules: <rule[]>[{}],
|
||||
invert: false,
|
||||
action: 'route',
|
||||
outbound: this.$props.outTags[0]?? 'direct',
|
||||
}
|
||||
this.title = 'add'
|
||||
@@ -130,11 +252,48 @@ export default {
|
||||
},
|
||||
saveChanges() {
|
||||
this.loading = true
|
||||
if (this.ruleData.type == 'simple'){
|
||||
this.ruleData.rules[0].outbound = this.ruleData.outbound
|
||||
this.ruleData.rules[0].invert = this.ruleData.invert
|
||||
let newRule = <any>{
|
||||
action: this.ruleData.action,
|
||||
invert: this.ruleData.invert,
|
||||
}
|
||||
this.$emit('save', this.ruleData)
|
||||
|
||||
// Filter action data
|
||||
switch (newRule.action){
|
||||
case 'route':
|
||||
newRule.outbound = this.ruleData.outbound
|
||||
break
|
||||
case 'route-options':
|
||||
newRule.override_address = this.ruleData.override_address.length > 0 ? this.ruleData.override_address : undefined
|
||||
newRule.override_port = this.ruleData.override_port > 0 ? this.ruleData.override_port : undefined
|
||||
newRule.network_strategy = this.ruleData.network_strategy.length > 0 ? this.ruleData.network_strategy : undefined
|
||||
newRule.fallback_delay = this.ruleData.fallback_delay.length > 0 ? this.ruleData.fallback_delay : undefined
|
||||
newRule.udp_disable_domain_unmapping = this.ruleData.udp_disable_domain_unmapping? true : undefined
|
||||
newRule.udp_connect = this.ruleData.udp_connect? true : undefined
|
||||
newRule.udp_timeout = this.ruleData.udp_timeout.length > 0 ? this.ruleData.udp_timeout : undefined
|
||||
break
|
||||
case 'reject':
|
||||
newRule.method = this.ruleData.method.length > 0 ? this.ruleData.method : undefined
|
||||
newRule.no_drop = this.ruleData.no_drop? true : undefined
|
||||
break
|
||||
case 'sniff':
|
||||
newRule.sniffer = this.ruleData.sniffer.length > 0 ? this.ruleData.sniffer : undefined
|
||||
newRule.timeout = this.ruleData.timeout.length > 0 ? this.ruleData.timeout : undefined
|
||||
break
|
||||
case 'resolve':
|
||||
newRule.strategy = this.ruleData.strategy.length > 0 ? this.ruleData.strategy : undefined
|
||||
newRule.server = this.ruleData.server.length > 0 ? this.ruleData.server : undefined
|
||||
break
|
||||
}
|
||||
|
||||
// Add rules
|
||||
if (this.ruleData.type == 'simple'){
|
||||
newRule = { ...this.ruleData.rules[0], ...newRule }
|
||||
} else {
|
||||
newRule.type = 'logical'
|
||||
newRule.mode = this.ruleData.mode
|
||||
newRule.rules = this.ruleData.rules
|
||||
}
|
||||
this.$emit('save', newRule)
|
||||
this.loading = false
|
||||
},
|
||||
deleteRule(index:number) {
|
||||
@@ -145,14 +304,7 @@ export default {
|
||||
logical: {
|
||||
get() { return this.ruleData.type == 'logical' },
|
||||
set(v:boolean) {
|
||||
if (v) {
|
||||
this.ruleData.type = 'logical'
|
||||
this.ruleData.outbound = this.ruleData.rules[0].outbound?? this.$props.outTags[0]
|
||||
delete this.ruleData.rules[0].outbound
|
||||
} else {
|
||||
this.ruleData.type = 'simple'
|
||||
this.ruleData.rules[0].outbound = this.ruleData.outbound
|
||||
}
|
||||
this.ruleData.type = v? 'logical' : 'simple'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -88,7 +88,6 @@ export default {
|
||||
tls: "TLS",
|
||||
multiplex: "Multiplex",
|
||||
transport: "Transport",
|
||||
method: "Method",
|
||||
headers: "Headers",
|
||||
key: "Key",
|
||||
value: "Value",
|
||||
@@ -260,9 +259,6 @@ export default {
|
||||
mdOption: "Multi Domain Options",
|
||||
},
|
||||
listen: {
|
||||
sniffing: "Sniffing",
|
||||
sniffingTimeout: "Sniffing Timeout",
|
||||
sniffingOverride: "Override Destation",
|
||||
options: "Listen Options",
|
||||
tcpOptions: "TCP Options",
|
||||
udpOptions: "UDP Options",
|
||||
@@ -328,6 +324,14 @@ export default {
|
||||
domainRules: "Domain/IP",
|
||||
srcIpRules: "Source IP",
|
||||
srcPortRules: "Source Port",
|
||||
udpDisableDomainUnmapping: "UDP Disable Domain Unmapping",
|
||||
udpConnect: "UDP Connect",
|
||||
udpTimeout: "UDP Timeout",
|
||||
method: "Method",
|
||||
noDrop: "No Drop",
|
||||
sniffer: "Sniffer",
|
||||
timeout: "Timeout",
|
||||
strategy: "Strategy",
|
||||
},
|
||||
ruleset: {
|
||||
add: "Add Ruleset",
|
||||
|
||||
@@ -259,9 +259,6 @@ export default {
|
||||
mdOption: "گزینههای دامنه چندگانه",
|
||||
},
|
||||
listen: {
|
||||
sniffing: "شنود آدرس",
|
||||
sniffingTimeout: "مهلت شنود آدرس",
|
||||
sniffingOverride: "جایگزینی مقصد",
|
||||
options: "گزینههای گوشدادن",
|
||||
tcpOptions: "گزینههای TCP",
|
||||
udpOptions: "گزینههای UDP",
|
||||
@@ -327,6 +324,14 @@ export default {
|
||||
domainRules: "دامنه/آدرس",
|
||||
srcIpRules: "آدرس مبدا",
|
||||
srcPortRules: "پورت مبدا",
|
||||
udpDisableDomainUnmapping: "عدم تبدیل مسیریابی دامنه",
|
||||
udpConnect: "اتصال UDP",
|
||||
udpTimeout: "مهلت UDP",
|
||||
method: "روش",
|
||||
noDrop: "عدم رهاکردن",
|
||||
sniffer: "شنود کننده",
|
||||
timeout: "مهلت",
|
||||
strategy: "استراتژی",
|
||||
},
|
||||
ruleset: {
|
||||
add: "ایجاد مجموعه",
|
||||
|
||||
@@ -88,7 +88,6 @@ export default {
|
||||
tls: "TLS",
|
||||
multiplex: "Мультиплекс",
|
||||
transport: "Транспорт",
|
||||
method: "Метод",
|
||||
headers: "Заголовки",
|
||||
key: "Ключ",
|
||||
value: "Значение",
|
||||
@@ -260,9 +259,6 @@ export default {
|
||||
mdOption: "Параметры мультидомена",
|
||||
},
|
||||
listen: {
|
||||
sniffing: "Обнаружение",
|
||||
sniffingTimeout: "Таймаут обнаружения",
|
||||
sniffingOverride: "Переопределение назначения",
|
||||
options: "Параметры прослушивания",
|
||||
tcpOptions: "Параметры TCP",
|
||||
udpOptions: "Параметры UDP",
|
||||
@@ -328,6 +324,14 @@ export default {
|
||||
domainRules: "Домен/IP",
|
||||
srcIpRules: "Источник IP",
|
||||
srcPortRules: "Источник порта",
|
||||
udpDisableDomainUnmapping: "Отключить перенос доменных имен",
|
||||
udpConnect: "Подключение UDP",
|
||||
udpTimeout: "Таймаут UDP",
|
||||
method: "Метод",
|
||||
noDrop: "Не сбрасывать",
|
||||
sniffer: "Обнаружение",
|
||||
timeout: "Таймаут",
|
||||
strategy: "Стратегия",
|
||||
},
|
||||
ruleset: {
|
||||
add: "Добавить набор правил",
|
||||
|
||||
@@ -86,7 +86,6 @@ export default {
|
||||
tls: "TLS",
|
||||
multiplex: "Ghép đa truyền thông ",
|
||||
transport: "Giao thông",
|
||||
method: "Phương pháp",
|
||||
headers: "Tiêu đề",
|
||||
key: "Chìa khóa",
|
||||
value: "Giá trị",
|
||||
@@ -249,7 +248,6 @@ export default {
|
||||
in: {
|
||||
addr: "Địa chỉ",
|
||||
port: "Cổng",
|
||||
sniffing: "Đang Sniffing",
|
||||
clients: "Kích hoạt khách hàng",
|
||||
ssMethod: "Phương thức",
|
||||
sSide: "Phía Máy chủ",
|
||||
@@ -259,9 +257,6 @@ export default {
|
||||
mdOption: "Tùy chọn Nhiều Tên miền",
|
||||
},
|
||||
listen: {
|
||||
sniffing: "Đang Sniffing",
|
||||
sniffingTimeout: "Thời gian Chờ Sniffing",
|
||||
sniffingOverride: "Ghi đè Đích",
|
||||
options: "Tùy chọn Nghe",
|
||||
tcpOptions: "Tùy chọn TCP",
|
||||
udpOptions: "Tùy chọn UDP",
|
||||
@@ -327,6 +322,15 @@ export default {
|
||||
domainRules: "Tên miền/IP",
|
||||
srcIpRules: "IP Nguồn",
|
||||
srcPortRules: "Cổng Nguồn",
|
||||
udpDisableDomainUnmapping: "Không màm mạng tiền lập tên miền",
|
||||
udpFallbackDelay: "Thời gian Chờ Fallback",
|
||||
udpConnect: "Kết nối UDP",
|
||||
udpTimeout: "Thời gian Chờ UDP",
|
||||
method: "Phương pháp",
|
||||
noDrop: "Không Tháp",
|
||||
sniffer: "Kiểm tra Sniffer",
|
||||
timeout: "Thời gian Chờ Sniffing",
|
||||
strategy: "Chiến lệ",
|
||||
},
|
||||
ruleset: {
|
||||
add: "Thêm Bộ quy tắc",
|
||||
|
||||
@@ -86,7 +86,6 @@ export default {
|
||||
tls: "TLS",
|
||||
multiplex: "多路复用",
|
||||
transport: "传输",
|
||||
method: "方法",
|
||||
headers: "标头",
|
||||
key: "键",
|
||||
value: "值",
|
||||
@@ -249,7 +248,6 @@ export default {
|
||||
in: {
|
||||
addr: "地址",
|
||||
port: "端口",
|
||||
sniffing: "嗅探",
|
||||
clients: "启用客户端",
|
||||
ssMethod: "方法",
|
||||
sSide: "服务器端",
|
||||
@@ -259,9 +257,6 @@ export default {
|
||||
mdOption: "多域名选项",
|
||||
},
|
||||
listen: {
|
||||
sniffing: "嗅探",
|
||||
sniffingTimeout: "嗅探超时",
|
||||
sniffingOverride: "覆盖目标地址",
|
||||
options: "监听选项",
|
||||
tcpOptions: "TCP 选项",
|
||||
udpOptions: "UDP 选项",
|
||||
@@ -327,6 +322,14 @@ export default {
|
||||
domainRules: "域名/IP",
|
||||
srcIpRules: "源 IP",
|
||||
srcPortRules: "源端口",
|
||||
udpDisableDomainUnmapping: "禁用域名解析映射",
|
||||
udpConnect: "启用 UDP 连接",
|
||||
udpTimeout: "UDP 超时",
|
||||
method: "方法",
|
||||
noDrop: "不丢弃",
|
||||
sniffer: "嗅探",
|
||||
timeout: "超时",
|
||||
strategy: "策略",
|
||||
},
|
||||
ruleset: {
|
||||
add: "添加规则集",
|
||||
|
||||
@@ -87,7 +87,6 @@ export default {
|
||||
tls: "TLS",
|
||||
multiplex: "多路復用",
|
||||
transport: "傳輸",
|
||||
method: "方法",
|
||||
headers: "方法",
|
||||
key: "鑰匙",
|
||||
value: "價值",
|
||||
@@ -250,7 +249,6 @@ export default {
|
||||
in: {
|
||||
addr: "地址",
|
||||
port: "端口",
|
||||
sniffing: "嗅探",
|
||||
clients: "啟用客戶端",
|
||||
ssMethod: "方法",
|
||||
sSide: "服務器端",
|
||||
@@ -260,9 +258,6 @@ export default {
|
||||
mdOption: "多域名選項",
|
||||
},
|
||||
listen: {
|
||||
sniffing: "嗅探",
|
||||
sniffingTimeout: "嗅探超時",
|
||||
sniffingOverride: "覆蓋目的地",
|
||||
options: "監聽選項",
|
||||
tcpOptions: "TCP 選項",
|
||||
udpOptions: "UDP 選項",
|
||||
@@ -328,6 +323,14 @@ export default {
|
||||
domainRules: "域名/IP",
|
||||
srcIpRules: "源 IP",
|
||||
srcPortRules: "源端口",
|
||||
udpDisableDomainUnmapping: "禁用域名解析映射",
|
||||
udpConnect: "啟用 UDP 連接",
|
||||
udpTimeout: "UDP 超時",
|
||||
method: "方法",
|
||||
noDrop: "不丟弃",
|
||||
sniffer: "嗅探",
|
||||
timeout: "超時",
|
||||
strategy: "策略",
|
||||
},
|
||||
ruleset: {
|
||||
add: "添加規則集",
|
||||
|
||||
@@ -41,10 +41,6 @@ export interface Listen {
|
||||
udp_fragment?: boolean
|
||||
udp_timeout?: string
|
||||
detour?: string
|
||||
sniff?: boolean
|
||||
sniff_override_destination?: boolean
|
||||
sniff_timeout?: string
|
||||
domain_strategy?: string
|
||||
}
|
||||
|
||||
interface InboundBasics extends Listen {
|
||||
@@ -180,7 +176,6 @@ export interface Tun extends InboundBasics {
|
||||
udp_timeout?: string
|
||||
stack?: string
|
||||
auto_route?: boolean
|
||||
// gso?: boolean
|
||||
// strict_route?: boolean
|
||||
// iproute2_table_index?: number
|
||||
// iproute2_rule_index?: number
|
||||
|
||||
@@ -4,7 +4,6 @@ import { Transport } from "./transport"
|
||||
|
||||
export const OutTypes = {
|
||||
Direct: 'direct',
|
||||
Block: 'block',
|
||||
SOCKS: 'socks',
|
||||
HTTP: 'http',
|
||||
Shadowsocks: 'shadowsocks',
|
||||
@@ -17,7 +16,6 @@ export const OutTypes = {
|
||||
Hysteria2: 'hysteria2',
|
||||
Tor: 'tor',
|
||||
SSH: 'ssh',
|
||||
DNS: 'dns',
|
||||
Selector: 'selector',
|
||||
URLTest: 'urltest',
|
||||
}
|
||||
@@ -54,12 +52,7 @@ export interface WgPeer {
|
||||
reserved?: number[]
|
||||
}
|
||||
|
||||
export interface Direct extends OutboundBasics, Dial {
|
||||
override_address?: string
|
||||
override_port?: number
|
||||
}
|
||||
|
||||
export interface Block extends OutboundBasics {}
|
||||
export interface Direct extends OutboundBasics, Dial {}
|
||||
|
||||
export interface SOCKS extends OutboundBasics, Dial {
|
||||
server: string
|
||||
@@ -209,8 +202,6 @@ export interface SSH extends OutboundBasics, Dial {
|
||||
client_version?: string
|
||||
}
|
||||
|
||||
export interface DNS extends OutboundBasics {}
|
||||
|
||||
export interface Selector extends OutboundBasics {
|
||||
outbounds: string[]
|
||||
url?: string
|
||||
@@ -240,7 +231,6 @@ export type Outbound = InterfaceMap[keyof InterfaceMap]
|
||||
// Create defaultValues object dynamically
|
||||
const defaultValues: Record<OutType, Outbound> = {
|
||||
direct: { type: OutTypes.Direct },
|
||||
block: { type: OutTypes.Block },
|
||||
socks: { type: OutTypes.SOCKS, version: "5" },
|
||||
http: { type: OutTypes.HTTP, tls: {} },
|
||||
shadowsocks: { type: OutTypes.Shadowsocks, method: 'none', multiplex: {} },
|
||||
@@ -253,7 +243,6 @@ const defaultValues: Record<OutType, Outbound> = {
|
||||
hysteria2: { type: OutTypes.Hysteria2, tls: { enabled: true } },
|
||||
tor: { type: OutTypes.Tor, executable_path: './tor', data_directory: '$HOME/.cache/tor', torrc: { ClientOnly: 1 } },
|
||||
ssh: { type: OutTypes.SSH },
|
||||
dns: { type: OutTypes.DNS },
|
||||
selector: { type: OutTypes.Selector },
|
||||
urltest: { type: OutTypes.URLTest },
|
||||
}
|
||||
|
||||
@@ -1,12 +1,43 @@
|
||||
export interface logicalRule {
|
||||
interface generalRule {
|
||||
invert: boolean
|
||||
action: 'route' | 'route-options' | 'reject' | 'hijack-dns' | 'sniff' | 'resolve'
|
||||
outbound?: string
|
||||
override_address?: string
|
||||
override_port?: number
|
||||
udp_disable_domain_unmapping?: boolean
|
||||
udp_connect?: boolean
|
||||
udp_timeout?: string
|
||||
method?: string
|
||||
no_drop?: boolean
|
||||
sniffer: string[]
|
||||
timeout: string
|
||||
strategy: string
|
||||
server: string
|
||||
}
|
||||
|
||||
export const actionKeys = [
|
||||
'invert',
|
||||
'action',
|
||||
'outbound',
|
||||
'override_address',
|
||||
'override_port',
|
||||
'udp_disable_domain_unmapping',
|
||||
'udp_connect',
|
||||
'udp_timeout',
|
||||
'method',
|
||||
'no_drop',
|
||||
'sniffer',
|
||||
'timeout',
|
||||
'strategy',
|
||||
'server'
|
||||
]
|
||||
export interface logicalRule extends generalRule {
|
||||
type: 'logical' | 'simple'
|
||||
mode: 'and' | 'or'
|
||||
rules: rule[]
|
||||
invert: boolean
|
||||
outbound: string
|
||||
}
|
||||
|
||||
export interface rule {
|
||||
export interface rule extends generalRule {
|
||||
inbound?: string[]
|
||||
ip_version?: 4 | 6
|
||||
network?: string[]
|
||||
@@ -32,8 +63,6 @@ export interface rule {
|
||||
clash_mode?: string
|
||||
rule_set?: string[]
|
||||
rule_set_ipcidr_match_source?: boolean
|
||||
invert?: boolean
|
||||
outbound?: string
|
||||
}
|
||||
|
||||
export interface ruleset {
|
||||
|
||||
@@ -96,16 +96,22 @@
|
||||
</v-row>
|
||||
</v-card-subtitle>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
<v-col>{{ $t('admin.action') }}</v-col>
|
||||
<v-col>
|
||||
{{ item.action }}
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col>{{ $t('objects.outbound') }}</v-col>
|
||||
<v-col>
|
||||
{{ item.outbound }}
|
||||
{{ item.outbound?? '-' }}
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
<v-col>{{ $t('pages.rules') }}</v-col>
|
||||
<v-col>
|
||||
{{ item.rules ? item.rules.length : Object.keys(item).filter(r => !["rule_set_ipcidr_match_source","invert","outbound"].includes(r)).length }}
|
||||
{{ item.rules ? item.rules.length : Object.keys(item).filter(r => !actionKeys.includes(r)).length }}
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row>
|
||||
@@ -151,7 +157,7 @@ import { computed, ref, onMounted } from 'vue'
|
||||
import RuleVue from '@/layouts/modals/Rule.vue'
|
||||
import RulesetVue from '@/layouts/modals/Ruleset.vue'
|
||||
import { Config } from '@/types/config'
|
||||
import { logicalRule, ruleset } from '@/types/rules'
|
||||
import { actionKeys, ruleset } from '@/types/rules'
|
||||
import { FindDiff } from '@/plugins/utils'
|
||||
|
||||
const oldConfig = ref({})
|
||||
@@ -239,15 +245,12 @@ const closeRuleModal = () => {
|
||||
ruleModal.value.visible = false
|
||||
}
|
||||
|
||||
const saveRuleModal = (data:logicalRule) => {
|
||||
// Logical or simple
|
||||
const ruleData = data.type == 'logical' ? data : data.rules[0]
|
||||
|
||||
const saveRuleModal = (data:any) => {
|
||||
// New or Edit
|
||||
if (ruleModal.value.index == -1) {
|
||||
rules.value.push(ruleData)
|
||||
rules.value.push(data)
|
||||
} else {
|
||||
rules.value[ruleModal.value.index] = ruleData
|
||||
rules.value[ruleModal.value.index] = data
|
||||
}
|
||||
ruleModal.value.visible = false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user