Merge pull request #331 from libc0607/master

Add luci-app-v2ray.
This commit is contained in:
coolsnowwolf 2018-03-28 16:33:57 +08:00 committed by GitHub
commit d4b78759c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 4220 additions and 0 deletions

View File

@ -0,0 +1,16 @@
# Copyright (C) 2016 Openwrt.org
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI support for V2Ray
LUCI_DEPENDS:=+iptables-mod-tproxy +kmod-ipt-tproxy +ip +ipset-lists +pdnsd-alt +coreutils +coreutils-base64 +coreutils-nohup +dnsmasq-full +lua-cjson +ca-certificates +v2ray
LUCI_PKGARCH:=all
PKG_VERSION:=1.0
PKG_RELEASE:=1
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -0,0 +1,9 @@
module("luci.controller.v2ray", package.seeall)
function index()
if not nixio.fs.access("/etc/config/v2ray") then
return
end
local page
page = entry({"admin", "services", "v2ray"}, cbi("v2ray"), _("V2Ray Pro"))
page.dependent = true
end

View File

@ -0,0 +1,330 @@
local fs = require "nixio.fs"
local NXFS = require "nixio.fs"
local WLFS = require "nixio.fs"
local SYS = require "luci.sys"
local ND = SYS.exec("cat /etc/gfwlist/china-banned | wc -l")
local conf = "/etc/v2ray/base-gfwlist.txt"
local watch = "/tmp/v2ray_watchdog.log"
local dog = "/tmp/v2raypro.log"
local http = luci.http
local ucursor = require "luci.model.uci".cursor()
local Status
if SYS.call("pidof v2ray > /dev/null") == 0 then
Status = translate("<strong><font color=\"green\">V2Ray is Running</font></strong>")
else
Status = translate("<strong><font color=\"red\">V2Ray is Not Running</font></strong>")
end
m = Map("v2ray")
m.title = translate("V2Ray Transparent Proxy")
m.description = translate("A fast secure tunnel proxy that help you get through firewalls on your router")
s = m:section(TypedSection, "v2ray")
s.anonymous = true
s.description = translate(string.format("%s<br /><br />", Status))
-- ---------------------------------------------------
s:tab("basic", translate("Base Setting"))
switch = s:taboption("basic",Flag, "enabled", translate("Enable"))
switch.rmempty = false
proxy_mode = s:taboption("basic",ListValue, "proxy_mode", translate("Proxy Mode"))
proxy_mode:value("M", translate("Base on GFW-List Auto Proxy Mode(Recommend)"))
proxy_mode:value("S", translate("Bypassing China Manland IP Mode(Be caution when using P2P download)"))
proxy_mode:value("G", translate("Global Mode"))
proxy_mode:value("V", translate("Overseas users watch China video website Mode"))
cronup = s:taboption("basic", Flag, "cron_mode", translate("Auto Update GFW-List"),
translate(string.format("GFW-List Lines <strong><font color=\"blue\">%s</font></strong> Lines", ND)))
cronup.default = 0
cronup.rmempty = false
updatead = s:taboption("basic", Button, "updatead", translate("Manually force update GFW-List"), translate("Note: It needs to download and convert the rules. The background process may takes 60-120 seconds to run. <br / > After completed it would automatically refresh, please do not duplicate click!"))
updatead.inputtitle = translate("Manually force update GFW-List")
updatead.inputstyle = "apply"
updatead.write = function()
SYS.call("nohup sh /etc/v2ray/up-gfwlist.sh > /tmp/gfwupdate.log 2>&1 &")
end
safe_dns_tcp = s:taboption("basic",Flag, "safe_dns_tcp", translate("DNS uses TCP"),
translate("Through the server transfer mode inquires DNS pollution prevention (Safer and recommended)"))
safe_dns_tcp.rmempty = false
-- safe_dns_tcp:depends("more", "1")
-- more_opt = s:taboption("basic",Flag, "more", translate("More Options"),
-- translate("Options for advanced users"))
-- timeout = s:taboption("basic",Value, "timeout", translate("Timeout"))
-- timeout.datatype = "range(0,10000)"
-- timeout.placeholder = "60"
-- timeout.optional = false
-- timeout:depends("more", "1")
-- safe_dns = s:taboption("basic",Value, "safe_dns", translate("Safe DNS"),
-- translate("8.8.8.8 or 8.8.4.4 is recommended"))
-- safe_dns.datatype = "ip4addr"
-- safe_dns.optional = false
-- safe_dns:depends("more", "1")
-- safe_dns_port = s:taboption("basic",Value, "safe_dns_port", translate("Safe DNS Port"),
-- translate("Foreign DNS on UDP port 53 might be polluted"))
-- safe_dns_port.datatype = "range(1,65535)"
-- safe_dns_port.placeholder = "53"
-- safe_dns_port.optional = false
-- safe_dns_port:depends("more", "1")
--fast_open =s:taboption("basic",Flag, "fast_open", translate("TCP Fast Open"),
-- translate("Enable TCP fast open, only available on kernel > 3.7.0"))
s:tab("main", translate("Server Setting"))
use_conf_file = s:taboption("main",Flag, "use_conf_file", translate("Use Config File"))
use_conf_file.rmempty = false
if nixio.fs.access("/usr/bin/v2ray/v2ctl") then
conf_file_type = s:taboption("main",ListValue, "conf_file_type", translate("Config File Type"))
conf_file_type:value("pb","Protobuf")
else
conf_file_type = s:taboption("main",ListValue, "conf_file_type", translate("Config File Type"), translate("Warning: Can't find v2ctl. You can only choose Protobuf."))
end
conf_file_type:value("json","JSON")
conf_file_type:depends("use_conf_file", 1)
conf_file_path = s:taboption("main",Value, "conf_file_path", translate("Config File Path"),
translate("If you choose to upload a new file, please do not modify and this configuration will be overwritten automatically."))
conf_file_path:depends("use_conf_file", 1)
upload_conf = s:taboption("main",FileUpload, "")
upload_conf.template = "cbi/other_upload2"
upload_conf:depends("use_conf_file", 1)
um = s:taboption("main",DummyValue, "", nil)
um.template = "cbi/other_dvalue"
um:depends("use_conf_file", 1)
local conf_dir, fd
conf_dir = "/etc/v2ray/"
nixio.fs.mkdir(conf_dir)
http.setfilehandler(
function(meta, chunk, eof)
if not fd then
if not meta then return end
if meta and chunk then fd = nixio.open(conf_dir .. meta.file, "w") end
if not fd then
um.value = translate("Create upload file error.")
return
end
end
if chunk and fd then
fd:write(chunk)
end
if eof and fd then
fd:close()
fd = nil
um.value = translate("File saved to") .. ' "/etc/v2ray/' .. meta.file .. '"'
ucursor:set("v2ray","v2ray","conf_file_path","/etc/v2ray/" .. meta.file)
ucursor:commit("v2ray")
end
end
)
if luci.http.formvalue("upload") then
local f = luci.http.formvalue("ulfile")
if #f <= 0 then
um.value = translate("No specify upload file.")
end
end
server = s:taboption("main",Value, "address", translate("Server Address"))
server.datatype = "host"
server:depends("use_conf_file", 0)
server_port = s:taboption("main",Value, "port", translate("Server Port"))
server_port.datatype = "range(0,65535)"
server_port:depends("use_conf_file", 0)
id = s:taboption("main",Value, "id", translate("ID"))
id.password = true
id:depends("use_conf_file", 0)
alterId = s:taboption("main",Value, "alterId", translate("Alter ID"))
alterId.datatype = "range(1,65535)"
alterId:depends("use_conf_file", 0)
security = s:taboption("main",ListValue, "security", translate("Security"))
security:value("none")
security:value("auto")
security:value("aes-128-cfb")
security:value("aes-128-gcm")
security:value("chacha20-poly1305")
security:depends("use_conf_file", 0)
network_type = s:taboption("main",ListValue, "network_type", translate("Network Type"))
network_type:value("tcp")
network_type:value("kcp")
network_type:value("ws")
network_type:depends("use_conf_file", 0)
-- tcp settings
tcp_obfs = s:taboption("main",ListValue, "tcp_obfs", translate("TCP Obfs"))
tcp_obfs:value("none")
tcp_obfs:value("http")
tcp_obfs:depends("network_type", "tcp")
tcp_path = s:taboption("main",DynamicList, "tcp_path", translate("TCP Obfs Path"))
tcp_path:depends("tcp_obfs", "http")
tcp_host = s:taboption("main",DynamicList, "tcp_host", translate("TCP Obfs Header"))
tcp_host:depends("tcp_obfs", "http")
tcp_host.datatype = "host"
-- kcp settings
kcp_obfs = s:taboption("main",ListValue, "kcp_obfs", translate("KCP Obfs"))
kcp_obfs:value("none")
kcp_obfs:value("srtp")
kcp_obfs:value("utp")
kcp_obfs:value("wechat-video")
kcp_obfs:depends("network_type", "kcp")
kcp_mtu = s:taboption("main",Value, "kcp_mtu", translate("KCP MTU"))
kcp_mtu.datatype = "range(576,1460)"
kcp_mtu:depends("network_type", "kcp")
kcp_tti = s:taboption("main",Value, "kcp_tti", translate("KCP TTI"))
kcp_tti.datatype = "range(10,100)"
kcp_tti:depends("network_type", "kcp")
kcp_uplink = s:taboption("main",Value, "kcp_uplink", translate("KCP uplinkCapacity"))
kcp_uplink.datatype = "range(0,1000)"
kcp_uplink:depends("network_type", "kcp")
kcp_downlink = s:taboption("main",Value, "kcp_downlink", translate("KCP downlinkCapacity"))
kcp_downlink.datatype = "range(0,1000)"
kcp_downlink:depends("network_type", "kcp")
kcp_readbuf = s:taboption("main",Value, "kcp_readbuf", translate("KCP readBufferSize"))
kcp_readbuf.datatype = "range(0,100)"
kcp_readbuf:depends("network_type", "kcp")
kcp_writebuf = s:taboption("main",Value, "kcp_writebuf", translate("KCP writeBufferSize"))
kcp_writebuf.datatype = "range(0,100)"
kcp_writebuf:depends("network_type", "kcp")
kcp_congestion = s:taboption("main",Flag, "kcp_congestion", translate("KCP Congestion"))
kcp_congestion:depends("network_type", "kcp")
-- websocket settings
ws_path = s:taboption("main",Value, "ws_path", translate("WebSocket Path"))
ws_path:depends("network_type", "ws")
ws_headers = s:taboption("main",Value, "ws_headers", translate("WebSocket Header"))
ws_headers:depends("network_type", "ws")
ws_headers.datatype = "host"
-- others
tls = s:taboption("main",Flag, "tls", translate("TLS"))
tls.rmempty = false
tls:depends("use_conf_file", 0)
mux = s:taboption("main",Flag, "mux", translate("Mux"))
mux.rmempty = false
mux:depends("use_conf_file", 0)
s:tab("list", translate("User-defined GFW-List"))
gfwlist = s:taboption("list", TextValue, "conf")
gfwlist.description = translate("<br />!Note: When the domain name is entered and will automatically merge with the online GFW-List. Please manually update the GFW-List list after applying.")
gfwlist.rows = 13
gfwlist.wrap = "off"
gfwlist.cfgvalue = function(self, section)
return NXFS.readfile(conf) or ""
end
gfwlist.write = function(self, section, value)
NXFS.writefile(conf, value:gsub("\r\n", "\n"))
end
local addipconf = "/etc/v2ray/addinip.txt"
s:tab("addip", translate("GFW-List Add-in IP"))
gfwaddin = s:taboption("addip", TextValue, "addipconf")
gfwaddin.description = translate("<br />!Note: IP add-in to GFW-List. Such as Telegram Messenger")
gfwaddin.rows = 13
gfwaddin.wrap = "off"
gfwaddin.cfgvalue = function(self, section)
return NXFS.readfile(addipconf) or ""
end
gfwaddin.write = function(self, section, value)
NXFS.writefile(addipconf, value:gsub("\r\n", "\n"))
end
s:tab("status", translate("Status and Tools"))
s:taboption("status", DummyValue,"opennewwindow" ,
translate("<input type=\"button\" class=\"cbi-button cbi-button-apply\" value=\"IP111.CN\" onclick=\"window.open('http://www.ip111.cn/')\" />"))
s:tab("watchdog", translate("Watchdog Log"))
log = s:taboption("watchdog", TextValue, "sylogtext")
log.template = "cbi/tvalue"
log.rows = 13
log.wrap = "off"
log.readonly="readonly"
function log.cfgvalue(self, section)
SYS.exec("[ -f /tmp/v2ray_watchdog.log ] && sed '1!G;h;$!d' /tmp/v2ray_watchdog.log > /tmp/v2raypro.log")
return nixio.fs.readfile(dog)
end
function log.write(self, section, value)
value = value:gsub("\r\n?", "\n")
nixio.fs.writefile(dog, value)
end
t=m:section(TypedSection,"acl_rule",translate("<strong>Client Proxy Mode Settings</strong>"),
translate("Proxy mode settings can be set to specific LAN clients ( <font color=blue> No Proxy, Global Proxy, Game Mode</font>) . Does not need to be set by default."))
t.template="cbi/tblsection"
t.sortable=true
t.anonymous=true
t.addremove=true
e=t:option(Value,"ipaddr",translate("IP Address"))
e.width="40%"
e.datatype="ip4addr"
e.placeholder="0.0.0.0/0"
luci.ip.neighbors({ family = 4 }, function(entry)
if entry.reachable then
e:value(entry.dest:string())
end
end)
e=t:option(ListValue,"filter_mode",translate("Proxy Mode"))
e.width="40%"
e.default="disable"
e.rmempty=false
e:value("disable",translate("No Proxy"))
e:value("global",translate("Global Proxy"))
e:value("game",translate("Game Mode"))
-- ---------------------------------------------------
local apply = luci.http.formvalue("cbi.apply")
if apply then
os.execute("chmod +x /etc/init.d/v2raypro &")
os.execute("/etc/init.d/v2raypro restart >/dev/null 2>&1 &")
end
return m

View File

@ -0,0 +1,6 @@
<%+cbi/valueheader%>
<label class="cbi-value-title" style="display:inline-block; width: 180px" for="ulfile"><%:Choose local file:%></label>
<input class="cbi-input-file" style="width: 400px" type="file" id="ulfile" name="ulfile" />
<%+cbi/valuefooter%>

View File

@ -0,0 +1,116 @@
msgid "<strong><font color=\"green\">V2Ray is Running</font></strong>"
msgstr "<strong><font color=\"green\">V2Ray 正在运行</font></strong>"
msgid "<strong><font color=\"red\">V2Ray is Not Running</font></strong>"
msgstr "<strong><font color=\"red\">V2Ray 没有运行</font></strong>"
msgid "V2Ray Transparent Proxy"
msgstr "V2Ray 透明代理"
msgid "A fast secure tunnel proxy that help you get through firewalls on your router"
msgstr "一个快速安全隧道代理,帮助您穿过防火墙"
msgid "Base Setting"
msgstr "基本设置"
msgid "Proxy Mode"
msgstr "代理模式"
msgid "Base on GFW-List Auto Proxy Mode(Recommend)"
msgstr "基于GFW-List自动代理(推荐)"
msgid "Bypassing China Manland IP Mode(Be caution when using P2P download)"
msgstr "绕过中国大陆IP地址(P2P 下载慎用!)"
msgid "Global Mode"
msgstr "全局代理"
msgid "Overseas users watch China video website Mode"
msgstr "海外用户回国看视频"
msgid "Auto Update GFW-List"
msgstr "自动更新GFW-List"
msgid "Manually force update GFW-List"
msgstr "手动强制更新GFW-List"
msgid "DNS uses TCP"
msgstr "启用DNS TCP防污染"
msgid "Through the server transfer mode inquires DNS pollution prevention (Safer and recommended)"
msgstr "往国外的DNS请求将通过服务器中转发出更安全推荐"
msgid "Server Setting"
msgstr "服务器设置"
msgid "Server Address"
msgstr "服务器地址(支持域名)"
msgid "Server Port"
msgstr "服务器端口"
msgid "ID"
msgstr "ID"
msgid "Alter ID"
msgstr "额外ID"
msgid "Security"
msgstr "加密方式"
msgid "Network Type"
msgstr "传输协议"
msgid "User-defined GFW-List"
msgstr "用户自定义GFW-List"
msgid "<br />!Note: When the domain name is entered and will automatically merge with the online GFW-List. Please manually update the GFW-List list after applying."
msgstr "用户自定义GFW-List将会和自动更新的自动合并。如果要新加入域名马上生效请应用后点击手动强制更新GFW-List"
msgid "Status and Tools"
msgstr "状态与工具"
msgid "Watchdog Log"
msgstr "守护日志"
msgid "<strong>Client Proxy Mode Settings</strong>"
msgstr "<strong>客户端代理模式设置</strong>"
msgid "Proxy mode settings can be set to specific LAN clients ( <font color=blue> No Proxy, Global Proxy, Game Mode</font>) . Does not need to be set by default."
msgstr "可以为局域网客户端分别设置不同的代理模式 ( <font color=blue> 不代理, 全局代理, 游戏模式</font>).默认无需设置"
msgid "GFW-List Add-in IP"
msgstr "GFW-List附加IP"
msgid "<br />!Note: IP add-in to GFW-List. Such as Telegram Messenger"
msgstr "<br />!注意有些应用使用IP而不是域名例如 Telegram Messenger 您需要把IP地址加入这里"
msgid "No Proxy"
msgstr "不代理"
msgid "Global Proxy"
msgstr "全局代理"
msgid "Game Mode"
msgstr "游戏模式"
msgid "Config File Type"
msgstr "配置文件类型"
msgid "Use Config File"
msgstr "使用配置文件"
msgid "Warning: Can't find v2ctl. You can only choose Protobuf."
msgstr "注意:没有找到 v2ctl 可执行程序。你只能选择使用 Protobuf."
msgid "If you choose to upload a new file, please do not modify and this configuration will be overwritten automatically."
msgstr "如果你在下方选择了上传新的配置文件,那你不需要改动这个框框里的内容。上传完成后将会自动填充。"
msgid "Create upload file error."
msgstr "上传文件失败。"
msgid "File saved to"
msgstr "文件已保存到"
msgid "No specify upload file."
msgstr "未指定上传文件"

View File

@ -0,0 +1,31 @@
config v2ray 'v2ray'
option gfwlist 'china-banned'
option enabled '0'
option proxy_mode 'M'
option safe_dns_tcp '1'
option cron_mode '1'
option address 'test.TEST'
option port '443'
option id '00755892-0921-4433-bd92-04242abd92af'
option alterId '64'
option security 'aes-128-gcm'
option network_type 'ws'
option tls '1'
option mux '1'
option tcp_obfs 'none'
list tcp_path '/'
list tcp_host 'www.baidu.com'
option kcp_obfs 'none'
option kcp_mtu '1350'
option kcp_tti '20'
option kcp_uplink '5'
option kcp_downlink '20'
option kcp_congestion '1'
option kcp_readbuf '2'
option kcp_writebuf '2'
option ws_path '/v2ray'
option ws_headers 'www.baidu.com'

View File

@ -0,0 +1,379 @@
#!/bin/sh /etc/rc.common
START=99
# local port is defined in $V2_CONF_GENERATE_LUA
SS_REDIR_PORT=7070
SS_REDIR_PIDFILE=/var/run/v2ray-go.pid
PDNSD_LOCAL_PORT=7453
SSRCONF=/etc/v2ray/config.json
V2_CONF_GENERATE_LUA=/etc/v2ray/gen_config.lua
CRON_FILE=/etc/crontabs/root
CONFIG=v2ray
V2RAY_EXEC_PATH=/usr/bin/v2ray/v2ray
# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# $covered_subnets, $local_addresses are not required
covered_subnets=`uci get v2ray.@v2ray[0].covered_subnets 2>/dev/null`
local_addresses=`uci get v2ray.@v2ray[0].local_addresses 2>/dev/null`
# Get LAN settings as default parameters
[ -f /lib/functions/network.sh ] && . /lib/functions/network.sh
[ -z "$covered_subnets" ] && network_get_subnet covered_subnets lan
[ -z "$local_addresses" ] && network_get_ipaddr local_addresses lan
vt_np_ipset="china" # Must be global variable
__gfwlist_by_mode()
{
case "$1" in
V) echo unblock-youku;;
*) echo china-banned;;
esac
}
# -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
start()
{
local vt_enabled=`uci get v2ray.@v2ray[0].enabled 2>/dev/null`
local vt_safe_dns=`uci get v2ray.@v2ray[0].safe_dns 2>/dev/null`
local vt_safe_dns_port=`uci get v2ray.@v2ray[0].safe_dns_port 2>/dev/null`
local vt_safe_dns_tcp=`uci get v2ray.@v2ray[0].safe_dns_tcp 2>/dev/null`
local vt_proxy_mode=`uci get v2ray.@v2ray[0].proxy_mode`
local vt_server_addr='uci get v2ray.@v2ray[0].address'
local cron_mode=`uci get v2ray.@v2ray[0].cron_mode 2>/dev/null`
local vt_gfwlist=`__gfwlist_by_mode $vt_proxy_mode`
local use_conf_file=`uci get v2ray.@v2ray[0].use_conf_file 2>/dev/null`
local conf_file_path=`uci get v2ray.@v2ray[0].conf_file_path 2>/dev/null`
local conf_file_type=`uci get v2ray.@v2ray[0].conf_file_type 2>/dev/null`
[ -f /etc/init.d/pdnsd ] && /etc/init.d/pdnsd disable 2>/dev/null
# -----------------------------------------------------------------
if [ "$vt_enabled" = 0 ]; then
echo "WARNING: V2Ray is disabled."
return 1
fi
[ -z "$vt_proxy_mode" ] && vt_proxy_mode=M
[ -z "$vt_method" ] && vt_method=table
[ -z "$vt_timeout" ] && vt_timeout=60
case "$vt_proxy_mode" in
M|S|G)
[ -z "$vt_safe_dns" ] && vt_safe_dns="8.8.8.8"
[ -z "$vt_safe_dns_tcp" ] && vt_safe_dns_tcp=1
;;
esac
[ -z "$vt_safe_dns_port" ] && vt_safe_dns_port=53
# -----------------------------------------------------------------
###### v2ray ######
if [ "$use_conf_file" = 0 ]; then
/usr/bin/lua $V2_CONF_GENERATE_LUA $CONFIG $SSRCONF
$V2RAY_EXEC_PATH -config=$SSRCONF &
else
$V2RAY_EXEC_PATH -config=$conf_file_path -format=$conf_file_type &
fi
sleep 3
if pidof v2ray>/dev/null; then
echo "V2Ray started"
else
return 1
fi
# IPv4 firewall rules
add_rule
# -----------------------------------------------------------------
mkdir -p /var/etc/dnsmasq-go.d
###### Anti-pollution configuration ######
if [ -n "$vt_safe_dns" ]; then
if [ "$vt_safe_dns_tcp" = 1 ]; then
start_pdnsd "$vt_safe_dns"
awk -vs="127.0.0.1#$PDNSD_LOCAL_PORT" '!/^$/&&!/^#/{printf("server=/%s/%s\n",$0,s)}' \
/etc/gfwlist/$vt_gfwlist > /var/etc/dnsmasq-go.d/01-pollution.conf
else
awk -vs="$vt_safe_dns#$vt_safe_dns_port" '!/^$/&&!/^#/{printf("server=/%s/%s\n",$0,s)}' \
/etc/gfwlist/$vt_gfwlist > /var/etc/dnsmasq-go.d/01-pollution.conf
fi
else
echo "WARNING: Not using secure DNS, DNS resolution might be polluted if you are in China."
fi
###### dnsmasq-to-ipset configuration ######
case "$vt_proxy_mode" in
M|V)
awk '!/^$/&&!/^#/{printf("ipset=/%s/'"$vt_gfwlist"'\n",$0)}' \
/etc/gfwlist/$vt_gfwlist > /var/etc/dnsmasq-go.d/02-ipset.conf
;;
esac
# -----------------------------------------------------------------
###### Restart main 'dnsmasq' service if needed ######
if ls /var/etc/dnsmasq-go.d/* >/dev/null 2>&1; then
mkdir -p /tmp/dnsmasq.d
cat > /tmp/dnsmasq.d/dnsmasq-go.conf <<EOF
conf-dir=/var/etc/dnsmasq-go.d
EOF
/etc/init.d/dnsmasq restart
fi
add_cron
}
stop()
{
# -----------------------------------------------------------------
rm -rf /var/etc/dnsmasq-go.d
if [ -f /tmp/dnsmasq.d/dnsmasq-go.conf ]; then
rm -f /tmp/dnsmasq.d/dnsmasq-go.conf
/etc/init.d/dnsmasq restart
fi
stop_pdnsd
# --STOP IPv4 firewall---------------------------------------------------------------
del_rule
# -----------------------------------------------------------------
if [ -f $SS_REDIR_PIDFILE ]; then
kill -9 `cat $SS_REDIR_PIDFILE`
rm -f $SS_REDIR_PIDFILE
fi
killall -9 v2ray 2>/dev/null
del_cron
}
restart()
{
KEEP_GFWLIST=Y
stop
start
}
reload()
{
local vt_enabled=`uci get v2ray.@v2ray[0].enabled 2>/dev/null`
local vt_server_addr=`uci get v2ray.@v2ray[0].address`
local vt_safe_dns=`uci get v2ray.@v2ray[0].safe_dns 2>/dev/null`
local vt_safe_dns_port=`uci get v2ray.@v2ray[0].safe_dns_port 2>/dev/null`
local vt_safe_dns_tcp=`uci get v2ray.@v2ray[0].safe_dns_tcp 2>/dev/null`
local vt_proxy_mode=`uci get v2ray.@v2ray[0].proxy_mode`
local vt_gfwlist=`__gfwlist_by_mode $vt_proxy_mode`
KEEP_GFWLIST=Y
del_rule
add_rule
if [ "$vt_safe_dns_tcp" = 1 ]; then
stop_pdnsd
start_pdnsd
fi
}
# $1: upstream DNS server
start_pdnsd()
{
local safe_dns="$1"
local tcp_dns_list="208.67.222.222, 208.67.220.220"
[ -n "$safe_dns" ] && tcp_dns_list="$safe_dns,$tcp_dns_list"
#killall -9 pdnsd 2>/dev/null && sleep 1
kill -9 $(cat /var/run/pdnsd.pid) >/dev/null 2>&1
mkdir -p /var/etc /var/pdnsd
if ! test -f "/var/pdnsd/pdnsd.cache"; then
dd if=/dev/zero of="/var/pdnsd/pdnsd.cache" bs=1 count=4 2> /dev/null
chown -R nobody.nogroup /var/pdnsd
fi
cat > /var/etc/pdnsd.conf <<EOF
global {
perm_cache=10240;
cache_dir="/var/pdnsd";
pid_file = /var/run/pdnsd.pid;
run_as="nobody";
server_ip = 127.0.0.1;
server_port = $PDNSD_LOCAL_PORT;
status_ctl = on;
query_method = tcp_only;
min_ttl=1h;
max_ttl=1w;
timeout=10;
neg_domain_pol=on;
proc_limit=2;
procq_limit=8;
}
server {
label= "fwxxx";
ip = $tcp_dns_list;
port = 53;
timeout=6;
uptest=none;
interval=10m;
purge_cache=off;
}
EOF
/usr/sbin/pdnsd -c /var/etc/pdnsd.conf -d
# Access TCP DNS server through V2Ray tunnel
if iptables -t nat -N pdnsd_output; then
iptables -t nat -A pdnsd_output -m set --match-set $vt_np_ipset dst -j RETURN
iptables -t nat -A pdnsd_output -p tcp -j REDIRECT --to $SS_REDIR_PORT
fi
iptables -t nat -I OUTPUT -p tcp --dport 53 -j pdnsd_output
}
stop_pdnsd()
{
if iptables -t nat -F pdnsd_output 2>/dev/null; then
while iptables -t nat -D OUTPUT -p tcp --dport 53 -j pdnsd_output 2>/dev/null; do :; done
iptables -t nat -X pdnsd_output
fi
killall -9 pdnsd 2>/dev/null
rm -rf /var/pdnsd
rm -f /var/etc/pdnsd.conf
}
add_cron()
{
sed -i '/up-gfwlist.sh/d' $CRON_FILE
sed -i '/v2ray_watchdog.log/d' $CRON_FILE
if [ $cron_mode -eq 1 ]; then
echo '0 5 * * * /etc/v2ray/up-gfwlist.sh > /tmp/gfwupdate.log 2>&1' >> $CRON_FILE
fi
echo '0 */1 * * * /etc/v2ray/v2ray-watchdog >> /tmp/v2ray_watchdog.log 2>&1' >> $CRON_FILE
echo '0 1 * * 0 echo "" > /tmp/v2ray_watchdog.log' >> $CRON_FILE
crontab $CRON_FILE
}
del_cron()
{
sed -i '/up-gfwlist.sh/d' $CRON_FILE
sed -i '/v2ray_watchdog.log/d' $CRON_FILE
/etc/init.d/cron restart
}
uci_get_by_name() {
local ret=$(uci get $CONFIG.$1.$2 2>/dev/null)
echo ${ret:=$3}
}
uci_get_by_type() {
local index=0
if [ -n $4 ]; then
index=$4
fi
local ret=$(uci get $CONFIG.@$1[$index].$2 2>/dev/null)
echo ${ret:=$3}
}
is_ipv6_address()
{
echo "$1" | grep -q ":"
}
add_rule()
{
iptables -t nat -N v2ray_pre
iptables -t nat -F v2ray_pre
iptables -t nat -A v2ray_pre -m set --match-set local dst -j RETURN || {
iptables -t nat -A v2ray_pre -d 10.0.0.0/8 -j RETURN
iptables -t nat -A v2ray_pre -d 127.0.0.0/8 -j RETURN
iptables -t nat -A v2ray_pre -d 172.16.0.0/12 -j RETURN
iptables -t nat -A v2ray_pre -d 192.168.0.0/16 -j RETURN
iptables -t nat -A v2ray_pre -d 127.0.0.0/8 -j RETURN
iptables -t nat -A v2ray_pre -d 224.0.0.0/3 -j RETURN
}
iptables -t nat -A v2ray_pre -d $vt_server_addr -j RETURN
iptables -N gameboost -t mangle
ipset -! create gameuser hash:ip maxelem 65536 2>/dev/null
/usr/bin/ip rule add fwmark 0x01/0x01 table 100
/usr/bin/ip route add local 0.0.0.0/0 dev lo table 100
iptables -t mangle -A gameboost -p udp -m set --match-set local dst -j RETURN
iptables -t mangle -A gameboost -p udp -m set --match-set china dst -j RETURN
iptables -t mangle -A gameboost -p udp --dport 53 -j RETURN
iptables -t mangle -A gameboost -p udp -j TPROXY --on-port 7070 --tproxy-mark 0x01/0x01
iptables -t mangle -A PREROUTING -m set --match-set gameuser src -j gameboost
for i in $(seq 0 100)
do
local ip=$(uci_get_by_type acl_rule ipaddr '' $i)
local mode=$(uci_get_by_type acl_rule filter_mode '' $i)
case "$mode" in
disable)
iptables -t nat -A v2ray_pre -s $ip -j RETURN
;;
global)
iptables -t nat -A v2ray_pre -s $ip -p tcp -j REDIRECT --to $SS_REDIR_PORT
iptables -t nat -A v2ray_pre -s $ip -j RETURN
;;
game)
iptables -t nat -A v2ray_pre -p tcp -s $ip -m set ! --match-set china dst -j REDIRECT --to $SS_REDIR_PORT
ipset -! add gameuser $ip
;;
esac
done
case "$vt_proxy_mode" in
G) : ;;
S)
iptables -t nat -A v2ray_pre -m set --match-set $vt_np_ipset dst -j RETURN
iptables -t nat -I OUTPUT -p tcp -m multiport --dports 80,443 -m set ! --match-set $vt_np_ipset dst -j REDIRECT --to $SS_REDIR_PORT
;;
M)
ipset -! create $vt_gfwlist hash:ip maxelem 65536 2>/dev/null
awk '!/^$/&&!/^#/{printf("add vt_gfwlist %s'" "'\n",$0)}' /etc/v2ray/addinip.txt > /tmp/addinip.ipset
sed -i "s/vt_gfwlist/$vt_gfwlist/g" /tmp/addinip.ipset
ipset -! restore < /tmp/addinip.ipset
iptables -t nat -A v2ray_pre -m set ! --match-set $vt_gfwlist dst -j RETURN
iptables -t nat -A v2ray_pre -m set --match-set $vt_np_ipset dst -j RETURN
iptables -t nat -I OUTPUT -p tcp -m multiport --dports 80,443 -m set --match-set $vt_gfwlist dst -j REDIRECT --to $SS_REDIR_PORT
;;
V)
vt_np_ipset=""
ipset -! create $vt_gfwlist hash:ip maxelem 65536 2>/dev/null
iptables -t nat -A v2ray_pre -m set ! --match-set $vt_gfwlist dst -j RETURN
;;
esac
local subnet
for subnet in $covered_subnets; do
iptables -t nat -A v2ray_pre -s $subnet -p tcp -j REDIRECT --to $SS_REDIR_PORT
done
iptables -t nat -I PREROUTING -p tcp -j v2ray_pre
}
del_rule()
{
if iptables -t nat -F v2ray_pre 2>/dev/null; then
while iptables -t nat -D PREROUTING -p tcp -j v2ray_pre 2>/dev/null; do :; done
iptables -t nat -X v2ray_pre 2>/dev/null
fi
iptables -t nat -D OUTPUT -p tcp -m multiport --dports 80,443 -m set --match-set china-banned dst -j REDIRECT --to $SS_REDIR_PORT 2>/dev/null
iptables -t nat -D OUTPUT -p tcp -m multiport --dports 80,443 -m set ! --match-set $vt_np_ipset dst -j REDIRECT --to $SS_REDIR_PORT 2>/dev/null
/usr/bin/ip rule del fwmark 0x01/0x01 table 100
/usr/bin/ip route del local 0.0.0.0/0 dev lo table 100
if iptables -t mangle -F gameboost 2>/dev/null; then
while iptables -t mangle -D PREROUTING -m set --match-set gameuser src -j gameboost 2>/dev/null; do :; done
iptables -t mangle -X gameboost 2>/dev/null
fi
ipset destroy gameuser 2>/dev/null
# -----------------------------------------------------------------
[ "$KEEP_GFWLIST" = Y ] || ipset destroy "$vt_gfwlist" 2>/dev/null
}

View File

@ -0,0 +1,16 @@
#!/bin/sh
uci -q batch <<-EOF >/dev/null
delete firewall.v2ray
set firewall.v2ray=include
set firewall.v2ray.type=script
set firewall.v2ray.path=/etc/v2ray.include
set firewall.v2ray.reload=1
commit firewall
EOF
/etc/init.d/v2raypro stop
/etc/init.d/v2raypro disable
rm -f /tmp/luci-indexcache
exit 0

View File

@ -0,0 +1,11 @@
#!/bin/sh
ssr_enable=$(uci get v2ray.@v2ray[0].enabled 2>/dev/null)
if [ $ssr_enable -eq 1 ]; then
if pidof v2ray>/dev/null; then
/etc/init.d/v2raypro reload
else
/etc/init.d/v2raypro restart
fi
fi

View File

@ -0,0 +1,7 @@
149.154.160.0/20
149.154.164.0/22
149.154.168.0/21
67.198.55.0/24
91.108.4.0/22
91.108.56.0/22
109.239.140.0/24

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
#!/bin/sh -e
generate_china_banned()
{
if [ ! -f /tmp/gfwlist.txt ]; then
wget-ssl --no-check-certificate https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt -O /tmp/gfwlist.b64 >&2
cat /tmp/gfwlist.b64 | base64 -d > /tmp/gfwlist.txt
rm -f /tmp/gfwlist.b64
fi
cat /tmp/gfwlist.txt | sort -u |
sed 's#!.\+##; s#|##g; s#@##g; s#http:\/\/##; s#https:\/\/##;' |
sed '/\*/d; /apple\.com/d; /sina\.cn/d; /sina\.com\.cn/d; /baidu\.com/d; /byr\.cn/d; /jlike\.com/d; /weibo\.com/d; /zhongsou\.com/d; /youdao\.com/d; /sogou\.com/d; /so\.com/d; /soso\.com/d; /aliyun\.com/d; /taobao\.com/d; /jd\.com/d; /qq\.com/d' |
sed '/^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$/d' |
grep '^[0-9a-zA-Z\.-]\+$' | grep '\.' | sed 's#^\.\+##' | sort -u |
awk '
BEGIN { prev = "________"; } {
cur = $0;
if (index(cur, prev) == 1 && substr(cur, 1 + length(prev) ,1) == ".") {
} else {
print cur;
prev = cur;
}
}' | sort -u
}
generate_china_banned

View File

@ -0,0 +1,169 @@
--[[
Auto generate config for Project V
Author: @libc0607
]]--
local conf_path, json_path = ...
conf_path = conf_path or "v2ray"
json_path = json_path or "/etc/v2ray/config.json"
local local_listen_port = 7070
local cjson = require "cjson.safe"
local ucursor = require "luci.model.uci".cursor()
local lip = require "luci.ip"
local v2ray_stream_mode = ucursor:get(conf_path, "v2ray", "network_type") -- tcp/kcp/ws
function v2ray_get_conf_list(op)
local t = {}
for k, v in pairs(ucursor:get_list(conf_path, 'v2ray', op)) do
table.insert(t, v)
end
return t
end
function check_addr_type(addr)
local ip = luci.ip.new(addr, 32)
if ip == nil then
return "domain"
elseif ip:is4() then
return "ipv4"
elseif ip:is6() then
return "ipv6"
end
end
function get_ip_list_by_domain(domain)
local domain_list = {}
local cmd = io.popen("nslookup " .. domain .. " |grep Address | awk {'print $3'}")
for cmd_line in cmd:lines() do
if check_addr_type(cmd_line) == "ipv4" then
table.insert(domain_list, cmd_line)
elseif check_addr_type(cmd_line) == "ipv6" then
table.insert(domain_list, cmd_line)
end
end
return domain_list
end
local v2ray = {
log = {
access = "",
error = "",
loglevel = "none"
},
inbound = {
protocol = "dokodemo-door",
port = local_listen_port,
domainOverride = {"tls", "http"},
address = "",
settings = {
network = "tcp,udp",
timeout = 30,
followRedirect = true
},
},
outbound = {
protocol = "vmess",
settings = {
vnext = {
[1] = {
address = ucursor:get(conf_path, "v2ray", "address"),
port = tonumber(ucursor:get(conf_path, "v2ray", "port")),
users = {
[1] = {
id = ucursor:get(conf_path, "v2ray", "id"),
alterId = tonumber(ucursor:get(conf_path, "v2ray", "alterId")),
security = ucursor:get(conf_path, "v2ray", "security")
},
},
},
},
},
streamSettings = {
network = ucursor:get(conf_path, "v2ray", "network_type"),
security = (ucursor:get(conf_path, "v2ray", "tls") == '1') and "tls" or "none",
tcpSettings = (v2ray_stream_mode == "tcp" and ucursor:get(conf_path, "v2ray", "tcp_obfs") == "http") and {
connectionReuse = true,
header = {
type = ucursor:get(conf_path, "v2ray", "tcp_obfs"),
request = {
version = "1.1",
method = "GET",
path = v2ray_get_conf_list('tcp_path'),
headers = {
Host = v2ray_get_conf_list('tcp_host'),
User_Agent = {
"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.75 Safari/537.36",
"Mozilla/5.0 (iPhone; CPU iPhone OS 10_0_2 like Mac OS X) AppleWebKit/601.1 (KHTML, like Gecko) CriOS/53.0.2785.109 Mobile/14A456 Safari/601.1.46"
},
Accept_Encoding = {"gzip, deflate"},
Connection = {"keep-alive"},
Pragma = "no-cache"
},
},
response = {
version = "1.1",
status = "200",
reason = "OK",
headers = {
Content_Type = {"application/octet-stream","video/mpeg"},
Transfer_Encoding = {"chunked"},
Connection= {"keep-alive"},
Pragma = "no-cache"
},
},
}
} or nil,
kcpSettings = (v2ray_stream_mode == "kcp") and {
mtu = tonumber(ucursor:get(conf_path, "v2ray", "kcp_mtu")),
tti = tonumber(ucursor:get(conf_path, "v2ray", "kcp_tti")),
uplinkCapacity = tonumber(ucursor:get(conf_path, "v2ray", "kcp_uplink")),
downlinkCapacity = tonumber(ucursor:get(conf_path, "v2ray", "kcp_downlink")),
congestion = (ucursor:get(conf_path, "v2ray", "kcp_congestion") == "1") and true or false,
readBufferSize = tonumber(ucursor:get(conf_path, "v2ray", "kcp_readbuf")),
writeBufferSize = tonumber(ucursor:get(conf_path, "v2ray", "kcp_writebuf")),
header = {
type = ucursor:get(conf_path, "v2ray", "kcp_obfs")
}
} or nil,
wsSettings = (v2ray_stream_mode == "ws") and {
connectionReuse = true,
path = ucursor:get(conf_path, "v2ray", "ws_path"),
headers = (ucursor:get(conf_path, "v2ray", "ws_headers") ~= nil) and {
Host = ucursor:get(conf_path, "v2ray", "ws_headers")
} or nil,
} or nil,
},
mux = {
enabled = (ucursor:get(conf_path, "v2ray", "mux") == "1") and true or false
},
},
dns = {
servers = {
"localhost"
},
},
}
-- Generate config json to <json_path>
local json_raw = cjson.encode(v2ray)
local json_file = io.open(json_path, "w+")
io.output(json_file)
io.write(json_raw)
io.close(json_file)
-- change '_' to '-'
local keys_including_minus = {"User_Agent", "Content_Type", "Accept_Encoding", "Transfer_Encoding"}
local keys_corrected = {"User-Agent", "Content-Type", "Accept-Encoding", "Transfer-Encoding"}
for k, v in pairs(keys_including_minus) do
os.execute("sed -i 's/" ..v.. "/" ..keys_corrected[k].. "/g' " .. json_path)
end
-- change "\/" to "/"
os.execute("sed -i 's/\\\\\\//\\//g' ".. json_path)
print("V2ray config generated at " .. json_path)

View File

@ -0,0 +1,20 @@
#!/bin/sh
/etc/v2ray/gen-gfwlist.sh > /tmp/ol-gfw.txt
if [ -s "/tmp/ol-gfw.txt" ];then
sort -u /etc/v2ray/base-gfwlist.txt /tmp/ol-gfw.txt > /tmp/china-banned
if ( ! cmp -s /tmp/china-banned /etc/gfwlist/china-banned );then
if [ -s "/tmp/china-banned" ];then
mv /tmp/china-banned /etc/gfwlist/china-banned
echo "Update GFW-List Done!"
fi
else
echo "GFW-List No Change!"
fi
fi
rm -f /tmp/gfwlist.txt
rm -f /tmp/ol-gfw.txt
/etc/init.d/v2raypro restart

View File

@ -0,0 +1,26 @@
#!/bin/sh
LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
#GOOGLE=$(ping -4 www.gstatic.com -c 1 -w 5| sed '1{s/[^(]*(//;s/).*//;q}')
#iptables -t nat -I OUTPUT -p tcp -d $GOOGLE -j REDIRECT --to-port 7070
#sleep 3
/usr/bin/wget --spider --quiet --tries=1 --timeout=3 www.gstatic.com/generate_204
if [ "$?" == "0" ]; then
echo '['$LOGTIME'] V2Ray No Problem.'
else
/usr/bin/wget --spider --quiet --tries=1 --timeout=3 www.baidu.com
if [ "$?" == "0" ]; then
echo '['$LOGTIME'] Problem decteted, restarting V2Ray...'
/etc/init.d/v2raypro restart
else
echo '['$LOGTIME'] Network Problem. Do nothing.'
fi
fi
#sleep 3
#iptables -t nat -D OUTPUT -p tcp -d $GOOGLE -j REDIRECT --to-port 7070

115
package/lean/v2ray/Makefile Normal file
View File

@ -0,0 +1,115 @@
#
# Copyright (C) 2015-2016 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v3.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=v2ray
PKG_VERSION:=v3.14
#PKG_VERSION:=$(shell wget https://api.github.com/repos/v2ray/v2ray-core/releases/latest -q -O -|grep tag_name|awk {'print $2'}|cut -d '"' -f 2)
#PKG_RELEASE:=$(shell wget https://api.github.com/repos/v2ray/v2ray-core/releases/latest -q -O -|grep published_at|awk {'print $2'}|cut -d '"' -f 2|cut -d 'T' -f 1)
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
ifeq ($(ARCH),x86_64)
PKG_ARCH_V2RAY:=linux-64
endif
ifeq ($(ARCH),mipsel)
PKG_ARCH_V2RAY:=linux-mipsle
endif
ifeq ($(ARCH),mips)
PKG_ARCH_V2RAY:=linux-mips
endif
ifeq ($(ARCH),i386)
PKG_ARCH_V2RAY:=linux-32
endif
ifeq ($(ARCH),arm)
PKG_ARCH_V2RAY:=linux-arm
endif
ifeq ($(ARCH),aarch64)
PKG_ARCH_V2RAY:=linux-arm64
endif
#PKG_SOURCE:=v2ray-$(PKG_ARCH_V2RAY).zip
#PKG_SOURCE_URL:=https://github.com/v2ray/v2ray-core/releases/download/$(PKG_VERSION)
#PKG_SOURCE_SUBDIR:=v2ray-$(PKG_VERSION)-$(V2RAY_PKG_ARCH)
#PKG_CAT:=unzip
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=net
CATEGORY:=Network
TITLE:=V2Ray is a cross-platform proxy software
DEPENDS:=
URL:=https://github.com/v2ray/v2ray-core
endef
define Package/$(PKG_NAME)/config
menu "V2Ray Configuration"
depends on PACKAGE_v2ray
config PACKAGE_V2RAY_INCLUDE_V2RAY
bool "Include v2ray"
default y
config PACKAGE_V2RAY_SOFTFLOAT
bool "Use soft-float binaries (mips/mipsle only)"
depends on PACKAGE_V2RAY_INCLUDE_V2RAY
default n
config PACKAGE_V2RAY_INCLUDE_V2CTL
bool "Include v2ctl"
depends on PACKAGE_V2RAY_INCLUDE_V2RAY
default y
config PACKAGE_V2RAY_INCLUDE_GEOIP
bool "Include geoip.dat"
depends on PACKAGE_V2RAY_INCLUDE_V2CTL
default n
config PACKAGE_V2RAY_INCLUDE_GEOSITE
bool "Include geosite.dat"
depends on PACKAGE_V2RAY_INCLUDE_V2CTL
default n
endmenu
endef
define Package/$(PKG_NAME)/description
V2Ray is a cross-platform proxy software
endef
define Build/Prepare
wget https://github.com/v2ray/v2ray-core/releases/download/$(PKG_VERSION)/v2ray-$(PKG_ARCH_V2RAY).zip -O $(PKG_BUILD_DIR)/v2ray-$(PKG_VERSION)-$(PKG_ARCH_V2RAY).zip
unzip -o $(PKG_BUILD_DIR)/v2ray-$(PKG_VERSION)-$(PKG_ARCH_V2RAY).zip -d $(PKG_BUILD_DIR)
ifdef CONFIG_PACKAGE_V2RAY_SOFTFLOAT
[ -f $(PKG_BUILD_DIR)/v2ray-$(PKG_VERSION)-$(PKG_ARCH_V2RAY)/v2ray_softfloat ] && mv $(PKG_BUILD_DIR)/v2ray-$(PKG_VERSION)-$(PKG_ARCH_V2RAY)/v2ray_softfloat $(PKG_BUILD_DIR)/v2ray-$(PKG_VERSION)-$(PKG_ARCH_V2RAY)/v2ray || echo "Can't find soft-float binary."
[ -f $(PKG_BUILD_DIR)/v2ray-$(PKG_VERSION)-$(PKG_ARCH_V2RAY)/v2ctl_softfloat ] && mv $(PKG_BUILD_DIR)/v2ray-$(PKG_VERSION)-$(PKG_ARCH_V2RAY)/v2ctl_softfloat $(PKG_BUILD_DIR)/v2ray-$(PKG_VERSION)-$(PKG_ARCH_V2RAY)/v2ctl || echo "Can't find soft-float binary."
endif
endef
define Build/Configure
endef
define Build/Compile
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/bin/v2ray
ifdef CONFIG_PACKAGE_V2RAY_INCLUDE_V2RAY
$(INSTALL_BIN) $(PKG_BUILD_DIR)/v2ray-$(PKG_VERSION)-$(PKG_ARCH_V2RAY)/v2ray $(1)/usr/bin/v2ray/
endif
ifdef CONFIG_PACKAGE_V2RAY_INCLUDE_V2CTL
$(INSTALL_BIN) $(PKG_BUILD_DIR)/v2ray-$(PKG_VERSION)-$(PKG_ARCH_V2RAY)/v2ctl $(1)/usr/bin/v2ray/
endif
ifdef CONFIG_PACKAGE_V2RAY_INCLUDE_GEOIP
$(INSTALL_BIN) $(PKG_BUILD_DIR)/v2ray-$(PKG_VERSION)-$(PKG_ARCH_V2RAY)/geoip.dat $(1)/usr/bin/v2ray/
endif
ifdef CONFIG_PACKAGE_V2RAY_INCLUDE_GEOSITE
$(INSTALL_BIN) $(PKG_BUILD_DIR)/v2ray-$(PKG_VERSION)-$(PKG_ARCH_V2RAY)/geosite.dat $(1)/usr/bin/v2ray/
endif
endef
$(eval $(call BuildPackage,$(PKG_NAME)))