diff --git a/package/lienol/luci-app-passwall/Makefile b/package/lienol/luci-app-passwall/Makefile
index e38560b7a4..d3df1e9d81 100644
--- a/package/lienol/luci-app-passwall/Makefile
+++ b/package/lienol/luci-app-passwall/Makefile
@@ -7,8 +7,8 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=3.9
-PKG_RELEASE:=61
-PKG_DATE:=20200919
+PKG_RELEASE:=64
+PKG_DATE:=20200925
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
@@ -93,7 +93,7 @@ define Package/$(PKG_NAME)
+curl +ca-certificates +resolveip +unzip +dnsmasq-full +tcping +libuci-lua \
+ipt2socks \
+ssocks \
- +ssocksd \
+ +microsocks \
+pdnsd-alt \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-redir \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks:shadowsocks-libev-ss-local \
diff --git a/package/lienol/luci-app-passwall/luasrc/controller/passwall.lua b/package/lienol/luci-app-passwall/luasrc/controller/passwall.lua
index fa946cc44f..b09a2a13ca 100644
--- a/package/lienol/luci-app-passwall/luasrc/controller/passwall.lua
+++ b/package/lienol/luci-app-passwall/luasrc/controller/passwall.lua
@@ -3,6 +3,7 @@ module("luci.controller.passwall", package.seeall)
local appname = "passwall"
local ucic = luci.model.uci.cursor()
local http = require "luci.http"
+local util = require "luci.util"
local kcptun = require "luci.model.cbi.passwall.api.kcptun"
local brook = require "luci.model.cbi.passwall.api.brook"
local v2ray = require "luci.model.cbi.passwall.api.v2ray"
@@ -47,6 +48,7 @@ function index()
entry({"admin", "services", appname, "link_load_temp"}, call("link_load_temp")).leaf = true
entry({"admin", "services", appname, "link_clear_temp"}, call("link_clear_temp")).leaf = true
entry({"admin", "services", appname, "link_add_node"}, call("link_add_node")).leaf = true
+ entry({"admin", "services", appname, "get_now_use_node"}, call("get_now_use_node")).leaf = true
entry({"admin", "services", appname, "get_log"}, call("get_log")).leaf = true
entry({"admin", "services", appname, "clear_log"}, call("clear_log")).leaf = true
entry({"admin", "services", appname, "status"}, call("status")).leaf = true
@@ -124,6 +126,28 @@ function link_add_node()
luci.sys.call("lua /usr/share/passwall/subscribe.lua add log")
end
+function get_now_use_node()
+ local e = {}
+ local tcp_node_num = ucic:get(appname, "@global_other[0]", "tcp_node_num") or 1
+ e.tcp = tonumber(tcp_node_num)
+ for i = 1, tcp_node_num, 1 do
+ local data, code, msg = nixio.fs.readfile("/var/etc/passwall/id/TCP_" .. i)
+ if data then
+ e["TCP" .. i] = util.trim(data)
+ end
+ end
+ local udp_node_num = ucic:get(appname, "@global_other[0]", "udp_node_num") or 1
+ e.udp = tonumber(udp_node_num)
+ for i = 1, udp_node_num, 1 do
+ local data, code, msg = nixio.fs.readfile("/var/etc/passwall/id/UDP_" .. i)
+ if data then
+ e["UDP" .. i] = util.trim(data)
+ end
+ end
+ luci.http.prepare_content("application/json")
+ luci.http.write_json(e)
+end
+
function get_log()
-- luci.sys.exec("[ -f /var/log/passwall.log ] && sed '1!G;h;$!d' /var/log/passwall.log > /var/log/passwall_show.log")
luci.http.write(luci.sys.exec("[ -f '/var/log/passwall.log' ] && cat /var/log/passwall.log"))
diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua
index 436c072888..5e62560d80 100644
--- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua
+++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua
@@ -45,6 +45,28 @@ uci:foreach(appname, "socks", function(s)
end
end)
+local doh_validate = function(self, value, t)
+ if value ~= "" then
+ local flag = 0
+ local util = require "luci.util"
+ local val = util.split(value, ",")
+ local url = val[1]
+ val[1] = nil
+ for i = 1, #val do
+ local v = val[i]
+ if v then
+ if not datatypes.ipmask4(v) then
+ flag = 1
+ end
+ end
+ end
+ if flag == 0 then
+ return value
+ end
+ end
+ return nil, translate("DoH request address") .. " " .. translate("Format must be:") .. " URL,IP"
+end
+
m = Map(appname)
local status = m:get("@global_other[0]", "status") or ""
if status:find("big_icon") then
@@ -143,10 +165,10 @@ o:value("180.76.76.76", "180.76.76.76 (" .. translate("Baidu") .. "DNS)")
---- DoH
o = s:taboption("DNS", Value, "up_china_dns_doh", translate("DoH request address"))
-o.description = translate("When custom, Please follow the format strictly:") .. "
" .. "https://dns.alidns.com/dns-query,223.5.5.5,223.6.6.6
" .. "https://doh.pub/dns-query,119.29.29.29"
o:value("https://dns.alidns.com/dns-query,223.5.5.5,223.6.6.6", "AliDNS")
o:value("https://doh.pub/dns-query,119.29.29.29,119.28.28.28", "DNSPod")
o.default = "https://dns.alidns.com/dns-query,223.5.5.5,223.6.6.6"
+o.validate = doh_validate
o:depends("up_china_dns", "https-dns-proxy")
---- DNS Forward Mode
@@ -169,6 +191,13 @@ o:value("custom", translate("Custom DNS"))
---- Custom DNS
o = s:taboption("DNS", Value, "custom_dns", translate("Custom DNS"))
o.default = "127.0.0.1#5353"
+o.validate = function(self, value, t)
+ local v = string.gsub(value, "#", ":")
+ if not datatypes.ipaddrport(v) then
+ return nil, translate("Custom DNS") .. " " .. translate("Not valid IP format, please re-enter!")
+ end
+ return value
+end
o:depends({dns_mode = "custom"})
o = s:taboption("DNS", ListValue, "up_trust_pdnsd_dns", translate("Resolver For The List Proxied"))
@@ -185,12 +214,17 @@ o:depends("dns_mode", "https-dns-proxy")
o = s:taboption("DNS", Value, "socks_server", translate("Socks Server"), translate("Make sure socks service is available on this address."))
for k, v in pairs(socks_table) do o:value(v.id, v.remarks) end
+o.validate = function(self, value, t)
+ if not datatypes.ipaddrport(value) then
+ return nil, translate("Socks Server") .. " " .. translate("Not valid IP format, please re-enter!")
+ end
+ return value
+end
o:depends({dns_mode = "dns2socks"})
o:depends({dns_mode = "https-dns-proxy", up_trust_doh_dns = "socks"})
---- DoH
o = s:taboption("DNS", Value, "up_trust_doh", translate("DoH request address"))
-o.description = translate("When custom, Please follow the format strictly:") .. "
" .. "https://dns.google/dns-query,8.8.8.8,8.8.4.4
" .. "https://doh.opendns.com/dns-query,208.67.222.222"
o:value("https://dns.adguard.com/dns-query,176.103.130.130,176.103.130.131", "AdGuard")
o:value("https://cloudflare-dns.com/dns-query,1.1.1.1,1.0.0.1", "Cloudflare")
o:value("https://security.cloudflare-dns.com/dns-query,1.1.1.2,1.0.0.2", "Cloudflare-Security")
@@ -200,6 +234,7 @@ o:value("https://doh.libredns.gr/dns-query,116.202.176.26", "LibreDNS")
o:value("https://doh.libredns.gr/ads,116.202.176.26", "LibreDNS (No Ads)")
o:value("https://dns.quad9.net/dns-query,9.9.9.9,149.112.112.112", "Quad9-Recommended")
o.default = "https://dns.google/dns-query,8.8.8.8,8.8.4.4"
+o.validate = doh_validate
o:depends({dns_mode = "https-dns-proxy"})
---- DNS Forward
diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/app.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/app.lua
index 7ae901f73f..e71b76c946 100644
--- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/app.lua
+++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/app.lua
@@ -69,16 +69,15 @@ local function start()
local udp_forward = 1
local type = user.type or ""
if type == "Socks" then
- local port = user.port
+ local auth = ""
local username = user.username
local password = user.password
- if username and password then
- local auth_file = CONFIG_PATH .. "/" .. id .. ".auth"
- cmd(string.format('echo %s:%s > %s', username, password, auth_file))
- bin = ln_start("/usr/bin/ssocksd", "ssocksd_" .. id, "-p " .. port .. " -a " .. auth_file)
- else
- bin = ln_start("/usr/bin/ssocksd", "ssocksd_" .. id, "-p " .. port)
+ if username and username ~= "" and password and password ~= "" then
+ username = "-u " .. username
+ password = "-P " .. password
+ auth = username .. " " .. password
end
+ bin = ln_start("/usr/bin/microsocks", "microsocks_" .. id, string.format("-i :: -p %s %s", port, auth))
elseif type == "SS" or type == "SSR" then
config = require("luci.model.cbi.passwall.server.api.shadowsocks").gen_config(user)
local udp_param = ""
diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/user.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/user.lua
index 33cb49013f..32d9a0a61a 100644
--- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/user.lua
+++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/user.lua
@@ -69,7 +69,7 @@ remarks.default = translate("Remarks")
remarks.rmempty = false
type = s:option(ListValue, "type", translate("Type"))
-if api.is_finded("ssocksd") then
+if api.is_finded("microsocks") then
type:value("Socks", translate("Socks"))
end
if api.is_finded("ss-server") then
@@ -125,12 +125,28 @@ port.datatype = "port"
port.rmempty = false
username = s:option(Value, "username", translate("Username"))
+username.validate = function(self, value, t)
+ if value then
+ if not password:formvalue(t) or password:formvalue(t) == "" then
+ return nil, translate("Username and Password must be used together!")
+ end
+ end
+ return value
+end
username:depends("protocol", "http")
username:depends("protocol", "socks")
username:depends("type", "Socks")
password = s:option(Value, "password", translate("Password"))
password.password = true
+password.validate = function(self, value, t)
+ if value then
+ if (protocol:formvalue(t) == "http" or protocol:formvalue(t) == "socks" or type:formvalue(t) == "Socks") and (not username:formvalue(t) or username:formvalue(t) == "") then
+ return nil, translate("Username and Password must be used together!")
+ end
+ end
+ return value
+end
password:depends("type", "Socks")
password:depends("type", "SS")
password:depends("type", "SSR")
diff --git a/package/lienol/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm b/package/lienol/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm
index 8e431f7967..2545d28266 100644
--- a/package/lienol/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm
+++ b/package/lienol/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm
@@ -34,6 +34,11 @@ table td, .table .td {
._select {
background: #dad8d8;
}
+
+._now_use {
+ background: #94e1ff;
+}
+
.ping a:hover{
text-decoration : underline;
}
@@ -214,6 +219,36 @@ table td, .table .td {
}
}
+ //获取当前使用的节点
+ function get_now_use_node() {
+ XHR.get('<%=dsp.build_url("admin/services/passwall/get_now_use_node")%>', null,
+ function(x, result) {
+ for (var i = 1; i <= result.udp; i++) {
+ var id = result["UDP" + i];
+ if (id) {
+ var dom = document.getElementById("cbi-passwall-" + id);
+ if (dom) {
+ dom.classList.add("_now_use");
+ dom.title = "当前UDP" + i + "节点";
+ }
+ }
+ }
+ for (var i = 1; i <= result.tcp; i++) {
+ var id = result["TCP" + i];
+ if (id) {
+ var dom = document.getElementById("cbi-passwall-" + id);
+ if (dom) {
+ dom.classList.add("_now_use");
+ dom.title = "当前TCP" + i + "节点";
+ //var v = "当前使用:" + document.getElementById("cbid.passwall." + id + ".remarks").value;
+ //document.getElementById("cbi-passwall-" + id + "-remarks").innerHTML = v;
+ }
+ }
+ }
+ }
+ );
+ }
+
function ping_node(cbi_id, dom) {
var full = get_address_full(cbi_id);
if (full != null) {
@@ -266,6 +301,8 @@ table td, .table .td {
}
}
+ get_now_use_node();
+
const _xhr = (index) => {
return new Promise((res) => {
const dom = nodes[index];
@@ -365,7 +402,7 @@ table td, .table .td {
*/
var edit_btn = document.getElementById("cbi-passwall-nodes").getElementsByClassName("cbi-button cbi-button-edit");
- for(var i = 0; i < edit_btn.length; i++) {
+ for (var i = 0; i < edit_btn.length; i++) {
try {
var onclick_str = edit_btn[i].getAttribute("onclick");
var id = onclick_str.substring(onclick_str.lastIndexOf('/') + 1, onclick_str.length - 1);
diff --git a/package/lienol/luci-app-passwall/po/zh_Hans/passwall.po b/package/lienol/luci-app-passwall/po/zh_Hans/passwall.po
index ccccdbb0ef..fcb300726a 100644
--- a/package/lienol/luci-app-passwall/po/zh_Hans/passwall.po
+++ b/package/lienol/luci-app-passwall/po/zh_Hans/passwall.po
@@ -211,6 +211,9 @@ msgstr "ChinaDNS-NG 公平模式"
msgid "Filtered DNS(For Proxied Domains)"
msgstr "域名过滤服务(用于被代理的域名)"
+msgid "Format must be:"
+msgstr "格式必须为:"
+
msgid "DoH request address"
msgstr "DoH 请求地址"
@@ -970,6 +973,9 @@ msgstr "匿名"
msgid "User Password"
msgstr "账号密码"
+msgid "Username and Password must be used together!"
+msgstr "账号和密码必须同时使用!"
+
msgid "Node Number"
msgstr "节点数量"
diff --git a/package/lienol/luci-app-passwall/root/usr/share/passwall/app.sh b/package/lienol/luci-app-passwall/root/usr/share/passwall/app.sh
index d903323b44..161c341762 100755
--- a/package/lienol/luci-app-passwall/root/usr/share/passwall/app.sh
+++ b/package/lienol/luci-app-passwall/root/usr/share/passwall/app.sh
@@ -438,16 +438,32 @@ run_redir() {
esac
;;
TCP)
+ local kcptun_use=$(config_n_get $node use_kcp 0)
+ if [ "$kcptun_use" == "1" ]; then
+ local kcptun_server_host=$(config_n_get $node kcp_server)
+ local network_type="ipv4"
+ local kcptun_port=$(config_n_get $node kcp_port)
+ local kcptun_config="$(config_n_get $node kcp_opts)"
+ if [ -z "$kcptun_port" -o -z "$kcptun_config" ]; then
+ echolog "Kcptun未配置参数,错误!"
+ return 1
+ fi
+ if [ -n "$kcptun_port" -a -n "$kcptun_config" ]; then
+ local run_kcptun_ip=$server_host
+ [ -n "$kcptun_server_host" ] && run_kcptun_ip=$(get_host_ip $network_type $kcptun_server_host)
+ KCPTUN_REDIR_PORT=$(get_new_port $KCPTUN_REDIR_PORT tcp)
+ kcptun_params="-l 0.0.0.0:$KCPTUN_REDIR_PORT -r $run_kcptun_ip:$kcptun_port $kcptun_config"
+ ln_start_bin "$(first_type $(config_t_get global_app kcptun_client_file notset) kcptun-client)" "kcptun_tcp_$6" $kcptun_params
+ fi
+ fi
+ local _socks_flag _socks_address _socks_port _socks_username _socks_password
case "$type" in
socks)
- local node_address=$(config_n_get $node address)
- local node_port=$(config_n_get $node port)
- local server_username=$(config_n_get $node username)
- local server_password=$(config_n_get $node password)
- eval port=\$TCP_REDIR_PORT$6
- local extra_param="-T"
- [ "$6" == 1 ] && [ "$UDP_NODE1" == "tcp" ] && extra_param=""
- ln_start_bin "$(first_type ipt2socks)" "ipt2socks_tcp_$6" -l "$port" -b 0.0.0.0 -s "$node_address" -p "$node_port" -R $extra_param
+ _socks_flag=1
+ _socks_address=$(config_n_get $node address)
+ _socks_port=$(config_n_get $node port)
+ _socks_username=$(config_n_get $node username)
+ _socks_password=$(config_n_get $node password)
;;
v2ray)
local extra_param="tcp"
@@ -470,65 +486,46 @@ run_redir() {
ln_start_bin "$(first_type naive)" naive "$config_file"
;;
brook)
+ local server_ip=$server_host
local protocol=$(config_n_get $node protocol client)
+ local brook_tls=$(config_n_get $node brook_tls 0)
if [ "$protocol" == "wsclient" ]; then
- echolog "Brook的WebSocket不支持UDP转发!"
+ [ "$brook_tls" == "1" ] && server_ip="wss://${server_ip}" || server_ip="ws://${server_ip}"
+ socks_port=$(get_new_port 2081 tcp)
+ ln_start_bin "$(first_type $(config_t_get global_app brook_file notset) brook)" "brook_tcp_$6" wsclient --socks5 "127.0.0.1:$socks_port" -s "$server_ip:$port" -p "$(config_n_get $node password)"
+ _socks_flag=1
+ _socks_address="127.0.0.1"
+ _socks_port=$socks_port
+ echolog "Brook的WebSocket不支持透明代理,将使用ipt2socks转换透明代理!"
+ [ "$6" == 1 ] && [ "$UDP_NODE1" == "tcp" ] && echolog "Brook的WebSocket不支持UDP转发!"
else
- ln_start_bin "$(first_type $(config_t_get global_app brook_file notset) brook)" "brook_udp_$6" tproxy -l ":$local_port" -s "$server_host:$port" -p "$(config_n_get $node password)"
+ [ "$kcptun_use" == "1" ] && {
+ server_ip=127.0.0.1
+ port=$KCPTUN_REDIR_PORT
+ }
+ ln_start_bin "$(first_type $(config_t_get global_app brook_file notset) brook)" "brook_tcp_$6" tproxy -l ":$local_port" -s "$server_ip:$port" -p "$(config_n_get $node password)"
fi
;;
- *)
- local kcptun_use=$(config_n_get $node use_kcp 0)
+ ss|ssr)
if [ "$kcptun_use" == "1" ]; then
- local kcptun_server_host=$(config_n_get $node kcp_server)
- local network_type="ipv4"
- local kcptun_port=$(config_n_get $node kcp_port)
- local kcptun_config="$(config_n_get $node kcp_opts)"
- if [ -z "$kcptun_port" -o -z "$kcptun_config" ]; then
- echolog "Kcptun未配置参数,错误!"
- force_stop
- fi
- if [ -n "$kcptun_port" -a -n "$kcptun_config" ]; then
- local run_kcptun_ip=$server_host
- [ -n "$kcptun_server_host" ] && run_kcptun_ip=$(get_host_ip $network_type $kcptun_server_host)
- KCPTUN_REDIR_PORT=$(get_new_port $KCPTUN_REDIR_PORT tcp)
- kcptun_params="-l 0.0.0.0:$KCPTUN_REDIR_PORT -r $run_kcptun_ip:$kcptun_port $kcptun_config"
- ln_start_bin "$(first_type $(config_t_get global_app kcptun_client_file notset) kcptun-client)" "kcptun_tcp_$6" $kcptun_params
- fi
- fi
- if [ "$type" == "ssr" ] || [ "$type" == "ss" ]; then
- if [ "$kcptun_use" == "1" ]; then
- lua $API_GEN_SS $node $local_port 127.0.0.1 $KCPTUN_REDIR_PORT > $config_file
- [ "$6" == 1 ] && [ "$UDP_NODE1" == "tcp" ] && echolog "Kcptun不支持UDP转发!"
- else
- lua $API_GEN_SS $node $local_port > $config_file
- [ "$6" == 1 ] && [ "$UDP_NODE1" == "tcp" ] && extra_param="-u"
- fi
- for k in $(seq 1 $process); do
- ln_start_bin "$(first_type ${type}-redir)" "${type}-redir" -c "$config_file" $extra_param
- done
- elif [ "$type" == "brook" ]; then
- local server_ip=$server_host
- local protocol=$(config_n_get $node protocol client)
- local brook_tls=$(config_n_get $node brook_tls 0)
- if [ "$protocol" == "wsclient" ]; then
- [ "$brook_tls" == "1" ] && server_ip="wss://${server_ip}" || server_ip="ws://${server_ip}"
- socks_port=$(get_new_port 2081 tcp)
- ln_start_bin "$(first_type $(config_t_get global_app brook_file notset) brook)" "brook_tcp_$6" wsclient --socks5 "127.0.0.1:$socks_port" -s "$server_ip:$port" -p "$(config_n_get $node password)"
- eval port=\$TCP_REDIR_PORT$6
- ln_start_bin "$(first_type ipt2socks)" "ipt2socks_tcp_$6" -T -l "$port" -b 0.0.0.0 -s 127.0.0.1 -p "$socks_port" -R
- echolog "Brook的WebSocket不支持透明代理,将使用ipt2socks转换透明代理!"
- [ "$6" == 1 ] && [ "$UDP_NODE1" == "tcp" ] && echolog "Brook的WebSocket不支持UDP转发!"
- else
- [ "$kcptun_use" == "1" ] && {
- server_ip=127.0.0.1
- port=$KCPTUN_REDIR_PORT
- }
- ln_start_bin "$(first_type $(config_t_get global_app brook_file notset) brook)" "brook_tcp_$6" tproxy -l ":$local_port" -s "$server_ip:$port" -p "$(config_n_get $node password)"
- fi
+ lua $API_GEN_SS $node $local_port 127.0.0.1 $KCPTUN_REDIR_PORT > $config_file
+ process=1
+ [ "$6" == 1 ] && [ "$UDP_NODE1" == "tcp" ] && echolog "Kcptun不支持UDP转发!"
+ else
+ lua $API_GEN_SS $node $local_port > $config_file
+ [ "$6" == 1 ] && [ "$UDP_NODE1" == "tcp" ] && extra_param="-u"
fi
+ for k in $(seq 1 $process); do
+ ln_start_bin "$(first_type ${type}-redir)" "${type}-redir" -c "$config_file" $extra_param
+ done
;;
esac
+ if [ -n "$_socks_flag" ]; then
+ local extra_param="-T"
+ [ "$6" == 1 ] && [ "$UDP_NODE1" == "tcp" ] && extra_param=""
+ ln_start_bin "$(first_type ipt2socks)" "ipt2socks_tcp_$6" -l "$local_port" -b 0.0.0.0 -s "$_socks_address" -p "$_socks_port" -R $extra_param
+ fi
+ unset _socks_flag _socks_address _socks_port _socks_username _socks_password
;;
esac
return 0