luci-app-passwall: initial support nftables transparent proxy

This commit is contained in:
ShanStone 2022-10-02 15:42:42 +08:00 committed by sbwml
parent a57d07a888
commit b534485864
6 changed files with 1401 additions and 33 deletions

View File

@ -10,12 +10,12 @@ PKG_VERSION:=4.55
PKG_RELEASE:=1
PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_Transparent_Proxy \
CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \
CONFIG_PACKAGE_$(PKG_NAME)_Nftables_Transparent_Proxy \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Brook \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Haproxy \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_IPv6_Nat \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Server \
@ -40,7 +40,6 @@ LUCI_DEPENDS:=+coreutils +coreutils-base64 +coreutils-nohup +curl \
+PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG:chinadns-ng \
+PACKAGE_$(PKG_NAME)_INCLUDE_Haproxy:haproxy \
+PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria:hysteria \
+PACKAGE_$(PKG_NAME)_INCLUDE_IPv6_Nat:ip6tables-mod-nat \
+PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy:naiveproxy \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client:shadowsocks-libev-ss-local \
+PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Libev_Client:shadowsocks-libev-ss-redir \
@ -61,8 +60,8 @@ LUCI_DEPENDS:=+coreutils +coreutils-base64 +coreutils-nohup +curl \
define Package/$(PKG_NAME)/config
menu "Configuration"
config PACKAGE_$(PKG_NAME)_Transparent_Proxy
bool "Transparent Proxy"
config PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy
bool "Iptables Transparent Proxy"
select PACKAGE_dnsmasq-full
select PACKAGE_ipset
select PACKAGE_ipt2socks
@ -72,7 +71,16 @@ config PACKAGE_$(PKG_NAME)_Transparent_Proxy
select PACKAGE_iptables-mod-socket
select PACKAGE_iptables-mod-tproxy
select PACKAGE_kmod-ipt-nat
default y
default y if ! PACKAGE_firewall4
config PACKAGE_$(PKG_NAME)_Nftables_Transparent_Proxy
bool "Nftables Transparent Proxy"
select PACKAGE_dnsmasq-full
select PACKAGE_nftables
select PACKAGE_kmod-nft-socket
select PACKAGE_kmod-nft-tproxy
select PACKAGE_kmod-nft-nat
default y if PACKAGE_firewall4
select PACKAGE_iptables-nft
default y if PACKAGE_firewall4
@ -83,7 +91,8 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Brook
config PACKAGE_$(PKG_NAME)_INCLUDE_ChinaDNS_NG
bool "Include ChinaDNS-NG"
default y
select PACKAGE_ipset
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_Haproxy
bool "Include Haproxy"
@ -93,11 +102,6 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria
bool "Include Hysteria"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_IPv6_Nat
depends on PACKAGE_ip6tables
bool "Include IPv6 Nat"
default n
config PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy
bool "Include NaiveProxy"
depends on !(arc||(arm&&TARGET_gemini)||armeb||mips||mips64||powerpc)

View File

@ -95,7 +95,7 @@ o.default = "1:65535"
o:value("1:65535", translate("All"))
o:value("53", "DNS")
if os.execute("lsmod | grep -i REDIRECT >/dev/null") == 0 and os.execute("lsmod | grep -i TPROXY >/dev/null") == 0 then
if (os.execute("lsmod | grep -i REDIRECT >/dev/null") == 0 and os.execute("lsmod | grep -i TPROXY >/dev/null") == 0) or (os.execute("lsmod | grep -i nft_redir >/dev/null") == 0 and os.execute("lsmod | grep -i nft_tproxy >/dev/null") == 0) then
o = s:option(ListValue, "tcp_proxy_way", translate("TCP Proxy Way"))
o.default = "tproxy"
o:value("redirect", "REDIRECT")
@ -110,7 +110,7 @@ if os.execute("lsmod | grep -i REDIRECT >/dev/null") == 0 and os.execute("lsmod
return self.map:set(section, "tcp_proxy_way", value)
end
if os.execute("lsmod | grep -i ip6table_mangle >/dev/null") == 0 then
if os.execute("lsmod | grep -i ip6table_mangle >/dev/null") == 0 or os.execute("lsmod | grep -i nft_tproxy >/dev/null") == 0 then
---- IPv6 TProxy
o = s:option(Flag, "ipv6_tproxy", translate("IPv6 TProxy"),
"<font color='red'>" .. translate(

View File

@ -1149,7 +1149,7 @@ start_dns() {
smartdns)
local group_domestic=$(config_t_get global group_domestic)
CHINADNS_NG=0
source $APP_PATH/helper_smartdns.sh add FLAG="default" DNS_MODE=$DNS_MODE SMARTDNS_CONF=/tmp/etc/smartdns/$CONFIG.conf REMOTE_FAKEDNS=$fakedns DEFAULT_DNS=$DEFAULT_DNS LOCAL_GROUP=$group_domestic TUN_DNS=$TUN_DNS TCP_NODE=$TCP_NODE PROXY_MODE=${TCP_PROXY_MODE}${LOCALHOST_TCP_PROXY_MODE}${ACL_TCP_PROXY_MODE} NO_PROXY_IPV6=${filter_proxy_ipv6}
source $APP_PATH/helper_smartdns.sh add FLAG="default" DNS_MODE=$DNS_MODE SMARTDNS_CONF=/tmp/etc/smartdns/$CONFIG.conf REMOTE_FAKEDNS=$fakedns DEFAULT_DNS=$DEFAULT_DNS LOCAL_GROUP=$group_domestic TUN_DNS=$TUN_DNS TCP_NODE=$TCP_NODE PROXY_MODE=${TCP_PROXY_MODE}${LOCALHOST_TCP_PROXY_MODE}${ACL_TCP_PROXY_MODE} NO_PROXY_IPV6=${filter_proxy_ipv6} NFTFLAG=${nftflag}
source $APP_PATH/helper_smartdns.sh restart
echolog " - 域名解析使用SmartDNS请确保配置正常。"
;;
@ -1184,7 +1184,7 @@ start_dns() {
[ "$DNS_SHUNT" = "dnsmasq" ] && {
source $APP_PATH/helper_dnsmasq.sh stretch
source $APP_PATH/helper_dnsmasq.sh add FLAG="default" DNS_MODE=$DNS_MODE TMP_DNSMASQ_PATH=$TMP_DNSMASQ_PATH DNSMASQ_CONF_FILE=/tmp/dnsmasq.d/dnsmasq-passwall.conf REMOTE_FAKEDNS=$fakedns DEFAULT_DNS=$DEFAULT_DNS LOCAL_DNS=$LOCAL_DNS TUN_DNS=$TUN_DNS CHINADNS_DNS=$china_ng_listen TCP_NODE=$TCP_NODE PROXY_MODE=${TCP_PROXY_MODE}${LOCALHOST_TCP_PROXY_MODE}${ACL_TCP_PROXY_MODE} NO_PROXY_IPV6=${filter_proxy_ipv6}
source $APP_PATH/helper_dnsmasq.sh add FLAG="default" DNS_MODE=$DNS_MODE TMP_DNSMASQ_PATH=$TMP_DNSMASQ_PATH DNSMASQ_CONF_FILE=/tmp/dnsmasq.d/dnsmasq-passwall.conf REMOTE_FAKEDNS=$fakedns DEFAULT_DNS=$DEFAULT_DNS LOCAL_DNS=$LOCAL_DNS TUN_DNS=$TUN_DNS CHINADNS_DNS=$china_ng_listen TCP_NODE=$TCP_NODE PROXY_MODE=${TCP_PROXY_MODE}${LOCALHOST_TCP_PROXY_MODE}${ACL_TCP_PROXY_MODE} NO_PROXY_IPV6=${filter_proxy_ipv6} NFTFLAG=${nftflag}
}
}
@ -1348,9 +1348,22 @@ start() {
ulimit -n 65535
start_haproxy
start_socks
nftflag=0
[ "$NO_PROXY" == 1 ] || {
if [ -z "$(command -v iptables-legacy || command -v iptables)" ] || [ -z "$(command -v ipset)" ]; then
if [ -n "$(command -v fw4)" ] && [ -z "$(dnsmasq --version | grep 'nftset')" ]; then
echolog "检测到fw4防火墙但Dnsmasq软件包不满足nftables透明代理要求如需使用请确保dnsmasq版本在2.87以上并开启nftset支持。"
fi
if [ -n "$(command -v fw4)" ] && [ -n "$(dnsmasq --version | grep 'nftset')" ]; then
echolog "检测fw4防火墙使用nftables进行透明代理一些不支持nftables的组件如smartdns分流等将不可用。"
nftflag=1
start_redir TCP
start_redir UDP
start_dns
source $APP_PATH/nftables.sh start
source $APP_PATH/helper_${DNS_N}.sh logic_restart
elif [ -z "$(command -v iptables-legacy || command -v iptables)" ] || [ -z "$(command -v ipset)" ]; then
echolog "系统未安装iptables或ipset无法透明代理"
else
start_redir TCP
@ -1366,7 +1379,7 @@ start() {
stop() {
clean_log
source $APP_PATH/iptables.sh stop
[ -n "$(command -v fw4)" ] && [ -n "$(dnsmasq --version | grep 'nftset')" ] && source $APP_PATH/nftables.sh stop || source $APP_PATH/iptables.sh stop
delete_ip2route
kill_all v2ray-plugin obfs-local
pgrep -f "sleep.*(6s|9s|58s)" | xargs kill -9 >/dev/null 2>&1

View File

@ -65,9 +65,9 @@ restart() {
}
add() {
local FLAG TMP_DNSMASQ_PATH DNSMASQ_CONF_FILE DEFAULT_DNS LOCAL_DNS TUN_DNS REMOTE_FAKEDNS CHINADNS_DNS TCP_NODE PROXY_MODE NO_PROXY_IPV6 NO_LOGIC_LOG
local FLAG TMP_DNSMASQ_PATH DNSMASQ_CONF_FILE DEFAULT_DNS LOCAL_DNS TUN_DNS REMOTE_FAKEDNS CHINADNS_DNS TCP_NODE PROXY_MODE NO_PROXY_IPV6 NO_LOGIC_LOG NFTFLAG
eval_set_val $@
lua $APP_PATH/helper_dnsmasq_add.lua -FLAG $FLAG -TMP_DNSMASQ_PATH $TMP_DNSMASQ_PATH -DNSMASQ_CONF_FILE $DNSMASQ_CONF_FILE -DEFAULT_DNS $DEFAULT_DNS -LOCAL_DNS $LOCAL_DNS -TUN_DNS $TUN_DNS -REMOTE_FAKEDNS ${REMOTE_FAKEDNS:-0} -CHINADNS_DNS ${CHINADNS_DNS:-0} -TCP_NODE $TCP_NODE -PROXY_MODE $PROXY_MODE -NO_PROXY_IPV6 ${NO_PROXY_IPV6:-0} -NO_LOGIC_LOG ${NO_LOGIC_LOG:-0}
lua $APP_PATH/helper_dnsmasq_add.lua -FLAG $FLAG -TMP_DNSMASQ_PATH $TMP_DNSMASQ_PATH -DNSMASQ_CONF_FILE $DNSMASQ_CONF_FILE -DEFAULT_DNS $DEFAULT_DNS -LOCAL_DNS $LOCAL_DNS -TUN_DNS $TUN_DNS -REMOTE_FAKEDNS ${REMOTE_FAKEDNS:-0} -CHINADNS_DNS ${CHINADNS_DNS:-0} -TCP_NODE $TCP_NODE -PROXY_MODE $PROXY_MODE -NO_PROXY_IPV6 ${NO_PROXY_IPV6:-0} -NO_LOGIC_LOG ${NO_LOGIC_LOG:-0} -NFTFLAG ${NFTFLAG}
}
del() {

View File

@ -14,6 +14,7 @@ local TCP_NODE = var["-TCP_NODE"]
local PROXY_MODE = var["-PROXY_MODE"]
local NO_PROXY_IPV6 = var["-NO_PROXY_IPV6"]
local NO_LOGIC_LOG = var["-NO_LOGIC_LOG"]
local NFTFLAG = var["-NFTFLAG"]
local LOG_FILE = api.LOG_FILE
local CACHE_PATH = api.CACHE_PATH
local CACHE_FLAG = "dns_" .. FLAG
@ -192,6 +193,8 @@ if global and (not returnhome and not chnlist and not gfwlist) then
only_global = 1
end
local setflag= (NFTFLAG == "1") and "inet#fw4#" or ""
if not fs.access(CACHE_DNS_PATH) then
fs.mkdir("/tmp/dnsmasq.d")
fs.mkdir(CACHE_DNS_PATH)
@ -224,13 +227,13 @@ if not fs.access(CACHE_DNS_PATH) then
log(string.format(" - 域名白名单(whitelist)%s", LOCAL_DNS or "默认"))
local fwd_dns = LOCAL_DNS
local ipset_flag = "whitelist,whitelist6"
local ipset_flag = setflag.."whitelist,"..setflag.."whitelist6"
local no_ipv6
if subscribe_proxy == "1" then
fwd_dns = TUN_DNS
ipset_flag = "blacklist,blacklist6"
ipset_flag = setflag.."blacklist,"..setflag.."blacklist6"
if NO_PROXY_IPV6 == "1" then
ipset_flag = "blacklist"
ipset_flag = setflag.."blacklist"
no_ipv6 = true
end
if not only_global then
@ -255,10 +258,10 @@ if not fs.access(CACHE_DNS_PATH) then
for line in io.lines("/usr/share/passwall/rules/proxy_host") do
if line ~= "" and not line:find("#") then
add_excluded_domain(line)
local ipset_flag = "blacklist,blacklist6"
local ipset_flag = setflag.."blacklist,"..setflag.."blacklist6"
if NO_PROXY_IPV6 == "1" then
set_domain_address(line, "::")
ipset_flag = "blacklist"
ipset_flag = setflag.."blacklist"
end
if REMOTE_FAKEDNS == "1" then
ipset_flag = nil
@ -286,12 +289,12 @@ if not fs.access(CACHE_DNS_PATH) then
if _node_id == "_direct" then
fwd_dns = LOCAL_DNS
ipset_flag = "whitelist,whitelist6"
ipset_flag = setflag.."whitelist,"..setflag.."whitelist6"
else
fwd_dns = TUN_DNS
ipset_flag = "shuntlist,shuntlist6"
ipset_flag = setflag.."shuntlist,"..setflag.."shuntlist6"
if NO_PROXY_IPV6 == "1" then
ipset_flag = "shuntlist"
ipset_flag = setflag.."shuntlist"
no_ipv6 = true
end
if not only_global then
@ -329,9 +332,9 @@ if not fs.access(CACHE_DNS_PATH) then
local gfwlist_str = sys.exec('cat /usr/share/passwall/rules/gfwlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '"')
for line in string.gmatch(gfwlist_str, "[^\r\n]+") do
if line ~= "" then
local ipset_flag = "gfwlist,gfwlist6"
local ipset_flag = setflag.."gfwlist,"..setflag.."gfwlist6"
if NO_PROXY_IPV6 == "1" then
ipset_flag = "gfwlist"
ipset_flag = setflag.."gfwlist"
set_domain_address(line, "::")
end
if not only_global then
@ -368,9 +371,9 @@ if not fs.access(CACHE_DNS_PATH) then
local chnlist_str = sys.exec('cat /usr/share/passwall/rules/chnlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '"')
for line in string.gmatch(chnlist_str, "[^\r\n]+") do
if line ~= "" then
local ipset_flag = "chnroute,chnroute6"
local ipset_flag = setflag.."chnroute,"..setflag.."chnroute6"
if NO_PROXY_IPV6 == "1" then
ipset_flag = "chnroute"
ipset_flag = setflag.."chnroute"
set_domain_address(line, "::")
end
if not only_global then
@ -389,6 +392,10 @@ if not fs.access(CACHE_DNS_PATH) then
local address_out = io.open(CACHE_DNS_PATH .. "/000-address.conf", "a")
local server_out = io.open(CACHE_DNS_PATH .. "/001-server.conf", "a")
local ipset_out = io.open(CACHE_DNS_PATH .. "/ipset.conf", "a")
local set_name = "ipset"
if NFTFLAG == "1" then
set_name = "nftset"
end
for key, value in pairs(list1) do
if value.address and #value.address > 0 then
address_out:write(string.format("address=/.%s/%s\n", key, value.address))
@ -404,7 +411,7 @@ if not fs.access(CACHE_DNS_PATH) then
ipsets_str = ipsets_str .. ipset .. ","
end
ipsets_str = ipsets_str:sub(1, #ipsets_str - 1)
ipset_out:write(string.format("ipset=/.%s/%s\n", key, ipsets_str))
ipset_out:write(string.format("%s=/.%s/%s\n", set_name, key, ipsets_str))
end
end
address_out:close()

File diff suppressed because it is too large Load Diff