update 2024-07-22 20:35:13

This commit is contained in:
kenzok8 2024-07-22 20:35:13 +08:00
parent 41b16fb9ce
commit a070788e0e
28 changed files with 409 additions and 283 deletions

View File

@ -33,6 +33,9 @@ uci set ua2f.firewall.handle_intranet=1
# 使用自定义 User-Agent
uci set ua2f.main.custom_ua="Test UA/1.0"
# 禁用 Conntrack 标记,这会降低性能,但是有助于和其他修改 Connmark 的软件共存
uci set ua2f.main.disable_connmark=1
# 应用配置
uci commit ua2f

View File

@ -8,4 +8,5 @@ config ua2f 'firewall'
option handle_intranet '1'
config ua2f 'main'
option custom_ua ''
option custom_ua ''
option disable_connmark '0'

View File

@ -34,10 +34,11 @@ setup_firewall() {
return 1
fi
local handle_tls handle_intranet handle_mmtls
local handle_tls handle_intranet handle_mmtls disable_connmark
config_get_bool handle_tls "firewall" "handle_tls" "0"
config_get_bool handle_intranet "firewall" "handle_intranet" "0"
config_get_bool handle_mmtls "firewall" "handle_mmtls" "0"
config_get_bool disable_connmark "main" "disable_connmark" "0"
if [ -n "$HAS_NFT" ]; then
nft -f- <<-EOF
@ -67,23 +68,23 @@ setup_firewall() {
};
}
chain prerouting {
type filter hook prerouting priority mangle -5; policy accept;
chain postrouting {
type filter hook postrouting priority mangle -5; policy accept;
$([ "$handle_intranet" -ne "1" ] || echo 'ip daddr @localaddr_v4 counter return;')
$([ "$handle_intranet" -ne "1" ] || echo 'ip6 daddr @localaddr_v6 counter return;')
tcp dport 22 counter return comment "!ua2f: bypass SSH";
$([ "$handle_tls" -eq "1" ] || echo 'tcp dport 443 counter return comment "!ua2f: bypass HTTPS";')
tcp dport 80 counter ct mark set 44;
ct mark 43 counter return comment "!ua2f: bypass non-http stream";
$([ "$disable_connmark" -eq "1" ] || echo 'tcp dport 80 counter ct mark set 44;')
$([ "$disable_connmark" -eq "1" ] || echo 'ct mark 43 counter return comment "!ua2f: bypass non-http stream";')
meta l4proto tcp ct direction original counter queue num 10010 bypass;
}
}
EOF
else
# Flush existing rules
$IPT_M -D FORWARD -p tcp -m conntrack --ctdir ORIGINAL -j ua2f 2>"/dev/null"
$IPT_M -D POSTROUTING -p tcp -m conntrack --ctdir ORIGINAL -j ua2f 2>"/dev/null"
if $IPT_M -N ua2f; then
if [ "$handle_intranet" -ne "1" ]; then
@ -98,16 +99,16 @@ setup_firewall() {
fi
[ "$handle_tls" -eq "1" ] || $IPT_M -A ua2f -p tcp --dport 443 -j RETURN # 不处理 HTTPS
$IPT_M -A ua2f -p tcp --dport 80 -j CONNMARK --set-mark 44
$IPT_M -A ua2f -m connmark --mark 43 -j RETURN # 不处理标记为非 http 的流
[ "$disable_connmark" -eq "1" ] || $IPT_M -A ua2f -p tcp --dport 80 -j CONNMARK --set-mark 44
[ "$disable_connmark" -eq "1" ] || $IPT_M -A ua2f -m connmark --mark 43 -j RETURN # 不处理标记为非 http 的流
[ "$handle_mmtls" -eq "1" ] || $IPT_M -A ua2f -p tcp --dport 80 -m string --string "/mmtls/" --algo bm -j RETURN # 不处理微信的mmtls
$IPT_M -A ua2f -j NFQUEUE --queue-num 10010 --queue-bypass
fi
$IPT_M -A FORWARD -p tcp -m conntrack --ctdir ORIGINAL -j ua2f
$IPT_M -A POSTROUTING -p tcp -m conntrack --ctdir ORIGINAL -j ua2f
if [ -n "$HAS_IPT6" ]; then
# Flush existing rules
$IPT6_M -D FORWARD -p tcp -m conntrack --ctdir ORIGINAL -j ua2f 2>"/dev/null"
$IPT6_M -D POSTROUTING -p tcp -m conntrack --ctdir ORIGINAL -j ua2f 2>"/dev/null"
if $IPT6_M -N ua2f; then
if [ "$handle_intranet" -ne "1" ]; then
@ -127,12 +128,12 @@ setup_firewall() {
fi
[ "$handle_tls" -eq "1" ] || $IPT6_M -A ua2f -p tcp --dport 443 -j RETURN # 不处理 HTTPS
$IPT6_M -A ua2f -p tcp --dport 80 -j CONNMARK --set-mark 44
$IPT6_M -A ua2f -m connmark --mark 43 -j RETURN # 不处理标记为非 http 的流
[ "$disable_connmark" -eq "1" ] || $IPT6_M -A ua2f -p tcp --dport 80 -j CONNMARK --set-mark 44
[ "$disable_connmark" -eq "1" ] || $IPT6_M -A ua2f -m connmark --mark 43 -j RETURN # 不处理标记为非 http 的流
[ "$handle_mmtls" -eq "1" ] || $IPT6_M -A ua2f -p tcp --dport 80 -m string --string "/mmtls/" --algo bm -j RETURN # 不处理微信的mmtls
$IPT6_M -A ua2f -j NFQUEUE --queue-num 10010 --queue-bypass
fi
$IPT6_M -A FORWARD -p tcp -m conntrack --ctdir ORIGINAL -j ua2f
$IPT6_M -A POSTROUTING -p tcp -m conntrack --ctdir ORIGINAL -j ua2f
fi
fi
}
@ -173,12 +174,12 @@ stop_service() {
nft flush table inet ua2f
nft delete table inet ua2f
else
$IPT_M -D FORWARD -p tcp -m conntrack --ctdir ORIGINAL -j ua2f 2>"/dev/null"
$IPT_M -D POSTROUTING -p tcp -m conntrack --ctdir ORIGINAL -j ua2f 2>"/dev/null"
$IPT_M -F ua2f 2>"/dev/null"
$IPT_M -X ua2f 2>"/dev/null"
if [ -n "$HAS_IPT6" ]; then
$IPT6_M -D FORWARD -p tcp -m conntrack --ctdir ORIGINAL -j ua2f 2>"/dev/null"
$IPT6_M -D POSTROUTING -p tcp -m conntrack --ctdir ORIGINAL -j ua2f 2>"/dev/null"
$IPT6_M -F ua2f 2>"/dev/null"
$IPT6_M -X ua2f 2>"/dev/null"
fi

View File

@ -29,6 +29,12 @@ void try_print_info(const int argc, char *argv[]) {
} else {
printf("Config UA: not set\n");
}
if (config.disable_connmark) {
printf("Conntrack cache: disabled\n");
} else {
printf("Conntrack cache: auto\n");
}
#else
printf("UCI support disabled\n");
#endif

View File

@ -8,11 +8,12 @@
struct ua2f_config config = {
.use_custom_ua = false,
.custom_ua = NULL,
.disable_connmark = false,
};
void load_config() {
const __auto_type ctx = uci_alloc_context();
if (!ctx) {
if (ctx == NULL) {
syslog(LOG_ERR, "Failed to allocate uci context");
return;
}
@ -24,12 +25,12 @@ void load_config() {
// find ua2f.main.custom_ua
const __auto_type section = uci_lookup_section(ctx, package, "main");
if (!section) {
if (section == NULL) {
goto cleanup;
}
const __auto_type custom_ua = uci_lookup_option_string(ctx, section, "custom_ua");
if (!custom_ua) {
if (custom_ua == NULL) {
goto cleanup;
}
if (strlen(custom_ua) > 0) {
@ -37,6 +38,11 @@ void load_config() {
config.custom_ua = strdup(custom_ua);
}
const __auto_type disable_connmark = uci_lookup_option_string(ctx, section, "disable_connmark");
if (disable_connmark != NULL && strcmp(disable_connmark, "1") == 0) {
config.disable_connmark = true;
}
cleanup:
uci_free_context(ctx);
}

View File

@ -9,6 +9,7 @@
struct ua2f_config {
bool use_custom_ua;
char *custom_ua;
bool disable_connmark;
};
void load_config();

View File

@ -27,6 +27,9 @@ static char *replacement_user_agent_string = NULL;
#define CONNMARK_NOT_HTTP 43
#define CONNMARK_HTTP 44
bool use_conntrack = true;
static bool cache_initialized = false;
void init_handler() {
replacement_user_agent_string = malloc(MAX_USER_AGENT_LENGTH);
@ -39,6 +42,11 @@ void init_handler() {
syslog(LOG_INFO, "Using config user agent string: %s", replacement_user_agent_string);
ua_set = true;
}
if (config.disable_connmark) {
use_conntrack = false;
syslog(LOG_INFO, "Conntrack cache disabled by config.");
}
#endif
#ifdef UA2F_CUSTOM_UA
@ -100,9 +108,6 @@ end:
}
}
bool conntrack_info_available = true;
static bool cache_initialized = false;
static void add_to_cache(const struct nf_packet *pkt) {
struct addr_port target = {
.addr = pkt->orig.dst,
@ -113,7 +118,7 @@ static void add_to_cache(const struct nf_packet *pkt) {
}
static struct mark_op get_next_mark(const struct nf_packet *pkt, const bool has_ua) {
if (!conntrack_info_available) {
if (!use_conntrack) {
return (struct mark_op){false, 0};
}
@ -162,9 +167,9 @@ bool should_ignore(const struct nf_packet *pkt) {
}
void handle_packet(const struct nf_queue *queue, const struct nf_packet *pkt) {
if (conntrack_info_available) {
if (use_conntrack) {
if (!pkt->has_conntrack) {
conntrack_info_available = false;
use_conntrack = false;
syslog(LOG_WARNING, "Packet has no conntrack. Switching to no cache mode.");
syslog(LOG_WARNING, "Note that this may lead to performance degradation. Especially on low-end routers.");
} else {
@ -175,19 +180,17 @@ void handle_packet(const struct nf_queue *queue, const struct nf_packet *pkt) {
}
}
struct pkt_buff *pkt_buff = NULL;
if (conntrack_info_available && should_ignore(pkt)) {
if (use_conntrack && should_ignore(pkt)) {
send_verdict(queue, pkt, (struct mark_op){true, CONNMARK_NOT_HTTP}, NULL);
goto end;
}
pkt_buff = pktb_alloc(AF_INET, pkt->payload, pkt->payload_len, 0);
struct pkt_buff *pkt_buff = pktb_alloc(AF_INET, pkt->payload, pkt->payload_len, 0);
ASSERT(pkt_buff != NULL);
int type;
if (conntrack_info_available) {
if (use_conntrack) {
type = pkt->orig.ip_version;
} else {
const __auto_type ip_hdr = nfq_ip_get_hdr(pkt_buff);

View File

@ -3,7 +3,7 @@
#include "third/nfqueue-mnl.h"
extern bool conntrack_info_available;
extern bool use_conntrack;
void init_handler();

View File

@ -50,10 +50,10 @@ int read_buffer(struct nf_queue *queue, struct nf_buffer *buf) {
}
}
bool retry_disable_conntrack(struct nf_queue *queue) {
bool retry_without_conntrack(struct nf_queue *queue) {
nfqueue_close(queue);
syslog(LOG_INFO, "Retrying to disable conntrack");
syslog(LOG_INFO, "Retry without conntrack");
const __auto_type ret = nfqueue_open(queue, QUEUE_NUM, 0, true);
if (!ret) {
syslog(LOG_ERR, "Failed to open nfqueue with conntrack disabled");
@ -70,7 +70,7 @@ void main_loop(struct nf_queue *queue) {
if (read_buffer(queue, buf) == IO_ERROR) {
if (!retried) {
retried = true;
if (!retry_disable_conntrack(queue)) {
if (!retry_without_conntrack(queue)) {
break;
}
} else {

View File

@ -5,11 +5,11 @@
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI support for Timewol From Koolshare
LUCI_TITLE:=LuCI support for Timewol
LUCI_DEPENDS:=+etherwake
LUCI_PKGARCH:=all
PKG_VERSION:=1.0
PKG_RELEASE:=3-20220406
PKG_VERSION:=1.1
PKG_RELEASE:=1
include $(TOPDIR)/feeds/luci/luci.mk

View File

@ -4,16 +4,13 @@ function index()
if not nixio.fs.access("/etc/config/timewol") then return end
entry({"admin", "control"}, firstchild(), "Control", 44).dependent = false
entry({"admin", "control", "timewol"}, cbi("timewol"), _("定时唤醒"), 95).dependent =
true
entry({"admin", "control", "timewol"}, cbi("timewol"), _("Timed Wakeup"), 95).dependent = true
entry({"admin", "control", "timewol", "status"}, call("status")).leaf = true
end
function status()
local e = {}
e.status = luci.sys
.call("cat /etc/crontabs/root |grep etherwake >/dev/null") ==
0
e.status = luci.sys.call("cat /etc/crontabs/root | grep etherwake >/dev/null") == 0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end

View File

@ -1,37 +1,38 @@
local i = require "luci.sys"
local t, e, o
t = Map("timewol", translate("定时网络唤醒"),
translate("定时唤醒你的局域网设备"))
t.template = "timewol/index"
e = t:section(TypedSection, "basic", translate("Running Status"))
t = Map("timewol", translate("Timed network wake-up"), translate("Wake up your LAN device regularly"))
e = t:section(TypedSection, "basic", translate("Basic setting"))
e.anonymous = true
o = e:option(DummyValue, "timewol_status", translate("当前状态"))
o.template = "timewol/timewol"
o.value = translate("Collecting data...")
e = t:section(TypedSection, "basic", translate("基本设置"))
e.anonymous = true
o = e:option(Flag, "enable", translate("开启"))
o = e:option(Flag, "enable", translate("Enable"))
o.rmempty = false
e = t:section(TypedSection, "macclient", translate("客户端设置"))
e = t:section(TypedSection, "macclient", translate("Client setting"))
e.template = "cbi/tblsection"
e.anonymous = true
e.addremove = true
nolimit_mac = e:option(Value, "macaddr", translate("客户端MAC"))
nolimit_mac = e:option(Value, "macaddr", translate("MAC Address"))
nolimit_mac.rmempty = false
i.net.mac_hints(function(e, t) nolimit_mac:value(e, "%s (%s)" % {e, t}) end)
nolimit_eth = e:option(Value, "maceth", translate("网络接口"))
nolimit_eth = e:option(Value, "maceth", translate("Network interface"))
nolimit_eth.rmempty = false
for t, e in ipairs(i.net.devices()) do if e ~= "lo" then nolimit_eth:value(e) end end
a = e:option(Value, "minute", translate("分钟"))
a = e:option(Value, "minute", translate("minutes"))
a.optional = false
a = e:option(Value, "hour", translate("小时"))
a = e:option(Value, "hour", translate("hour"))
a.optional = false
a = e:option(Value, "day", translate(""))
a = e:option(Value, "day", translate("day"))
a.optional = false
a = e:option(Value, "month", translate(""))
a = e:option(Value, "month", translate("month"))
a.optional = false
a = e:option(Value, "weeks", translate("星期"))
a = e:option(Value, "weeks", translate("weeks"))
a.optional = false
local e = luci.http.formvalue("cbi.apply")
if e then io.popen("/etc/init.d/timewol restart") end
return t

View File

@ -4,8 +4,50 @@ msgstr "管控"
msgid "Running Status"
msgstr "运行状态"
msgid "Collecting data..."
msgstr "正在收集数据..."
msgid "NOT RUNNING"
msgstr "未运行"
msgid "RUNNING"
msgstr "运行中"
msgid "Timed Wakeup"
msgstr "定时唤醒"
msgid "Timed network wake-up"
msgstr "定时网络唤醒"
msgid "Wake up your LAN device regularly"
msgstr "定时唤醒你的局域网设备"
msgid "Basic setting"
msgstr "基本设置"
msgid "Enable"
msgstr "开启"
msgid "Client setting"
msgstr "客户端设置"
msgid "MAC Address"
msgstr "MAC 地址"
msgid "Network interface"
msgstr "网络接口"
msgid "minutes"
msgstr "分钟"
msgid "hour"
msgstr "小时"
msgid "day"
msgstr "日"
msgid "month"
msgstr "月"
msgid "weeks"
msgstr "星期"

View File

@ -33,39 +33,40 @@ load_config() {
}
add_rule(){
sed -i '/etherwake/d' /etc/crontabs/root >/dev/null 2>&1
for i in $(seq 0 100)
do
local macaddr=$(uci_get_by_type macclient macaddr '' $i)
local maceth=$(uci_get_by_type macclient maceth '' $i)
local minute=$(uci_get_by_type macclient minute '' $i)
local hour=$(uci_get_by_type macclient hour '' $i)
local day=$(uci_get_by_type macclient day '' $i)
local month=$(uci_get_by_type macclient month '' $i)
local weeks=$(uci_get_by_type macclient weeks '' $i)
local items=$(uci show ${CONFIG} | grep "=macclient" | cut -d '.' -sf 2 | cut -d '=' -sf 1)
for i in $items; do
local macaddr=$(uci -q get ${CONFIG}.${i}.macaddr)
local maceth=$(uci -q get ${CONFIG}.${i}.maceth)
local minute=$(uci -q get ${CONFIG}.${i}.minute)
local hour=$(uci -q get ${CONFIG}.${i}.hour)
local day=$(uci -q get ${CONFIG}.${i}.day)
local month=$(uci -q get ${CONFIG}.${i}.month)
local weeks=$(uci -q get ${CONFIG}.${i}.weeks)
if [ -z $macaddr ] || [ -z $maceth ]; then
break
continue
fi
if [ -z $minute ] ; then
minute="0"
minute="0"
fi
if [ -z $hour ] ; then
hour="*"
hour="*"
fi
if [ -z $day ] ; then
day="*"
day="*"
fi
if [ -z $month ] ; then
month="*"
month="*"
fi
if [ -z $weeks ] ; then
weeks="*"
weeks="*"
fi
echo "$minute $hour $day $month $weeks /usr/bin/etherwake -D -i $maceth $macaddr" >> /etc/crontabs/root
done
echo "$minute $hour $day $month $weeks /usr/bin/etherwake -D -i $maceth $macaddr" >> /etc/crontabs/root
unset macaddr maceth minute hour day month weeks
done
}
start() {
stop
! load_config && exit 0
add_rule
}

View File

@ -5,13 +5,11 @@
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI support for Webrestriction From Koolshare
LUCI_TITLE:=LuCI support for Webrestriction
LUCI_PKGARCH:=all
PKG_VERSION:=1.0
PKG_RELEASE:=5-20220406
PKG_VERSION:=1.1
PKG_RELEASE:=1
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -4,16 +4,13 @@ function index()
if not nixio.fs.access("/etc/config/webrestriction") then return end
entry({"admin", "control"}, firstchild(), "Control", 44).dependent = false
entry({"admin", "control", "webrestriction"}, cbi("webrestriction"),
_("访问限制"), 11).dependent = true
entry({"admin", "control", "webrestriction", "status"}, call("status")).leaf =
true
entry({"admin", "control", "webrestriction"}, cbi("webrestriction"), _("Access Control"), 11).dependent = true
entry({"admin", "control", "webrestriction", "status"}, call("status")).leaf = true
end
function status()
local e = {}
e.status = luci.sys.call(
"iptables -L FORWARD |grep WEB_RESTRICTION >/dev/null") == 0
e.status = luci.sys.call("iptables -L FORWARD | grep WEB_RESTRICTION >/dev/null") == 0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end

View File

@ -1,30 +1,36 @@
local o = require "luci.sys"
local a, e, t
a = Map("webrestriction", translate("访问限制"), translate(
"使用黑名单或者白名单模式控制列表中的客户端是否能够连接到互联网。"))
a = Map("webrestriction", translate("Access Control"), translate("Use the blacklist or whitelist mode to control whether a client in the list can connect to the Internet."))
a.template = "webrestriction/index"
e = a:section(TypedSection, "basic", translate("Running Status"))
e.anonymous = true
t = e:option(DummyValue, "webrestriction_status", translate("当前状态"))
t = e:option(DummyValue, "webrestriction_status", translate("Running Status"))
t.template = "webrestriction/webrestriction"
t.value = translate("Collecting data...")
e = a:section(TypedSection, "basic", translate("全局设置"))
e = a:section(TypedSection, "basic", translate("Global setting"))
e.anonymous = true
t = e:option(Flag, "enable", translate("开启"))
t = e:option(Flag, "enable", translate("Enable"))
t.rmempty = false
t = e:option(ListValue, "limit_type", translate("限制模式"))
t = e:option(ListValue, "limit_type", translate("Limit mode"))
t.default = "blacklist"
t:value("whitelist", translate("白名单"))
t:value("whitelist", translate("Whitelist"))
t:value("blacklist", translate("Blacklist"))
t.rmempty = false
e = a:section(TypedSection, "macbind", translate("名单设置"), translate(
"如果是黑名单模式,列表中的客户端将被禁止连接到互联网;白名单模式表示仅有列表中的客户端可以连接到互联网。"))
e = a:section(TypedSection, "macbind", translate("List setting"), translate("In blacklist mode, the client in the list is prohibited from connecting to the Internet. In whitelist mode, only the clients in the list can connect to the Internet."))
e.template = "cbi/tblsection"
e.anonymous = true
e.addremove = true
t = e:option(Flag, "enable", translate("开启控制"))
t = e:option(Flag, "enable", translate("Enable"))
t.rmempty = false
t = e:option(Value, "macaddr", translate("MAC地址"))
t = e:option(Value, "macaddr", translate("MAC Address"))
t.rmempty = true
o.net.mac_hints(function(e, a) t:value(e, "%s (%s)" % {e, a}) end)
return a

View File

@ -4,11 +4,41 @@ msgstr "管控"
msgid "Running Status"
msgstr "运行状态"
msgid "Collecting data..."
msgstr "正在收集数据..."
msgid "NOT RUNNING"
msgstr "未运行"
msgid "RUNNING"
msgstr "运行中"
msgid "Access Control"
msgstr "访问限制"
msgid "Use the blacklist or whitelist mode to control whether a client in the list can connect to the Internet."
msgstr "使用黑名单或者白名单模式控制列表中的客户端是否能够连接到互联网。"
msgid "Global setting"
msgstr "全局设置"
msgid "Enable"
msgstr "开启"
msgid "Limit mode"
msgstr "限制模式"
msgid "Whitelist"
msgstr "白名单"
msgid "Blacklist"
msgstr "黑名单"
msgid "List setting"
msgstr "名单设置"
msgid "In blacklist mode, the client in the list is prohibited from connecting to the Internet. In whitelist mode, only the clients in the list can connect to the Internet."
msgstr "如果是黑名单模式,列表中的客户端将被禁止连接到互联网;白名单模式表示仅有列表中的客户端可以连接到互联网。"
msgid "MAC Address"
msgstr "MAC 地址"

View File

@ -1,86 +1,86 @@
#!/bin/sh /etc/rc.common
#
# Copyright (C) 2015 OpenWrt-dist
# Copyright (C) 2016 fw867 <ffkykzs@gmail.com>
#
# This is free software, licensed under the GNU General Public License v3.
# See /LICENSE for more information.
#
# Copyright (C) 2024 Lienol
START=99
CONFIG=webrestriction
limit_type=$(uci -q get webrestriction.@basic[0].limit_type)
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_true() {
case $1 in
1|on|true|yes|enabled) echo 0;;
*) echo 1;;
esac
}
load_config() {
ENABLED=$(uci_get_by_type basic enable)
return $(is_true $ENABLED)
}
ipt="iptables -w"
ip6t="ip6tables -w"
add_rule(){
action=$1
for i in $(seq 0 100)
do
enable=$(uci_get_by_type macbind enable '' $i)
macaddr=$(uci_get_by_type macbind macaddr '' $i)
local items=$(uci show ${CONFIG} | grep "=macbind" | cut -d '.' -sf 2 | cut -d '=' -sf 1)
for i in $items; do
enable=$(uci -q get ${CONFIG}.${i}.enable)
macaddr=$(uci -q get ${CONFIG}.${i}.macaddr)
if [ -z $enable ] || [ -z $macaddr ]; then
break
continue
fi
if [ "$enable" == "1" ]; then
iptables -t filter -A WEB_RESTRICTION -m mac --mac-source $macaddr -j $action
[ "$limit_type" == "blacklist" ] && iptables -t nat -A WEB_RESTRICTION -m mac --mac-source $macaddr -j RETURN
#unset "$macaddr"
$ipt -A WEB_RESTRICTION -m mac --mac-source $macaddr -j $action
$ip6t -A WEB_RESTRICTION -m mac --mac-source $macaddr -j $action 2>/dev/null
[ "$limit_type" == "blacklist" ] && {
$ipt -t nat -A WEB_RESTRICTION -m mac --mac-source $macaddr -j RETURN
$ip6t -t nat -A WEB_RESTRICTION -m mac --mac-source $macaddr -j RETURN 2>/dev/null
}
fi
unset enable macaddr
done
}
start(){
! load_config && exit 0
[ "`iptables -L FORWARD|grep -c WEB_RESTRICTION`" -gt 0 ] && exit 0;
iptables -P FORWARD DROP
iptables -t filter -N WEB_RESTRICTION
stop
ENABLED=$(uci -q get ${CONFIG}.@basic[0].enable || echo "0")
[ "${ENABLED}" != "1" ] && exit 0
limit_type=$(uci -q get ${CONFIG}.@basic[0].limit_type)
$ipt -N WEB_RESTRICTION
$ip6t -N WEB_RESTRICTION 2>/dev/null
if [ "$limit_type" == "blacklist" ]; then
iptables -t nat -N WEB_RESTRICTION
$ipt -t nat -N WEB_RESTRICTION
$ip6t -t nat -N WEB_RESTRICTION 2>/dev/null
add_rule DROP
else
add_rule ACCEPT
iptables -t filter -A WEB_RESTRICTION -j DROP
$ipt -A WEB_RESTRICTION -j DROP
$ip6t -A WEB_RESTRICTION -j DROP 2>/dev/null
fi
#获取FORWARD ACCEPT规则行号
FA_INDEX=`iptables -t filter -L FORWARD --line-numbers | tail -n +3 | grep -E ACCEPT | grep ctstate | grep fw3 | awk '{print $1}'`
if [ -n "$FA_INDEX" ]; then
let FA_INDEX+=1
fi
#确保添加到FORWARD ACCEPT规则之后
iptables -t filter -I FORWARD $FA_INDEX -m comment --comment "Rule For Control" -j WEB_RESTRICTION
[ "$limit_type" == "blacklist" ] && iptables -t nat -I PREROUTING 1 -m comment --comment "Rule For Control" -j WEB_RESTRICTION
FA_INDEX=`$ipt -L FORWARD --line-numbers | tail -n +3 | grep -E ACCEPT | grep ctstate | grep fw3 | awk '{print $1}'`
[ -n "$FA_INDEX" ] && let FA_INDEX+=1
$ipt -I FORWARD $FA_INDEX -j WEB_RESTRICTION
#获取FORWARD ACCEPT规则行号
FA_INDEX=`$ip6t -L FORWARD --line-numbers | tail -n +3 | grep -E ACCEPT | grep ctstate | grep fw3 | awk '{print $1}'`
[ -n "$FA_INDEX" ] && let FA_INDEX+=1
$ip6t -I FORWARD $FA_INDEX -j WEB_RESTRICTION
[ "$limit_type" == "blacklist" ] && {
$ipt -t nat -I PREROUTING 1 -j WEB_RESTRICTION
$ip6t -t nat -I PREROUTING 1 -j WEB_RESTRICTION 2>/dev/null
}
}
stop(){
[ "`iptables -t filter -L | grep -c WEB_RESTRICTION`" -gt 0 ] && {
iptables -t filter -D FORWARD -m comment --comment "Rule For Control" -j WEB_RESTRICTION
iptables -t nat -D PREROUTING -m comment --comment "Rule For Control" -j WEB_RESTRICTION
iptables -t filter -F WEB_RESTRICTION
iptables -t filter -X WEB_RESTRICTION
iptables -t nat -F WEB_RESTRICTION
iptables -t nat -X WEB_RESTRICTION
ipt_del() {
for i in $(seq 1 $($1 -nL $2 | grep -c "WEB_RESTRICTION")); do
local index=$($1 --line-number -nL $2 | grep "WEB_RESTRICTION" | head -1 | awk '{print $1}')
$1 -w -D $2 $index 2>/dev/null
done
}
ipt_del "$ipt" "FORWARD"
ipt_del "$ipt" "INPUT"
ipt_del "$ipt -t nat" "PREROUTING"
ipt_del "$ip6t" "FORWARD"
ipt_del "$ip6t" "INPUT"
ipt_del "$ip6t -t nat" "PREROUTING"
$ipt -F WEB_RESTRICTION 2>/dev/null
$ipt -X WEB_RESTRICTION 2>/dev/null
$ipt -t nat -F WEB_RESTRICTION 2>/dev/null
$ipt -t nat -X WEB_RESTRICTION 2>/dev/null
$ip6t -F WEB_RESTRICTION 2>/dev/null
$ip6t -X WEB_RESTRICTION 2>/dev/null
$ip6t -t nat -F WEB_RESTRICTION 2>/dev/null
$ip6t -t nat -X WEB_RESTRICTION 2>/dev/null
}

View File

@ -5,14 +5,12 @@
include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI support for Weburl From Koolshare
LUCI_TITLE:=LuCI support for Weburl
LUCI_DEPENDS:=+iptables-mod-filter +kmod-ipt-filter
LUCI_PKGARCH:=all
PKG_VERSION:=1.0
PKG_RELEASE:=3-20220422
PKG_VERSION:=1.1
PKG_RELEASE:=1
include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature

View File

@ -4,14 +4,13 @@ function index()
if not nixio.fs.access("/etc/config/weburl") then return end
entry({"admin", "control"}, firstchild(), "Control", 44).dependent = false
entry({"admin", "control", "weburl"}, cbi("weburl"), _("网址过滤"), 12).dependent =
true
entry({"admin", "control", "weburl"}, cbi("weburl"), _("URL Filter"), 12).dependent = true
entry({"admin", "control", "weburl", "status"}, call("status")).leaf = true
end
function status()
local e = {}
e.status = luci.sys.call("iptables -L FORWARD |grep WEBURL >/dev/null") == 0
e.status = luci.sys.call("iptables -L FORWARD | grep WEBURL >/dev/null") == 0
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end

View File

@ -1,36 +1,46 @@
local o = require "luci.sys"
local a, t, e
a = Map("weburl", translate("网址过滤"), translate(
"在这里设置关键词过滤可以是URL里任意字符可以过滤如视频网站、QQ、迅雷、淘宝。。。"))
a = Map("weburl", translate("URL Filter"), translate("Set keyword filtering here, can be any character in the URL, can filter such as video sites, QQ, thunder, Taobao..."))
a.template = "weburl/index"
t = a:section(TypedSection, "basic", translate("Running Status"))
t.anonymous = true
e = t:option(DummyValue, "weburl_status", translate("当前状态"))
e = t:option(DummyValue, "weburl_status", translate("Running Status"))
e.template = "weburl/weburl"
e.value = translate("Collecting data...")
t = a:section(TypedSection, "basic", translate("基本设置"), translate(
"一般来说普通过滤效果就很好了强制过滤会使用更复杂的算法导致更高的CPU占用。"))
t = a:section(TypedSection, "basic", translate("Basic setting"), translate("In general, normal filtering works fine, but forced filtering uses more complex algorithms and leads to higher CPU usage."))
t.anonymous = true
e = t:option(Flag, "enable", translate("开启"))
e = t:option(Flag, "enable", translate("Enable"))
e.rmempty = false
e = t:option(Flag, "algos", translate("强效过滤"))
e = t:option(Flag, "algos", translate("Forced filter"))
e.rmempty = false
t = a:section(TypedSection, "macbind", translate("关键词设置"), translate(
"黑名单MAC不设置为全客户端过滤如设置只过滤指定的客户端。过滤时间可不设置。"))
t = a:section(TypedSection, "macbind", translate("Keyword setting"), translate("MAC addresses do not filter out all clients. For example, only specified clients are filtered out. Filtering time is optional."))
t.template = "cbi/tblsection"
t.anonymous = true
t.addremove = true
e = t:option(Flag, "enable", translate("开启控制"))
e = t:option(Flag, "enable", translate("Enable"))
e.rmempty = false
e = t:option(Value, "macaddr", translate("黑名单MAC"))
e = t:option(Value, "macaddr", translate("MAC Address"))
e.rmempty = true
o.net.mac_hints(function(t, a) e:value(t, "%s (%s)" % {t, a}) end)
e = t:option(Value, "timeon", translate("开始过滤时间"))
e = t:option(Value, "timeon", translate("Start time"))
e.placeholder = "00:00"
e.rmempty = true
e = t:option(Value, "timeoff", translate("取消过滤时间"))
e = t:option(Value, "timeoff", translate("End time"))
e.placeholder = "23:59"
e.rmempty = true
e = t:option(Value, "keyword", translate("网址关键词"))
e = t:option(Value, "keyword", translate("Keyword"))
e.rmempty = false
return a

View File

@ -4,8 +4,47 @@ msgstr "管控"
msgid "Running Status"
msgstr "运行状态"
msgid "Collecting data..."
msgstr "正在收集数据..."
msgid "NOT RUNNING"
msgstr "未运行"
msgid "RUNNING"
msgstr "运行中"
msgid "URL Filter"
msgstr "网址过滤"
msgid "Set keyword filtering here, can be any character in the URL, can filter such as video sites, QQ, thunder, Taobao..."
msgstr "在这里设置关键词过滤可以是URL里任意字符可以过滤如视频网站、QQ、迅雷、淘宝。。。"
msgid "Basic setting"
msgstr "基本设置"
msgid "In general, normal filtering works fine, but forced filtering uses more complex algorithms and leads to higher CPU usage."
msgstr "一般来说普通过滤效果就很好了强制过滤会使用更复杂的算法导致更高的CPU占用。"
msgid "Enable"
msgstr "启用"
msgid "Forced filter"
msgstr "强效过滤"
msgid "Keyword setting"
msgstr "关键词设置"
msgid "MAC addresses do not filter out all clients. For example, only specified clients are filtered out. Filtering time is optional."
msgstr "MAC不设置为全客户端过滤如设置只过滤指定的客户端。过滤时间可不设置。"
msgid "MAC Address"
msgstr "MAC 地址"
msgid "Start time"
msgstr "开始时间"
msgid "End time"
msgstr "结束时间"
msgid "Keyword"
msgstr "关键字"

View File

@ -1,79 +1,21 @@
#!/bin/sh /etc/rc.common
#
# Copyright (C) 2015 OpenWrt-dist
# Copyright (C) 2016 fw867 <ffkykzs@gmail.com>
#
# This is free software, licensed under the GNU General Public License v3.
# See /LICENSE for more information.
#
# Copyright (C) 2024 Lienol
START=99
WEBURL_ENABLE=0
WEBURL_ALGOS=
is_true() {
case $1 in
1|on|true|yes|enabled) echo 0;;
*) echo 1;;
esac
}
get_algo_mode(){
if [ "x$1" = "x1" ]; then
echo "kmp"
else
echo "bm"
fi
}
iptables_w(){
iptables -w 1 "$@"
}
add_rule(){
local settime
local macaddr
local enable
local timeon
local timeoff
local keyword
config_get enable "$1" enable "0"
config_get macaddr "$1" macaddr
config_get timeon "$1" timeon
config_get timeoff "$1" timeoff
config_get keyword "$1" keyword
if [ -z "$enable" ] || [ $enable = 0 ] || [ -z "$keyword" ]; then
return
fi
if [ -z "$timeon" ] || [ -z "$timeoff" ]; then
settime=""
else
settime="-m time --kerneltz --timestart $timeon --timestop $timeoff"
fi
if [ -z $macaddr ]; then
iptables_w -t filter -I WEBURL_RULES $settime -m string --string "$keyword" --algo $WEBURL_ALGOS -j WEBURL_REJECT
else
iptables_w -t filter -I WEBURL_RULES $settime -m mac --mac-source $macaddr -m string --string "$keyword" --algo $WEBURL_ALGOS -j WEBURL_REJECT
fi
}
weburl_header() {
local algos
config_get WEBURL_ENABLE "$1" enable "0"
config_get algos "$1" algos "0"
WEBURL_ALGOS=$(get_algo_mode $algos)
}
CONFIG=weburl
ipt="iptables -w"
ip6t="ip6tables -w"
start(){
config_load weburl
config_foreach weburl_header basic
[ "x`is_true $WEBURL_ENABLE`" = "x0" ] || return 0
iptables_w -L FORWARD | grep -c WEBURL 2>/dev/null && [ $? -eq 0 ] && return 0;
stop
ENABLED=$(uci -q get ${CONFIG}.@basic[0].enable || echo "0")
[ "${ENABLED}" != "1" ] && exit 0
ALGOS=$(uci -q get ${CONFIG}.@basic[0].algos || echo "0")
WEBURL_ALGOS="bm"
[ "${ALGOS}" = "1" ] && WEBURL_ALGOS="kmp"
# resolve interface
local interface=$(
. /lib/functions/network.sh
@ -81,28 +23,68 @@ start(){
network_is_up "lan" && network_get_device device "lan"
echo "${device:-br-lan}"
)
iptables_w -t filter -N WEBURL_REJECT
iptables_w -t filter -F WEBURL_REJECT
iptables_w -t filter -I WEBURL_REJECT -j DROP
iptables_w -t filter -I WEBURL_REJECT -p tcp -j REJECT --reject-with tcp-reset
iptables_w -t filter -N WEBURL_RULES
iptables_w -t filter -F WEBURL_RULES
config_foreach add_rule macbind
iptables_w -t filter -N WEBURL
iptables_w -t filter -F WEBURL
iptables_w -t filter -I WEBURL -i $interface -m length --length 53:768 -j WEBURL_RULES
# iptables_w -t filter -I WEBURL -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables_w -t filter -I FORWARD -m comment --comment "Rule For Control" -j WEBURL
$ipt -t filter -N WEBURL_REJECT
$ipt -t filter -I WEBURL_REJECT -j DROP
$ipt -t filter -I WEBURL_REJECT -p tcp -j REJECT --reject-with tcp-reset
$ipt -t filter -N WEBURL_RULES
$ipt -t filter -N WEBURL
$ipt -t filter -I WEBURL -i $interface -m length --length 53:768 -j WEBURL_RULES
# $ipt -t filter -I WEBURL -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
$ipt -t filter -I FORWARD -j WEBURL
$ip6t -t filter -N WEBURL_REJECT 2>/dev/null
$ip6t -t filter -I WEBURL_REJECT -j DROP 2>/dev/null
$ip6t -t filter -I WEBURL_REJECT -p tcp -j REJECT --reject-with tcp-reset 2>/dev/null
$ip6t -t filter -N WEBURL_RULES 2>/dev/null
$ip6t -t filter -N WEBURL 2>/dev/null
$ip6t -t filter -I WEBURL -i $interface -m length --length 53:768 -j WEBURL_RULES 2>/dev/null
# $ip6t -t filter -I WEBURL -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT 2>/dev/null
$ip6t -t filter -I FORWARD -j WEBURL 2>/dev/null
local items=$(uci show ${CONFIG} | grep "=macbind" | cut -d '.' -sf 2 | cut -d '=' -sf 1)
for i in $items; do
enable=$(uci -q get ${CONFIG}.${i}.enable || echo "0")
macaddr=$(uci -q get ${CONFIG}.${i}.macaddr)
timeon=$(uci -q get ${CONFIG}.${i}.timeon)
timeoff=$(uci -q get ${CONFIG}.${i}.timeoff)
keyword=$(uci -q get ${CONFIG}.${i}.keyword)
if [ "$enable" == "0" ] || [ -z "$keyword" ]; then
continue
fi
if [ -z "$timeon" ] || [ -z "$timeoff" ]; then
settime=""
else
settime="-m time --kerneltz --timestart $timeon --timestop $timeoff"
fi
if [ -z "$macaddr" ]; then
$ipt -t filter -I WEBURL_RULES $settime -m string --string "$keyword" --algo $WEBURL_ALGOS -j WEBURL_REJECT
$ip6t -t filter -I WEBURL_RULES $settime -m string --string "$keyword" --algo $WEBURL_ALGOS -j WEBURL_REJECT 2>/dev/null
else
$ipt -t filter -I WEBURL_RULES $settime -m mac --mac-source $macaddr -m string --string "$keyword" --algo $WEBURL_ALGOS -j WEBURL_REJECT
$ip6t -t filter -I WEBURL_RULES $settime -m mac --mac-source $macaddr -m string --string "$keyword" --algo $WEBURL_ALGOS -j WEBURL_REJECT 2>/dev/null
fi
unset enable macaddr timeon timeoff keyword
done
logger -t weburl "weburl filter on $interface"
}
stop(){
iptables_w -t filter -D FORWARD -m comment --comment "Rule For Control" -j WEBURL
iptables_w -t filter -F WEBURL
iptables_w -t filter -X WEBURL
iptables_w -t filter -F WEBURL_RULES
iptables_w -t filter -X WEBURL_RULES
iptables_w -t filter -F WEBURL_REJECT
iptables_w -t filter -X WEBURL_REJECT
$ipt -t filter -D FORWARD -j WEBURL 2>/dev/null
$ipt -t filter -F WEBURL 2>/dev/null
$ipt -t filter -X WEBURL 2>/dev/null
$ipt -t filter -F WEBURL_RULES 2>/dev/null
$ipt -t filter -X WEBURL_RULES 2>/dev/null
$ipt -t filter -F WEBURL_REJECT 2>/dev/null
$ipt -t filter -X WEBURL_REJECT 2>/dev/null
$ip6t -t filter -D FORWARD -j WEBURL 2>/dev/null
$ip6t -t filter -F WEBURL 2>/dev/null
$ip6t -t filter -X WEBURL 2>/dev/null
$ip6t -t filter -F WEBURL_RULES 2>/dev/null
$ip6t -t filter -X WEBURL_RULES 2>/dev/null
$ip6t -t filter -F WEBURL_REJECT 2>/dev/null
$ip6t -t filter -X WEBURL_REJECT 2>/dev/null
}

View File

@ -203,8 +203,10 @@ if has_singbox then
o.rmempty = false
o = s:option(Value, "geoip_url", translate("Custom geoip URL"))
o.default = "https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db"
o:value("https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db")
o.default = "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.db"
o:value("https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geoip.db")
o:value("https://github.com/1715173329/sing-geoip/releases/latest/download/geoip.db")
o:value("https://github.com/lyc8503/sing-box-rules/releases/latest/download/geoip.db")
o.rmempty = false
o = s:option(Value, "geosite_path", translate("Custom geosite Path"))
@ -212,8 +214,10 @@ if has_singbox then
o.rmempty = false
o = s:option(Value, "geosite_url", translate("Custom geosite URL"))
o.default = "https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db"
o:value("https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db")
o.default = "https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.db"
o:value("https://github.com/MetaCubeX/meta-rules-dat/releases/download/latest/geosite.db")
o:value("https://github.com/1715173329/sing-geosite/releases/latest/download/geosite.db")
o:value("https://github.com/lyc8503/sing-box-rules/releases/latest/download/geosite.db")
o.rmempty = false
o = s:option(Button, "_remove_resource", translate("Remove resource files"))

View File

@ -7,8 +7,8 @@ include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI support for Time Control
LUCI_PKGARCH:=all
PKG_VERSION:=1.1
PKG_RELEASE:=20220505
PKG_VERSION:=1.2
PKG_RELEASE:=1
include $(TOPDIR)/feeds/luci/luci.mk

View File

@ -6,6 +6,7 @@ TIMECONTROL_ENABLE=0
iptables_w(){
iptables -w 1 "$@"
ip6tables -w 1 "$@" 2>/dev/null
}
add_rule(){

View File

@ -9,12 +9,12 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=xunyou
PKG_VERSION:=2.0.4.5
PKG_VERSION:=2.0.5.1
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)_v$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://partnerdownload.xunyou.com/routerplugin/koolshare/
PKG_HASH:=00d8dfd34dc4033c53f7e751edc2f7e266f951c4dca0f22a6e77cbe6d813ddab
PKG_HASH:=09871cc45b321a556a7faff329ab04d40c536e64eb98665e143317dd6367c252
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)_v$(PKG_VERSION)