258 lines
8.8 KiB
Lua
Executable File
258 lines
8.8 KiB
Lua
Executable File
local ucursor = require 'luci.model.uci'.cursor()
|
|
local name = 'vssr'
|
|
local json = require 'luci.jsonc'
|
|
local nixio = require 'nixio'
|
|
local server_section = arg[1]
|
|
local proto = arg[2]
|
|
local local_port = arg[3]
|
|
local outbounds_table = {}
|
|
local rules_table = {}
|
|
|
|
function read_conf(file)
|
|
if not nixio.fs.access(file) then
|
|
return nil
|
|
end
|
|
local rfile = io.open(file, "r")
|
|
local ltable = {}
|
|
for line in rfile:lines() do
|
|
local re = string.gsub(line, "\r", "")
|
|
table.insert(ltable, re)
|
|
end
|
|
local rtable = next(ltable) ~= nil and ltable or nil
|
|
return rtable
|
|
end
|
|
|
|
local v2ray_flow = ucursor:get_first(name, 'global', 'v2ray_flow', '0')
|
|
|
|
local custom_domain = read_conf("/etc/vssr/custom_domain.list")
|
|
local custom_ip = read_conf("/etc/vssr/custom_ip.list")
|
|
|
|
local youtube_domain = read_conf("/etc/vssr/youtube_domain.list")
|
|
local youtube_ip = read_conf("/etc/vssr/youtube_ip.list")
|
|
|
|
local tw_video_domain = read_conf("/etc/vssr/tw_video_domain.list")
|
|
local tw_video_ip = read_conf("/etc/vssr/tw_video_ip.list")
|
|
|
|
local netflix_domain = read_conf("/etc/vssr/netflix_domain.list")
|
|
local netflix_ip = read_conf("/etc/vssr/netflix_ip.list")
|
|
|
|
local disney_domain = read_conf("/etc/vssr/disney_domain.list")
|
|
local disney_ip = read_conf("/etc/vssr/disney_ip.list")
|
|
|
|
local prime_domain = read_conf("/etc/vssr/prime_domain.list")
|
|
local prime_ip = read_conf("/etc/vssr/prime_ip.list")
|
|
|
|
local tvb_domain = read_conf("/etc/vssr/tvb_domain.list")
|
|
local tvb_ip = read_conf("/etc/vssr/tvb_ip.list")
|
|
|
|
|
|
local flow_table = {
|
|
yotube = {
|
|
name = 'youtube',
|
|
port = 2081,
|
|
rules = {
|
|
type = 'field',
|
|
domain = youtube_domain,
|
|
ip = youtube_ip,
|
|
outboundTag = 'youtube'
|
|
}
|
|
},
|
|
tw_video = {
|
|
name = 'tw_video',
|
|
port = 2082,
|
|
rules = {
|
|
type = 'field',
|
|
domain = tw_video_domain,
|
|
ip = tw_video_ip,
|
|
outboundTag = 'tw_video'
|
|
}
|
|
},
|
|
netflix = {
|
|
name = 'netflix',
|
|
port = 2083,
|
|
rules = {
|
|
type = 'field',
|
|
domain = netflix_domain,
|
|
ip = netflix_ip,
|
|
outboundTag = 'netflix'
|
|
}
|
|
},
|
|
disney = {
|
|
name = 'disney',
|
|
port = 2084,
|
|
rules = {
|
|
type = 'field',
|
|
domain = disney_domain,
|
|
ip = disney_ip,
|
|
outboundTag = 'disney'
|
|
}
|
|
},
|
|
prime = {
|
|
name = 'prime',
|
|
port = 2085,
|
|
rules = {
|
|
type = 'field',
|
|
domain = prime_domain,
|
|
ip = prime_ip,
|
|
outboundTag = 'prime'
|
|
}
|
|
},
|
|
tvb = {
|
|
name = 'tvb',
|
|
port = 2086,
|
|
rules = {
|
|
type = 'field',
|
|
domain = tvb_domain,
|
|
ip = tvb_ip,
|
|
outboundTag = 'tvb'
|
|
}
|
|
},
|
|
custom = {
|
|
name = 'custom',
|
|
port = 2087,
|
|
rules = {
|
|
type = 'field',
|
|
domain = custom_domain,
|
|
ip = custom_ip,
|
|
outboundTag = 'custom'
|
|
}
|
|
}
|
|
}
|
|
|
|
function gen_outbound(server_node, tags, local_ports)
|
|
local bound = {}
|
|
if server_node == nil or server_node == 'nil' then
|
|
bound = nil
|
|
else
|
|
local server = ucursor:get_all(name, server_node)
|
|
local node_type = server.type == "vless" and "vless" or "vmess"
|
|
|
|
if server.type ~= 'v2ray' and server.type ~= 'vless' then
|
|
bound = {
|
|
tag = tags,
|
|
protocol = 'socks',
|
|
settings = {
|
|
servers = {
|
|
{ address = '127.0.0.1', port = tonumber(local_ports) }
|
|
}
|
|
}
|
|
}
|
|
else
|
|
bound = {
|
|
tag = tags,
|
|
protocol = node_type,
|
|
settings = {
|
|
vnext = {
|
|
{
|
|
address = server.server,
|
|
port = tonumber(server.server_port),
|
|
users = {
|
|
{
|
|
id = server.vmess_id,
|
|
alterId = server.type == "v2ray" and tonumber(server.alter_id) or nil,
|
|
security = server.type == "v2ray" and server.security or nil,
|
|
flow = (server.xtls == '1') and (server.vless_flow and server.vless_flow or "xtls-rprx-origin") or nil,
|
|
encryption = server.type == "vless" and server.vless_encryption or nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
-- 底层传输配置
|
|
streamSettings = {
|
|
network = server.transport,
|
|
security = (server.tls == '1') and ((server.xtls == '1') and "xtls" or "tls") or "none",
|
|
tlsSettings = (server.tls == '1' and server.xtls ~= '1') and { allowInsecure = (server.insecure ~= "0") and true or false, serverName = server.tls_host, } or nil,
|
|
xtlsSettings = (server.xtls == '1') and { allowInsecure = (server.insecure ~= "0") and true or false, serverName = server.tls_host, } or nil,
|
|
kcpSettings = (server.transport == 'kcp') and
|
|
{
|
|
mtu = tonumber(server.mtu),
|
|
tti = tonumber(server.tti),
|
|
uplinkCapacity = tonumber(server.uplink_capacity),
|
|
downlinkCapacity = tonumber(server.downlink_capacity),
|
|
congestion = (server.congestion == '1') and true or false,
|
|
readBufferSize = tonumber(server.read_buffer_size),
|
|
writeBufferSize = tonumber(server.write_buffer_size),
|
|
header = { type = server.kcp_guise }
|
|
} or
|
|
nil,
|
|
wsSettings = (server.transport == 'ws') and (server.ws_path ~= nil or server.ws_host ~= nil) and
|
|
{
|
|
path = server.ws_path,
|
|
headers = (server.ws_host ~= nil) and { Host = server.ws_host } or nil
|
|
} or
|
|
nil,
|
|
httpSettings = (server.transport == 'h2') and { path = server.h2_path, host = server.h2_host } or nil,
|
|
quicSettings = (server.transport == 'quic') and
|
|
{
|
|
security = server.quic_security,
|
|
key = server.quic_key,
|
|
header = { type = server.quic_guise }
|
|
} or
|
|
nil
|
|
},
|
|
mux = {
|
|
enabled = (server.mux == '1') and true or false,
|
|
concurrency = tonumber(server.concurrency)
|
|
}
|
|
}
|
|
end
|
|
end
|
|
return bound
|
|
end
|
|
|
|
if v2ray_flow == '1' then
|
|
|
|
table.insert(outbounds_table, gen_outbound(server_section, 'global', 2080))
|
|
for _, v in pairs(flow_table) do
|
|
if (v.rules.domain ~= nil or v.rules.ip ~= nil) then
|
|
local server = ucursor:get_first(name, 'global', v.name .. '_server')
|
|
table.insert(outbounds_table, gen_outbound(server, v.name, v.port))
|
|
|
|
if (v.rules.domain ~= nil) then
|
|
domain_rules = {
|
|
type = 'field',
|
|
domain = v.rules.domain,
|
|
outboundTag = v.rules.outboundTag
|
|
}
|
|
table.insert(rules_table, (server ~= nil and server ~= 'nil') and domain_rules or nil)
|
|
end
|
|
|
|
if (v.rules.ip ~= nil) then
|
|
ip_rules = {
|
|
type = 'field',
|
|
ip = v.rules.ip,
|
|
outboundTag = v.rules.outboundTag
|
|
}
|
|
table.insert(rules_table, (server ~= nil and server ~= 'nil') and ip_rules or nil)
|
|
end
|
|
end
|
|
end
|
|
else
|
|
table.insert(outbounds_table, gen_outbound(server_section, 'main', local_port))
|
|
end
|
|
|
|
local v2ray = {
|
|
log = {
|
|
-- error = "/var/vssrsss.log",
|
|
-- access = "/var/v2rays.log",
|
|
loglevel = 'warning'
|
|
},
|
|
-- 传入连接
|
|
inbounds = {
|
|
{
|
|
port = tonumber(local_port),
|
|
protocol = 'dokodemo-door',
|
|
settings = { network = proto, followRedirect = true },
|
|
sniffing = { enabled = true, destOverride = { 'http', 'tls' } },
|
|
streamSettings = {
|
|
sockopt = { tproxy = (proto == 'tcp') and 'redirect' or 'tproxy' }
|
|
}
|
|
}
|
|
},
|
|
-- 传出连接
|
|
outbounds = outbounds_table,
|
|
routing = { domainStrategy = 'IPIfNonMatch', rules = rules_table }
|
|
}
|
|
print(json.stringify(v2ray, 1))
|