small-package/luci-app-vssr/luasrc/model/cbi/vssr/client-config.lua

519 lines
12 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Copyright (C) 2017 yushi studio <ywb94@qq.com> github.com/ywb94
-- Licensed to the public under the GNU General Public License v3.
local m, s, o, kcp_enable
local vssr = 'vssr'
local uci = luci.model.uci.cursor()
local fs = require 'nixio.fs'
local sys = require 'luci.sys'
local sid = arg[1]
local uuid = luci.sys.exec('cat /proc/sys/kernel/random/uuid')
local function isKcptun(file)
if not fs.access(file, 'rwx', 'rx', 'rx') then
fs.chmod(file, 755)
end
local str = sys.exec(file .. " -v | awk '{printf $1}'")
return (str:lower() == 'kcptun')
end
local server_table = {}
local encrypt_methods = {
'none',
'table',
'rc4',
'rc4-md5-6',
'rc4-md5',
'aes-128-cfb',
'aes-192-cfb',
'aes-256-cfb',
'aes-128-ctr',
'aes-192-ctr',
'aes-256-ctr',
'bf-cfb',
'camellia-128-cfb',
'camellia-192-cfb',
'camellia-256-cfb',
'cast5-cfb',
'des-cfb',
'idea-cfb',
'rc2-cfb',
'seed-cfb',
'salsa20',
'chacha20',
'chacha20-ietf'
}
local encrypt_methods_ss = {
-- aead
'aes-128-gcm',
'aes-192-gcm',
'aes-256-gcm',
'chacha20-ietf-poly1305',
'xchacha20-ietf-poly1305', -- stream
'table',
'rc4',
'rc4-md5',
'aes-128-cfb',
'aes-192-cfb',
'aes-256-cfb',
'aes-128-ctr',
'aes-192-ctr',
'aes-256-ctr',
'bf-cfb',
'camellia-128-cfb',
'camellia-192-cfb',
'camellia-256-cfb',
'salsa20',
'chacha20',
'chacha20-ietf'
}
local protocol = {
'origin',
'verify_deflate',
'auth_sha1_v4',
'auth_aes128_sha1',
'auth_aes128_md5',
'auth_chain_a',
'auth_chain_b',
'auth_chain_c',
'auth_chain_d',
'auth_chain_e',
'auth_chain_f'
}
obfs = {
'plain',
'http_simple',
'http_post',
'random_head',
'tls1.2_ticket_auth'
}
local securitys = {
'auto',
'none',
'aes-128-gcm',
'chacha20-poly1305'
}
local flows = {
'xtls-rprx-origin',
'xtls-rprx-origin-udp443',
'xtls-rprx-direct',
'xtls-rprx-direct-udp443',
'xtls-rprx-splice',
'xtls-rprx-splice-udp443'
}
m = Map(vssr, translate('Edit vssr Server'))
m.redirect = luci.dispatcher.build_url('admin/services/vssr/servers')
if m.uci:get(vssr, sid) ~= 'servers' then
luci.http.redirect(m.redirect)
return
end
-- [[ Servers Setting ]]--
s = m:section(NamedSection, sid, 'servers')
s.anonymous = true
s.addremove = false
o = s:option(DummyValue, 'ssr_url', translate('Configuration Url'))
o.rawhtml = true
o.template = 'vssr/ssrurl'
o.value = sid
o = s:option(ListValue, 'type', translate('Server Node Type'))
o:value('ssr', translate('ShadowsocksR'))
if nixio.fs.access('/usr/bin/ss-redir') then
o:value('ss', translate('Shadowsocks New Version'))
end
if nixio.fs.access('/usr/bin/xray') then
o:value('v2ray', translate('V2Ray'))
o:value('vless', translate('VLESS'))
end
if nixio.fs.access('/usr/sbin/trojan') then
o:value('trojan', translate('Trojan'))
end
if nixio.fs.access('/usr/bin/hysteria') then
o:value('hysteria', translate('Hysteria'))
end
o.description = translate('Using incorrect encryption mothod may causes service fail to start')
o = s:option(Value, 'alias', translate('Alias(optional)'))
o = s:option(Value, 'flag', translate('Area'))
o.description = translate('请自己指定。格式cn us hk 等')
o.rmempty = true
o = s:option(Value, 'server', translate('Server Address'))
o.datatype = 'host'
o.rmempty = false
o = s:option(Value, 'server_port', translate('Server Port'))
o.datatype = 'port'
o.rmempty = false
o = s:option(Value, 'password', translate('Password'))
o.password = true
o.rmempty = true
o:depends('type', 'ssr')
o:depends('type', 'ss')
o:depends('type', 'trojan')
o = s:option(Value, 'peer', translate('Peer'))
o.datatype = 'host'
o.rmempty = true
o:depends('type', 'trojan')
o = s:option(ListValue, 'encrypt_method', translate('Encrypt Method'))
for _, v in ipairs(encrypt_methods) do
o:value(v)
end
o.rmempty = true
o:depends('type', 'ssr')
o = s:option(ListValue, 'encrypt_method_ss', translate('Encrypt Method'))
for _, v in ipairs(encrypt_methods_ss) do
o:value(v)
end
o.rmempty = true
o:depends('type', 'ss')
-- o:depends("type", "hysteria")
o = s:option(Value, 'h_obfs', translate('Hysteria Obfs'))
o.datatype = "minlength(1)"
o.rmempty = false
o:depends('type', 'hysteria')
-- 协议
o = s:option(ListValue, 'h_protocol', translate('Protocol'))
o:value('udp', 'UDP')
o:value('wechat-video', 'Wechat Video')
o:value('faketcp', 'Fake TCP')
o.rmempty = false
o:depends('type', 'hysteria')
-- up_mbps
o = s:option(Value, 'h_up_mbps', translate('Up Mbps'))
o.datatype = "uinteger"
o.rmempty = false
o:depends('type', 'hysteria')
-- down_mbps
o = s:option(Value, 'h_down_mbps', translate('Down Mbps'))
o.datatype = "uinteger"
o.rmempty = false
o:depends('type', 'hysteria')
o = s:option(Value, 'h_server_name', translate('Server Name'))
o.datatype = 'host'
o.rmempty = true
o:depends('type', 'hysteria')
-- Shadowsocks Plugin
o = s:option(Value, 'plugin', translate('Plugin'))
o.rmempty = true
o:depends('type', 'ss')
o = s:option(Value, 'plugin_opts', translate('Plugin Opts'))
o.rmempty = true
o:depends('type', 'ss')
o = s:option(ListValue, 'protocol', translate('Protocol'))
for _, v in ipairs(protocol) do
o:value(v)
end
o.rmempty = true
o:depends('type', 'ssr')
o = s:option(Value, 'protocol_param', translate('Protocol param(optional)'))
o:depends('type', 'ssr')
o = s:option(ListValue, 'obfs', translate('Obfs'))
for _, v in ipairs(obfs) do
o:value(v)
end
o.rmempty = true
o:depends('type', 'ssr')
o = s:option(Value, 'obfs_param', translate('Obfs param(optional)'))
o:depends('type', 'ssr')
-- AlterId
o = s:option(Value, 'alter_id', translate('AlterId'))
o.datatype = 'port'
o.default = 16
o.rmempty = true
o:depends('type', 'v2ray')
-- VmessId
o = s:option(Value, 'vmess_id', translate('VMESS/VLESS ID (UUID)'))
o.rmempty = true
o.default = uuid
o:depends('type', 'v2ray')
o:depends('type', 'vless')
o:depends('type', 'xray')
-- VLESS 加密方式
o = s:option(Value, 'vless_encryption', translate('VLESS Encryption'))
o.rmempty = true
o.default = 'none'
o:depends('type', 'vless')
o:depends('type', 'xray')
-- 加密方式
o = s:option(ListValue, 'security', translate('Encrypt Method'))
for _, v in ipairs(securitys) do
o:value(v, v:upper())
end
o.rmempty = true
o:depends('type', 'v2ray')
-- 传输协议
o = s:option(ListValue, 'transport', translate('Transport'))
o:value('tcp', 'TCP')
o:value('kcp', 'mKCP')
o:value('ws', 'WebSocket')
o:value('h2', 'HTTP/2')
o:value('quic', 'QUIC')
o.rmempty = true
o:depends('type', 'v2ray')
o:depends('type', 'vless')
o:depends('type', 'xray')
-- [[ TCP部分 ]]--
-- TCP伪装
o = s:option(ListValue, 'tcp_guise', translate('Camouflage Type'))
o:depends('transport', 'tcp')
o:value('none', translate('None'))
o:value('http', 'HTTP')
o.rmempty = true
-- HTTP域名
o = s:option(DynamicList, 'http_host', translate('HTTP Host'))
o:depends('tcp_guise', 'http')
o.rmempty = true
-- HTTP路径
o = s:option(DynamicList, 'http_path', translate('HTTP Path'))
o:depends('tcp_guise', 'http')
o.rmempty = true
-- [[ WS部分 ]]--
-- WS域名
o = s:option(Value, 'ws_host', translate('WebSocket Host'))
o:depends('transport', 'ws')
o.rmempty = true
-- WS路径
o = s:option(Value, 'ws_path', translate('WebSocket Path'))
o:depends('transport', 'ws')
o.rmempty = true
-- [[ H2部分 ]]--
-- H2域名
o = s:option(DynamicList, 'h2_host', translate('HTTP/2 Host'))
o:depends('transport', 'h2')
o.rmempty = true
-- H2路径
o = s:option(Value, 'h2_path', translate('HTTP/2 Path'))
o:depends('transport', 'h2')
o.rmempty = true
-- [[ QUIC部分 ]]--
o = s:option(ListValue, 'quic_security', translate('QUIC Security'))
o:depends('transport', 'quic')
o.rmempty = true
o:value('none', translate('None'))
o:value('aes-128-gcm', translate('aes-128-gcm'))
o:value('chacha20-poly1305', translate('chacha20-poly1305'))
o = s:option(Value, 'quic_key', translate('QUIC Key'))
o:depends('transport', 'quic')
o.rmempty = true
o = s:option(ListValue, 'quic_guise', translate('Header'))
o:depends('transport', 'quic')
o.rmempty = true
o:value('none', translate('None'))
o:value('srtp', translate('VideoCall (SRTP)'))
o:value('utp', translate('BitTorrent (uTP)'))
o:value('wechat-video', translate('WechatVideo'))
o:value('dtls', 'DTLS 1.2')
o:value('wireguard', 'WireGuard')
-- [[ mKCP部分 ]]--
o = s:option(ListValue, 'kcp_guise', translate('Camouflage Type'))
o:depends('transport', 'kcp')
o:value('none', translate('None'))
o:value('srtp', translate('VideoCall (SRTP)'))
o:value('utp', translate('BitTorrent (uTP)'))
o:value('wechat-video', translate('WechatVideo'))
o:value('dtls', 'DTLS 1.2')
o:value('wireguard', 'WireGuard')
o.rmempty = true
o = s:option(Value, 'mtu', translate('MTU'))
o.datatype = 'uinteger'
o:depends('transport', 'kcp')
o.default = 1350
o.rmempty = true
o = s:option(Value, 'tti', translate('TTI'))
o.datatype = 'uinteger'
o:depends('transport', 'kcp')
o.default = 50
o.rmempty = true
o = s:option(Value, 'uplink_capacity', translate('Uplink Capacity'))
o.datatype = 'uinteger'
o:depends('transport', 'kcp')
o.default = 5
o.rmempty = true
o = s:option(Value, 'downlink_capacity', translate('Downlink Capacity'))
o.datatype = 'uinteger'
o:depends('transport', 'kcp')
o.default = 20
o.rmempty = true
o = s:option(Value, 'read_buffer_size', translate('Read Buffer Size'))
o.datatype = 'uinteger'
o:depends('transport', 'kcp')
o.default = 2
o.rmempty = true
o = s:option(Value, 'write_buffer_size', translate('Write Buffer Size'))
o.datatype = 'uinteger'
o:depends('transport', 'kcp')
o.default = 2
o.rmempty = true
o = s:option(Value, 'seed', translate('Seed'))
o:depends('transport', 'kcp')
o.default = ''
o.rmempty = true
o = s:option(Flag, 'congestion', translate('Congestion'))
o:depends('transport', 'kcp')
o.rmempty = true
-- [[ allowInsecure ]]--
o = s:option(Flag, 'insecure', translate('allowInsecure'))
o.rmempty = false
o:depends('type', 'v2ray')
o:depends('type', 'trojan')
o:depends('type', 'vless')
o:depends('type', 'xray')
o:depends('type', 'hysteria')
-- [[ TLS ]]--
o = s:option(Flag, 'tls', translate('TLS'))
o.rmempty = true
o.default = '0'
o:depends('type', 'v2ray')
o:depends('type', 'vless')
o:depends('type', 'xray')
o = s:option(Value, 'tls_host', translate('TLS Host'))
--o:depends("type", "trojan")
o:depends('tls', '1')
o.rmempty = true
-- XTLS
o = s:option(Flag, 'xtls', translate('XTLS'))
o.rmempty = true
o.default = '0'
o:depends({type = 'vless', tls = '1'})
o:depends({type = 'xray', tls = '1'})
-- Flow
o = s:option(ListValue, 'vless_flow', translate('Flow'))
for _, v in ipairs(flows) do
o:value(v, v)
end
o.rmempty = true
o.default = 'xtls-rprx-splice'
o:depends('xtls', '1')
-- [[ Mux ]]--
o = s:option(Flag, 'mux', translate('Mux'))
o.rmempty = true
o.default = '0'
o:depends('type', 'v2ray')
o:depends('type', 'vless')
o = s:option(Value, 'concurrency', translate('Concurrency'))
o.datatype = 'uinteger'
o.rmempty = true
o.default = '8'
o:depends('mux', '1')
-- [[NO self cert]]
o = s:option(Flag, 'fast_open', translate('TCP Fast Open'))
o.rmempty = true
o.default = '0'
o:depends('type', 'ssr')
o:depends('type', 'ss')
o:depends('type', 'trojan')
o = s:option(Flag, 'switch_enable', translate('Enable Auto Switch'))
o.rmempty = false
o.default = '1'
o = s:option(Value, 'local_port', translate('Local Port'))
o.datatype = 'port'
o.default = 1234
o.rmempty = false
if nixio.fs.access('/usr/bin/kcptun-client') then
kcp_enable = s:option(Flag, 'kcp_enable', translate('KcpTun Enable'), translate('bin:/usr/bin/kcptun-client'))
kcp_enable.rmempty = true
kcp_enable.default = '0'
kcp_enable:depends('type', 'ssr')
kcp_enable:depends('type', 'ss')
o = s:option(Value, 'kcp_port', translate('KcpTun Port'))
o.datatype = 'port'
o.default = 4000
function o.validate(self, value, section)
local kcp_file = '/usr/bin/kcptun-client'
local enable = kcp_enable:formvalue(section) or kcp_enable.disabled
if enable == kcp_enable.enabled then
if not fs.access(kcp_file) then
return nil, translate("Haven't a Kcptun executable file")
elseif not isKcptun(kcp_file) then
return nil, translate('Not a Kcptun executable file')
end
end
return value
end
o:depends('type', 'ssr')
o:depends('type', 'ss')
o = s:option(Value, 'kcp_password', translate('KcpTun Password'))
o.password = true
o:depends('type', 'ssr')
o:depends('type', 'ss')
o = s:option(Value, 'kcp_param', translate('KcpTun Param'))
o.default = '--nocomp'
o:depends('type', 'ssr')
o:depends('type', 'ss')
end
return m