From 7fd46d769340e8078fcb00266c01df7287d8865c Mon Sep 17 00:00:00 2001
From: SukkaW
Date: Fri, 10 May 2019 18:42:06 +0800
Subject: [PATCH 1/6] refactor: remove chromecast
---
docs/ui.md | 1 -
docs/usage.md | 4 +++-
koolclash/scripts/koolclash_control.sh | 27 -------------------------
koolclash/scripts/koolclash_firewall.sh | 3 +--
koolclash/webs/Module_koolclash.asp | 13 +-----------
5 files changed, 5 insertions(+), 43 deletions(-)
diff --git a/docs/ui.md b/docs/ui.md
index 86faf45..3492a0f 100755
--- a/docs/ui.md
+++ b/docs/ui.md
@@ -23,7 +23,6 @@
![](/img/ui-3.png)
- IP/CIDR 白名单:不通过 Clash 的 IP/CIDR 外网地址,一行一个
-- Chromecast 开关:是否劫持局域网内的 DNS 请求到 Clash
- 默认主机设置:Clash 全局代理控制
diff --git a/docs/usage.md b/docs/usage.md
index b86436b..c03d4a4 100755
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -94,7 +94,9 @@ KoolClash 启动以后,你可以通过检查「Clash 运行状态」和「IP
?> KoolClash 的 IP/CIDR 白名单已经包含所有局域网 IP 段和保留 IP 段,无需在这里重复提交。
-### Chromecast
+### ~~Chromecast~~
+
+?> 从 KoolClash `0.17.0-beta` 版本开始,KoolClash 使用 Clash 的 Fake-IP,不再提供 Chromecast 功能。
启用 Chromecast 功能后,将会劫持使用 UDP 协议发往不位于当前 LAN 网段的 53 端口的所有请求、并转发给 Clash,最终返回 Clash 给出的解析结果(即劫持常规 DNS 解析)。
diff --git a/koolclash/scripts/koolclash_control.sh b/koolclash/scripts/koolclash_control.sh
index 2da4bfb..3d0b316 100755
--- a/koolclash/scripts/koolclash_control.sh
+++ b/koolclash/scripts/koolclash_control.sh
@@ -139,11 +139,6 @@ flush_nat() {
iptables -t nat -F koolclash >/dev/null 2>&1 && iptables -t nat -X koolclash >/dev/null 2>&1
iptables -t mangle -F koolclash >/dev/null 2>&1 && iptables -t mangle -X koolclash >/dev/null 2>&1
- echo_date "停用 Chromecast(劫持 DNS)功能"
- # flush chromecast
- chromecast_nu=$(iptables -t nat -L PREROUTING -v -n --line-numbers | grep "dpt:53" | awk '{print $1}')
- iptables -t nat -D PREROUTING $chromecast_nu >/dev/null 2>&1
-
#flush_ipset
echo_date "删除 KoolClash 添加的 ipsets 名单"
ipset -F koolclash_white >/dev/null 2>&1 && ipset -X koolclash_white >/dev/null 2>&1
@@ -182,27 +177,6 @@ add_white_black_ip() {
}
#--------------------------------------------------------------------------
-chromecast() {
- chromecast_nu=$(iptables -t nat -L PREROUTING -v -n --line-numbers | grep "dpt:53" | awk '{print $1}')
- is_right_lanip=$(iptables -t nat -L PREROUTING -v -n --line-numbers | grep "dpt:53" | grep "$lan_ip")
- if [ $koolclash_firewall_chromecast == "true" ]; then
- if [ -z "$chromecast_nu" ]; then
- iptables -t nat -A PREROUTING -p udp -s $(get_lan_cidr) --dport 53 -j DNAT --to $lan_ip >/dev/null 2>&1
- echo_date '启用 Chromecast(劫持 DNS)'
- else
- if [ -z "$is_right_lanip" ]; then
- echo_date '启用 Chromecast(劫持 DNS)'
- iptables -t nat -D PREROUTING $chromecast_nu >/dev/null 2>&1
- iptables -t nat -A PREROUTING -p udp -s $(get_lan_cidr) --dport 53 -j DNAT --to $lan_ip >/dev/null 2>&1
- else
- echo_date '检测到 DNS 劫持功能已经启用'
- fi
- fi
- else
- echo_date '不启用 Chromecast(劫持 DNS)功能'
- fi
-}
-
get_mode_name() {
case "$1" in
0)
@@ -334,7 +308,6 @@ load_nat() {
creat_ipset
add_white_black_ip
apply_nat_rules
- chromecast
}
start_koolclash() {
diff --git a/koolclash/scripts/koolclash_firewall.sh b/koolclash/scripts/koolclash_firewall.sh
index 8e8b0b6..93eb19d 100755
--- a/koolclash/scripts/koolclash_firewall.sh
+++ b/koolclash/scripts/koolclash_firewall.sh
@@ -10,8 +10,7 @@ wan_ip=$(ubus call network.interface.wan status | grep \"address\" | grep -oE '[
case $2 in
white)
- dbus set koolclash_firewall_chromecast=$3
- dbus set koolclash_firewall_whiteip_base64=$4
+ dbus set koolclash_firewall_whiteip_base64=$3
http_response 'ok'
;;
default)
diff --git a/koolclash/webs/Module_koolclash.asp b/koolclash/webs/Module_koolclash.asp
index 7613929..c809e5c 100755
--- a/koolclash/webs/Module_koolclash.asp
+++ b/koolclash/webs/Module_koolclash.asp
@@ -575,13 +575,6 @@
value: Base64.decode(window.dbus.koolclash_firewall_whiteip_base64 || '') || '',
style: 'width: 80%; height: 150px;'
},
- {
- title: 'Chromecast 开关
强烈建议暂时不要使用!
',
- name: 'koolclash-chromecast-switch',
- prefix: '
',
- type: 'checkbox',
- style: `margin-top:16px;`
- },
]);
$('#koolclash-acl-default-panel').forms([
@@ -644,8 +637,6 @@
$('#_koolclash-acl-default-port-user').hide();
}
- document.getElementById('_koolclash-chromecast-switch').checked = (window.dbus.koolclash_firewall_chromecast === 'true') ? true : false;
-
$('.koolclash-nav-log').on('click', KoolClash.getLog);
},
// 选择 Tab
@@ -1327,7 +1318,6 @@ KoolClash 版本:${window.dbus.koolclash_version}
Clash 核心版本:${data.clash_version}
KoolClash 当前状态:${(window.dbus.koolclash_enable === '1') ? `Clash 进程正在运行` : `Clash 进程未在运行`}
用户指定 Clash 外部控制 Host:${(window.dbus.koolclash_api_host) ? koolclash_api_host : `未改动`}
-Chromecast(劫持 DNS)是否启用:${window.dbus.koolclash_firewall_chromecast}
IP 数据库是否存在:${data.ipdb_exists}
-------------------------- Clash 进程信息 --------------------------
${Base64.decode(data.clash_process)}
@@ -1371,14 +1361,13 @@ ${Base64.decode(data.firewall_white_ip)}
submitWhiteIP: () => {
KoolClash.disableAllButton();
let data = Base64.encode(document.getElementById('_koolclash_firewall_white_ipset').value);
- let chromecast = document.getElementById('_koolclash-chromecast-switch').checked;
document.getElementById('koolclash-btn-submit-white-ip').innerHTML = `正在提交`;
let id = parseInt(Math.random() * 100000000),
postData = JSON.stringify({
id,
"method": "koolclash_firewall.sh",
- "params": ['white', `${chromecast}`, `${data}`],
+ "params": ['white', `${data}`],
"fields": ""
});
From 0e90030a2938472457b6c84b0893d4bd19fd6dd0 Mon Sep 17 00:00:00 2001
From: SukkaW
Date: Sat, 11 May 2019 02:18:15 +0800
Subject: [PATCH 2/6] feat(fake-dns): add 198.19.0.0/24 as fake-dns
---
koolclash/scripts/koolclash_control.sh | 12 ++++++++++++
koolclash/scripts/koolclash_debug.sh | 4 +++-
koolclash/webs/Module_koolclash.asp | 6 ++++++
3 files changed, 21 insertions(+), 1 deletion(-)
diff --git a/koolclash/scripts/koolclash_control.sh b/koolclash/scripts/koolclash_control.sh
index 3d0b316..b84dbd8 100755
--- a/koolclash/scripts/koolclash_control.sh
+++ b/koolclash/scripts/koolclash_control.sh
@@ -124,6 +124,8 @@ flush_nat() {
iptables -t nat -D PREROUTING -p tcp -j koolclash >/dev/null 2>&1
iptables -t mangle -D PREROUTING -p tcp -j koolclash >/dev/null 2>&1
+ iptables -t nat -D PREROUTING -p tcp -j koolclash_dns >/dev/null 2>&1
+ iptables -t mangle -D PREROUTING -p tcp -j koolclash_dns >/dev/null 2>&1
nat_indexs=$(iptables -nvL PREROUTING -t nat | sed 1,2d | sed -n '/clash/=' | sort -r)
for nat_index in $nat_indexs; do
@@ -138,6 +140,8 @@ flush_nat() {
# flush iptables rules
iptables -t nat -F koolclash >/dev/null 2>&1 && iptables -t nat -X koolclash >/dev/null 2>&1
iptables -t mangle -F koolclash >/dev/null 2>&1 && iptables -t mangle -X koolclash >/dev/null 2>&1
+ iptables -t nat -F koolclash_dns >/dev/null 2>&1 && iptables -t nat -X koolclash_dns >/dev/null 2>&1
+ iptables -t mangle -F koolclash_dns >/dev/null 2>&1 && iptables -t mangle -X koolclash_dns >/dev/null 2>&1
#flush_ipset
echo_date "删除 KoolClash 添加的 ipsets 名单"
@@ -289,7 +293,11 @@ apply_nat_rules() {
# iptables -t nat -A koolclash -j $(get_action_chain $ss_acl_default_mode)
iptables -t nat -N koolclash
+ iptables -t nat -N koolclash_dns
iptables -t nat -A PREROUTING -p tcp -j koolclash
+ iptables -t nat -A PREROUTING -p tcp -j koolclash_dns
+ iptables -t nat -A PREROUTING -p udp -j koolclash_dns
+
# IP Whitelist
# 包括路由器本机 IP
@@ -297,6 +305,10 @@ apply_nat_rules() {
# Free 22 SSH
iptables -t nat -A koolclash -p tcp --dport 22 -j ACCEPT
#iptables -t nat -A koolclash -p tcp -m set --match-set koolclash_black dst -j REDIRECT --to-ports 23456
+
+ iptables -t nat -A koolclash_dns -p udp --dport 53 -d 198.19.0.0/24 -j DNAT --to-destination $lan_ip:23453
+ iptables -t nat -A koolclash_dns -p tcp --dport 53 -d 198.19.0.0/24 -j DNAT --to-destination $lan_ip:23453
+
# Redirect all tcp traffic to 23456
lan_access_control
}
diff --git a/koolclash/scripts/koolclash_debug.sh b/koolclash/scripts/koolclash_debug.sh
index 6994581..ac79c0e 100755
--- a/koolclash/scripts/koolclash_debug.sh
+++ b/koolclash/scripts/koolclash_debug.sh
@@ -50,6 +50,8 @@ iptables_mangle=$(iptables -nvL PREROUTING -t mangle | sed 1,2d | grep 'clash' |
iptables_nat=$(iptables -nvL PREROUTING -t nat | sed 1,2d | grep 'clash' | base64 | base64 | xargs)
iptables_mangle_clash=$(iptables -nvL koolclash -t mangle | sed 1,2d | base64 | base64 | xargs)
iptables_nat_clash=$(iptables -nvL koolclash -t nat | sed 1,2d | base64 | base64 | xargs)
+iptables_mangle_clash_dns=$(iptables -nvL koolclash_dns -t mangle | sed 1,2d | base64 | base64 | xargs)
+iptables_nat_clash_dns=$(iptables -nvL koolclash_dns -t nat | sed 1,2d | base64 | base64 | xargs)
white_ip=$(ipset list koolclash_white | base64 | xargs)
@@ -57,4 +59,4 @@ chromecast_nu=$(iptables -t nat -L PREROUTING -v -n --line-numbers | grep "dpt:5
clash_process=$(ps | grep clash | grep -v grep | base64 | xargs)
-http_response "{ \\\"lan_ip\\\": \\\"${lan_ip}\\\", \\\"koolshare_version\\\": \\\"$koolshare_version\\\", \\\"origin_exists\\\": \\\"$origin_exists\\\", \\\"config_exists\\\": \\\"$config_exists\\\", \\\"clash_allow_lan\\\": \\\"$clash_allow_lan\\\", \\\"clash_ext_controller\\\": \\\"$clash_ext_controller\\\", \\\"clash_dns_enable\\\": \\\"$clash_dns_enable\\\", \\\"clash_dns_ipv6\\\": \\\"$clash_dns_ipv6\\\", \\\"clash_dns_mode\\\": \\\"$clash_dns_mode\\\", \\\"clash_dns_listen\\\": \\\"$clash_dns_listen\\\", \\\"fallbackdns\\\": \\\"$fallbackdns\\\", \\\"iptables_mangle\\\": \\\"$iptables_mangle\\\", \\\"iptables_nat\\\": \\\"$iptables_nat\\\", \\\"iptables_mangle_clash\\\": \\\"$iptables_mangle_clash\\\", \\\"iptables_nat_clash\\\": \\\"$iptables_nat_clash\\\", \\\"clash_redir\\\": \\\"$clash_redir\\\", \\\"firewall_white_ip\\\": \\\"$white_ip\\\", \\\"chromecast_nu\\\": \\\"$chromecast_nu\\\", \\\"clash_process\\\": \\\"$clash_process\\\", \\\"clash_version\\\": \\\"$clash_version\\\", \\\"ipdb_exists\\\": \\\"$ipdb_exists\\\"}"
+http_response "{ \\\"lan_ip\\\": \\\"${lan_ip}\\\", \\\"koolshare_version\\\": \\\"$koolshare_version\\\", \\\"origin_exists\\\": \\\"$origin_exists\\\", \\\"config_exists\\\": \\\"$config_exists\\\", \\\"clash_allow_lan\\\": \\\"$clash_allow_lan\\\", \\\"clash_ext_controller\\\": \\\"$clash_ext_controller\\\", \\\"clash_dns_enable\\\": \\\"$clash_dns_enable\\\", \\\"clash_dns_ipv6\\\": \\\"$clash_dns_ipv6\\\", \\\"clash_dns_mode\\\": \\\"$clash_dns_mode\\\", \\\"clash_dns_listen\\\": \\\"$clash_dns_listen\\\", \\\"fallbackdns\\\": \\\"$fallbackdns\\\", \\\"iptables_mangle\\\": \\\"$iptables_mangle\\\", \\\"iptables_nat\\\": \\\"$iptables_nat\\\", \\\"iptables_mangle_clash\\\": \\\"$iptables_mangle_clash\\\", \\\"iptables_nat_clash\\\": \\\"$iptables_nat_clash\\\", \\\"iptables_mangle_clash_dns\\\": \\\"$iptables_mangle_clash_dns\\\", \\\"iptables_nat_clash_dns\\\": \\\"$iptables_nat_clash_dns\\\", \\\"clash_redir\\\": \\\"$clash_redir\\\", \\\"firewall_white_ip\\\": \\\"$white_ip\\\", \\\"chromecast_nu\\\": \\\"$chromecast_nu\\\", \\\"clash_process\\\": \\\"$clash_process\\\", \\\"clash_version\\\": \\\"$clash_version\\\", \\\"ipdb_exists\\\": \\\"$ipdb_exists\\\"}"
diff --git a/koolclash/webs/Module_koolclash.asp b/koolclash/webs/Module_koolclash.asp
index c809e5c..6ab63c1 100755
--- a/koolclash/webs/Module_koolclash.asp
+++ b/koolclash/webs/Module_koolclash.asp
@@ -1348,6 +1348,12 @@ ${Base64.decode(Base64.decode(data.iptables_mangle_clash))}
* iptables nat 中 koolclash 链
${Base64.decode(Base64.decode(data.iptables_nat_clash))}
+* iptables mangle 中 koolclash_dns 链
+${Base64.decode(Base64.decode(data.iptables_mangle_clash_dns))}
+
+ * iptables nat 中 koolclash_dns 链
+${Base64.decode(Base64.decode(data.iptables_nat_clash_dns))}
+
* iptables nat 中 Chromecast 相关条目
${Base64.decode(data.chromecast_nu)}
---------------------- ipset 白名单 IP 列表 ------------------------
From aaee74c32a2b32299739efec37ce3f4297af1c07 Mon Sep 17 00:00:00 2001
From: SukkaW
Date: Sat, 11 May 2019 13:31:19 +0800
Subject: [PATCH 3/6] feat(fake-ip): replace redir-host
---
docs/usage.md | 5 +++--
koolclash/scripts/koolclash_control.sh | 8 +++----
koolclash/scripts/koolclash_save_config.sh | 25 +++++++++++++++++-----
koolclash/scripts/koolclash_status.sh | 2 +-
koolclash/scripts/koolclash_sub.sh | 24 +++++++++++++++++----
koolclash/webs/Module_koolclash.asp | 2 +-
6 files changed, 49 insertions(+), 17 deletions(-)
diff --git a/docs/usage.md b/docs/usage.md
index c03d4a4..134f459 100755
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -24,7 +24,8 @@ KoolClash 也已经支持自动从托管配置自动下载更新 Clash 配置文
> 「合法的 DNS 配置」包括
> - `dns.enable = true`
-> - `dns.enhanced-mode = redir-host`
+> - `dns.enhanced-mode = redir-host`(KoolClash 0.16.2 及其之前的版本)
+> - `dns.enhanced-mode = fake-ip`(KoolClash 0.16.2 之后的版本)
以下是一个推荐的 自定义 DNS 配置 的示范:
@@ -32,7 +33,7 @@ KoolClash 也已经支持自动从托管配置自动下载更新 Clash 配置文
dns:
enable: true
listen: 0.0.0.0:53
- enhanced-mode: redir-host
+ enhanced-mode: fake-ip
nameserver:
- 119.29.29.29
- 119.28.28.28
diff --git a/koolclash/scripts/koolclash_control.sh b/koolclash/scripts/koolclash_control.sh
index b84dbd8..8e5c085 100755
--- a/koolclash/scripts/koolclash_control.sh
+++ b/koolclash/scripts/koolclash_control.sh
@@ -383,7 +383,7 @@ start)
stop_koolclash
echo "XU6J03M6"
else
- if [ $(yq r $KSROOT/koolclash/config/config.yml dns.enable) == 'true' ] && [ $(yq r $KSROOT/koolclash/config/config.yml dns.enhanced-mode) == 'redir-host' ]; then
+ if [ $(yq r $KSROOT/koolclash/config/config.yml dns.enable) == 'true' ] && [ $(yq r $KSROOT/koolclash/config/config.yml dns.enhanced-mode) == 'fake-ip' ]; then
echo_date "KoolClash 执行开机自动启动"
start_koolclash
echo "XU6J03M6"
@@ -409,7 +409,7 @@ start_after_install)
echo_date "没有找到 Clash 的配置文件,中断启动并回滚操作!"
stop_koolclash
else
- if [ $(yq r $KSROOT/koolclash/config/config.yml dns.enable) == 'true' ] && [ $(yq r $KSROOT/koolclash/config/config.yml dns.enhanced-mode) == 'redir-host' ]; then
+ if [ $(yq r $KSROOT/koolclash/config/config.yml dns.enable) == 'true' ] && [ $(yq r $KSROOT/koolclash/config/config.yml dns.enhanced-mode) == 'fake-ip' ]; then
start_koolclash
else
echo_date "没有找到 DNS 配置或 DNS 配置不合法,中断启动并回滚操作!"
@@ -425,7 +425,7 @@ start_after_install)
stop_koolclash
echo "XU6J03M6"
else
- if [ $(yq r $KSROOT/koolclash/config/config.yml dns.enable) == 'true' ] && [ $(yq r $KSROOT/koolclash/config/config.yml dns.enhanced-mode) == 'redir-host' ]; then
+ if [ $(yq r $KSROOT/koolclash/config/config.yml dns.enable) == 'true' ] && [ $(yq r $KSROOT/koolclash/config/config.yml dns.enhanced-mode) == 'fake-ip' ]; then
echo_date "KoolClash 执行开机自动启动"
start_koolclash
echo "XU6J03M6"
@@ -455,7 +455,7 @@ start)
echo_date ------------------ 请不要关闭或者刷新页面!倒计时结束时会自动刷新! ------------------ >>/tmp/upload/koolclash_log.txt
echo "XU6J03M6" >>/tmp/upload/koolclash_log.txt
else
- if [ $(yq r $KSROOT/koolclash/config/config.yml dns.enable) == 'true' ] && [ $(yq r $KSROOT/koolclash/config/config.yml dns.enhanced-mode) == 'redir-host' ]; then
+ if [ $(yq r $KSROOT/koolclash/config/config.yml dns.enable) == 'true' ] && [ $(yq r $KSROOT/koolclash/config/config.yml dns.enhanced-mode) == 'fake-ip' ]; then
http_response 'success'
start_koolclash >/tmp/upload/koolclash_log.txt
echo_date ------------------ 请不要关闭或者刷新页面!倒计时结束时会自动刷新! ------------------ >>/tmp/upload/koolclash_log.txt
diff --git a/koolclash/scripts/koolclash_save_config.sh b/koolclash/scripts/koolclash_save_config.sh
index 7d86d51..5e6e315 100755
--- a/koolclash/scripts/koolclash_save_config.sh
+++ b/koolclash/scripts/koolclash_save_config.sh
@@ -45,8 +45,23 @@ yq w -i $KSROOT/koolclash/config/origin.yml external-controller "$ext_control_ip
cp $KSROOT/koolclash/config/origin.yml $KSROOT/koolclash/config/config.yml
-# 判断是否存在 DNS 字段、DNS 是否启用、DNS 是否使用 redir-host 模式
-if [ $(yq r $KSROOT/koolclash/config/config.yml dns.enable) == 'true' ] && [ $(yq r $KSROOT/koolclash/config/config.yml dns.enhanced-mode) == 'redir-host' ]; then
+#---------------------------------------------------------------------
+# 强制覆盖 DNS、Fake-IP 的设置
+
+overwrite_dns_config() {
+ # 确保启用 DNS
+ yq w -i $KSROOT/koolclash/config/config.yml dns.enable "true"
+ # 修改端口
+ yq w -i $KSROOT/koolclash/config/config.yml dns.listen "0.0.0.0:23453"
+ # 修改模式
+ yq w -i $KSROOT/koolclash/config/config.yml dns.enhanced-mode "fake-ip"
+ # Fake IP Range
+ yq w -i $KSROOT/koolclash/config/config.yml dns.fake-ip-range "198.18.0.1/16"
+}
+#---------------------------------------------------------------------
+
+# 判断是否存在 DNS 字段、DNS 是否启用、DNS 是否使用 redir-host / fake-ip 模式
+if [ $(yq r $KSROOT/koolclash/config/config.yml dns.enable) == 'true' ] && [[ $(yq r $KSROOT/koolclash/config/config.yml dns.enhanced-mode) == 'fake-ip' || $(yq r $KSROOT/koolclash/config/config.yml dns.enhanced-mode) == 'redir-host' ]]; then
if [ "$koolclash_dnsmode" == "2" ] && [ -n "$fallbackdns" ]; then
# dnsmode 是 2 应该用自定义 DNS 配置进行覆盖
echo_date "删除 Clash 配置文件中原有的 DNS 配置"
@@ -55,6 +70,7 @@ if [ $(yq r $KSROOT/koolclash/config/config.yml dns.enable) == 'true' ] && [ $(y
echo_date "将提交的自定义 DNS 设置覆盖 Clash 配置文件..."
# 将后备 DNS 配置以覆盖的方式与 config.yml 合并
yq m -x -i $KSROOT/koolclash/config/config.yml $KSROOT/koolclash/config/dns.yml
+
dbus set koolclash_dnsmode=2
else
# 可能 dnsmode 是 2 但是没有自定义 DNS 配置;或者本来之前就是 1
@@ -62,7 +78,7 @@ if [ $(yq r $KSROOT/koolclash/config/config.yml dns.enable) == 'true' ] && [ $(y
fi
# 先将 Clash DNS 设置监听 53,以后作为 dnsmasq 的上游以后需要改变端口
- yq w -i $KSROOT/koolclash/config/config.yml dns.listen "0.0.0.0:23453"
+ overwrite_dns_config
echo_date "Clash 配置文件上传成功!"
http_response 'success'
else
@@ -81,8 +97,7 @@ else
yq d -i $KSROOT/koolclash/config/config.yml dns
yq m -x -i $KSROOT/koolclash/config/config.yml $KSROOT/koolclash/config/dns.yml
- # 先将 Clash DNS 设置监听 53,以后作为 dnsmasq 的上游以后需要改变端口
- yq w -i $KSROOT/koolclash/config/config.yml dns.listen "0.0.0.0:23453"
+ overwrite_dns_config
echo_date "Clash 配置文件上传成功!"
http_response 'success'
diff --git a/koolclash/scripts/koolclash_status.sh b/koolclash/scripts/koolclash_status.sh
index bad7a94..a90c4b7 100755
--- a/koolclash/scripts/koolclash_status.sh
+++ b/koolclash/scripts/koolclash_status.sh
@@ -28,7 +28,7 @@ if [ ! -f $KSROOT/koolclash/config/config.yml ]; then
elif [ $koolclash_dnsmode = 2 ]; then
# Clash 配置文件存在且 DNS 配置合法,但是用户选择了自定义 DNS 配置,显示 DNS 配置输入,dnsmode 为 2
dnsmode=2
-elif [ $(yq r $KSROOT/koolclash/config/origin.yml dns.enable) == 'true' ] && [ $(yq r $KSROOT/koolclash/config/origin.yml dns.enhanced-mode) == 'redir-host' ]; then
+elif [ $(yq r $KSROOT/koolclash/config/origin.yml dns.enable) == 'true' ] && [ $(yq r $KSROOT/koolclash/config/origin.yml dns.enhanced-mode) == 'fake-ip' ]; then
# Clash 配置文件存在且 DNS 配置合法,不显示 DNS 配置输入,dnsmode 为 1
dbus set koolclash_dnsmode=1
dnsmode=1
diff --git a/koolclash/scripts/koolclash_sub.sh b/koolclash/scripts/koolclash_sub.sh
index f175119..626f6bd 100755
--- a/koolclash/scripts/koolclash_sub.sh
+++ b/koolclash/scripts/koolclash_sub.sh
@@ -18,6 +18,22 @@ else
ext_control_ip=$koolclash_api_host
fi
+#---------------------------------------------------------------------
+# 强制覆盖 DNS、Fake-IP 的设置
+
+overwrite_dns_config() {
+ # 确保启用 DNS
+ yq w -i $KSROOT/koolclash/config/config.yml dns.enable "true"
+ # 修改端口
+ yq w -i $KSROOT/koolclash/config/config.yml dns.listen "0.0.0.0:23453"
+ # 修改模式
+ yq w -i $KSROOT/koolclash/config/config.yml dns.enhanced-mode "fake-ip"
+ # Fake IP Range
+ yq w -i $KSROOT/koolclash/config/config.yml dns.fake-ip-range "198.18.0.1/16"
+}
+#---------------------------------------------------------------------
+
+
case $2 in
del)
dbus remove koolclash_suburl
@@ -60,8 +76,8 @@ update)
cp $KSROOT/koolclash/config/origin.yml $KSROOT/koolclash/config/config.yml
- # 判断是否存在 DNS 字段、DNS 是否启用、DNS 是否使用 redir-host 模式
- if [ $(yq r $KSROOT/koolclash/config/config.yml dns.enable) == 'true' ] && [ $(yq r $KSROOT/koolclash/config/config.yml dns.enhanced-mode) == 'redir-host' ]; then
+ # 判断是否存在 DNS 字段、DNS 是否启用、DNS 是否使用 redir-host / fake-ip 模式
+ if [ $(yq r $KSROOT/koolclash/config/config.yml dns.enable) == 'true' ] && [[ $(yq r $KSROOT/koolclash/config/config.yml dns.enhanced-mode) == 'fake-ip' || $(yq r $KSROOT/koolclash/config/config.yml dns.enhanced-mode) == 'redir-host' ]]; then
if [ "$koolclash_dnsmode" == "2" ] && [ -n "$fallbackdns" ]; then
# dnsmode 是 2 应该用自定义 DNS 配置进行覆盖
echo_date "删除 Clash 配置文件中原有的 DNS 配置"
@@ -77,7 +93,7 @@ update)
fi
# 先将 Clash DNS 设置监听 53,以后作为 dnsmasq 的上游以后需要改变端口
- yq w -i $KSROOT/koolclash/config/config.yml dns.listen "0.0.0.0:23453"
+ overwrite_dns_config
echo_date "Clash 配置文件上传成功!"
http_response 'success'
else
@@ -97,7 +113,7 @@ update)
yq m -x -i $KSROOT/koolclash/config/config.yml $KSROOT/koolclash/config/dns.yml
# 先将 Clash DNS 设置监听 53,以后作为 dnsmasq 的上游以后需要改变端口
- yq w -i $KSROOT/koolclash/config/config.yml dns.listen "0.0.0.0:23453"
+ overwrite_dns_config
echo_date "Clash 配置文件上传成功!"
http_response 'success'
diff --git a/koolclash/webs/Module_koolclash.asp b/koolclash/webs/Module_koolclash.asp
index 6ab63c1..863b8b2 100755
--- a/koolclash/webs/Module_koolclash.asp
+++ b/koolclash/webs/Module_koolclash.asp
@@ -686,7 +686,7 @@ dns:
enable: true
ipv6: false
listen: 0.0.0.0:53
- enhanced-mode: redir-host
+ enhanced-mode: fake-ip
nameserver:
- 119.28.28.28
- 119.29.29.29
From dce7e414841424ca98610100af46dccde09a990e Mon Sep 17 00:00:00 2001
From: SukkaW
Date: Sat, 11 May 2019 13:38:01 +0800
Subject: [PATCH 4/6] refactor(dnsmasq): remove dnsmasq forward
---
koolclash/scripts/koolclash_control.sh | 60 +++++++++----------
koolclash/scripts/koolclash_save_config.sh | 1 -
.../scripts/koolclash_save_dns_config.sh | 34 +++++++----
koolclash/scripts/koolclash_sub.sh | 4 +-
4 files changed, 56 insertions(+), 43 deletions(-)
diff --git a/koolclash/scripts/koolclash_control.sh b/koolclash/scripts/koolclash_control.sh
index 8e5c085..8933336 100755
--- a/koolclash/scripts/koolclash_control.sh
+++ b/koolclash/scripts/koolclash_control.sh
@@ -20,15 +20,15 @@ get_lan_cidr() {
}
#--------------------------------------------------------------------------
-restore_dnsmasq_conf() {
- echo_date "删除 KoolClash 的 dnsmasq 配置..."
- rm -rf /tmp/dnsmasq.d/koolclash.conf
-
- echo_date "还原 DHCP/DNS 中 resolvfile 配置..."
- uci set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.auto
- uci set dhcp.@dnsmasq[0].noresolv=0
- uci commit dhcp
-}
+#restore_dnsmasq_conf() {
+# echo_date "删除 KoolClash 的 dnsmasq 配置..."
+# rm -rf /tmp/dnsmasq.d/koolclash.conf
+#
+# echo_date "还原 DHCP/DNS 中 resolvfile 配置..."
+# uci set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.auto
+# uci set dhcp.@dnsmasq[0].noresolv=0
+# uci commit dhcp
+#}
restore_start_file() {
echo_date "删除 KoolClash 的防火墙配置"
@@ -54,23 +54,23 @@ kill_process() {
#fi
}
-create_dnsmasq_conf() {
- echo_date "删除 DHCP/DNS 中 resolvfile 和 cachesize 配置"
- dhcp_server=$(uci get dhcp.@dnsmasq[0].server 2>/dev/null)
- if [ $dhcp_server ]; then
- uci delete dhcp.@dnsmasq[0].server >/dev/null 2>&1
- fi
- uci delete dhcp.@dnsmasq[0].resolvfile
- uci delete dhcp.@dnsmasq[0].cachesize
- uci set dhcp.@dnsmasq[0].noresolv=1
- uci commit dhcp
-
- touch /tmp/dnsmasq.d/koolclash.conf
- echo_date "修改 dnsmasq 配置使 dnsmasq 将所有的 DNS 请求转发给 Clash"
- echo "no-resolv" >>/tmp/dnsmasq.d/koolclash.conf
- echo "server=127.0.0.1#23453" >>/tmp/dnsmasq.d/koolclash.conf
- echo "cache-size=0" >>/tmp/dnsmasq.d/koolclash.conf
-}
+#create_dnsmasq_conf() {
+# echo_date "删除 DHCP/DNS 中 resolvfile 和 cachesize 配置"
+# dhcp_server=$(uci get dhcp.@dnsmasq[0].server 2>/dev/null)
+# if [ $dhcp_server ]; then
+# uci delete dhcp.@dnsmasq[0].server >/dev/null 2>&1
+# fi
+# uci delete dhcp.@dnsmasq[0].resolvfile
+# uci delete dhcp.@dnsmasq[0].cachesize
+# uci set dhcp.@dnsmasq[0].noresolv=1
+# uci commit dhcp
+#
+# touch /tmp/dnsmasq.d/koolclash.conf
+# echo_date "修改 dnsmasq 配置使 dnsmasq 将所有的 DNS 请求转发给 Clash"
+# echo "no-resolv" >>/tmp/dnsmasq.d/koolclash.conf
+# echo "server=127.0.0.1#23453" >>/tmp/dnsmasq.d/koolclash.conf
+# echo "cache-size=0" >>/tmp/dnsmasq.d/koolclash.conf
+#}
restart_dnsmasq() {
# Restart dnsmasq
@@ -329,12 +329,12 @@ start_koolclash() {
[ -n "$ONSTART" ] && echo_date 路由器开机触发 KoolClash 启动! || echo_date web 提交操作触发 KoolClash 启动!
echo_date ---------------------------------------------------------------------------------
# stop first
- restore_dnsmasq_conf
+ # restore_dnsmasq_conf
flush_nat
restore_start_file
kill_process
echo_date ---------------------------------------------------------------------------------
- create_dnsmasq_conf
+ # create_dnsmasq_conf
auto_start
start_clash_process
@@ -345,7 +345,7 @@ start_koolclash() {
echo_date '【即将关闭 KoolClash 并还原所有操作】'
echo_date ------------------------------- KoolClash 启动中断 -------------------------------
sleep 2
- restore_dnsmasq_conf
+ # restore_dnsmasq_conf
restart_dnsmasq
flush_nat
restore_start_file
@@ -365,7 +365,7 @@ start_koolclash() {
stop_koolclash() {
echo_date --------------------- KoolClash: Clash on Koolshare OpenWrt ---------------------
- restore_dnsmasq_conf
+ # restore_dnsmasq_conf
restart_dnsmasq
flush_nat
restore_start_file
diff --git a/koolclash/scripts/koolclash_save_config.sh b/koolclash/scripts/koolclash_save_config.sh
index 5e6e315..c5eb0d6 100755
--- a/koolclash/scripts/koolclash_save_config.sh
+++ b/koolclash/scripts/koolclash_save_config.sh
@@ -77,7 +77,6 @@ if [ $(yq r $KSROOT/koolclash/config/config.yml dns.enable) == 'true' ] && [[ $(
dbus set koolclash_dnsmode=1
fi
- # 先将 Clash DNS 设置监听 53,以后作为 dnsmasq 的上游以后需要改变端口
overwrite_dns_config
echo_date "Clash 配置文件上传成功!"
http_response 'success'
diff --git a/koolclash/scripts/koolclash_save_dns_config.sh b/koolclash/scripts/koolclash_save_dns_config.sh
index 3aa420f..68d241b 100755
--- a/koolclash/scripts/koolclash_save_dns_config.sh
+++ b/koolclash/scripts/koolclash_save_dns_config.sh
@@ -5,6 +5,21 @@ source $KSROOT/scripts/base.sh
alias echo_date='echo 【$(date +%Y年%m月%d日\ %X)】:'
eval $(dbus export koolclash_)
+#---------------------------------------------------------------------
+# 强制覆盖 DNS、Fake-IP 的设置
+
+overwrite_dns_config() {
+ # 确保启用 DNS
+ yq w -i $KSROOT/koolclash/config/config.yml dns.enable "true"
+ # 修改端口
+ yq w -i $KSROOT/koolclash/config/config.yml dns.listen "0.0.0.0:23453"
+ # 修改模式
+ yq w -i $KSROOT/koolclash/config/config.yml dns.enhanced-mode "fake-ip"
+ # Fake IP Range
+ yq w -i $KSROOT/koolclash/config/config.yml dns.fake-ip-range "198.18.0.1/16"
+}
+#---------------------------------------------------------------------
+
touch $KSROOT/koolclash/config/dns.yml
echo $2 | base64 -d | tee $KSROOT/koolclash/config/dns.yml
@@ -29,8 +44,7 @@ if [ "$koolclash_dnsmode" == "1" ] && [ "$3" == "1" ]; then
# 将后备 DNS 配置以覆盖的方式与 config.yml 合并
yq m -x -i $KSROOT/koolclash/config/config.yml $KSROOT/koolclash/config/dns.yml
- # 先将 Clash DNS 设置监听 23453,以后作为 dnsmasq 的上游以后需要改变端口
- yq w -i $KSROOT/koolclash/config/config.yml dns.listen 0.0.0.0:23453
+ overwrite_dns_config
# 强制生效 DNS 配置,修改 dnsmode 为 2
dbus set koolclash_dnsmode=2
echo_date "后备 DNS 设置提交成功!"
@@ -41,7 +55,7 @@ elif [ "$koolclash_dnsmode" == "2" ] && [ "$3" == "0" ]; then
# 但是取消勾选了 DNS 配置文件的勾,是想要还原原始 Clash 配置文件
rm -rf $KSROOT/koolclash/config/config.yml
cp $KSROOT/koolclash/config/origin.yml $KSROOT/koolclash/config/config.yml
- yq w -i $KSROOT/koolclash/config/config.yml dns.listen 0.0.0.0:23453
+ overwrite_dns_config
dbus set koolclash_dnsmode=1
echo_date "自定义 DNS 设置提交成功!"
http_response 'success'
@@ -51,7 +65,7 @@ elif [ "$koolclash_dnsmode" == "2" ] && [ "$3" == "1" ]; then
# 看来你是想还原原始 Clash 配置文件同时还删除自定义 DNS 配置
rm -rf $KSROOT/koolclash/config/config.yml
cp $KSROOT/koolclash/config/origin.yml $KSROOT/koolclash/config/config.yml
- yq w -i $KSROOT/koolclash/config/config.yml dns.listen 0.0.0.0:23453
+ overwrite_dns_config
dbus set koolclash_dnsmode=1
echo_date "自定义 DNS 设置提交成功!"
http_response 'success'
@@ -64,8 +78,8 @@ elif [ "$koolclash_dnsmode" == "2" ] && [ "$3" == "1" ]; then
# 将后备 DNS 配置以覆盖的方式与 config.yml 合并
yq m -x -i $KSROOT/koolclash/config/config.yml $KSROOT/koolclash/config/dns.yml
- # 先将 Clash DNS 设置监听 23453,以后作为 dnsmasq 的上游以后需要改变端口
- yq w -i $KSROOT/koolclash/config/config.yml dns.listen 0.0.0.0:23453
+
+ overwrite_dns_config
# 强制生效 DNS 配置,修改 dnsmode 为 2
dbus set koolclash_dnsmode=2
echo_date "后备 DNS 设置提交成功!"
@@ -85,8 +99,8 @@ elif [ "$koolclash_dnsmode" == "3" ]; then
# 将后备 DNS 配置以覆盖的方式与 config.yml 合并
yq m -x -i $KSROOT/koolclash/config/config.yml $KSROOT/koolclash/config/dns.yml
- # 先将 Clash DNS 设置监听 53,以后作为 dnsmasq 的上游以后需要改变端口
- yq w -i $KSROOT/koolclash/config/config.yml dns.listen 0.0.0.0:23453
+
+ overwrite_dns_config
echo_date "后备 DNS 设置提交成功!"
http_response 'success'
@@ -105,8 +119,8 @@ elif [ "$koolclash_dnsmode" == "4" ]; then
# 将后备 DNS 配置以覆盖的方式与 config.yml 合并
yq m -x -i $KSROOT/koolclash/config/config.yml $KSROOT/koolclash/config/dns.yml
- # 先将 Clash DNS 设置监听 53,以后作为 dnsmasq 的上游以后需要改变端口
- yq w -i $KSROOT/koolclash/config/config.yml dns.listen 0.0.0.0:23453
+
+ overwrite_dns_config
echo_date "后备 DNS 设置提交成功!"
http_response 'success'
diff --git a/koolclash/scripts/koolclash_sub.sh b/koolclash/scripts/koolclash_sub.sh
index 626f6bd..87340fd 100755
--- a/koolclash/scripts/koolclash_sub.sh
+++ b/koolclash/scripts/koolclash_sub.sh
@@ -92,7 +92,7 @@ update)
dbus set koolclash_dnsmode=1
fi
- # 先将 Clash DNS 设置监听 53,以后作为 dnsmasq 的上游以后需要改变端口
+
overwrite_dns_config
echo_date "Clash 配置文件上传成功!"
http_response 'success'
@@ -112,7 +112,7 @@ update)
yq d -i $KSROOT/koolclash/config/config.yml dns
yq m -x -i $KSROOT/koolclash/config/config.yml $KSROOT/koolclash/config/dns.yml
- # 先将 Clash DNS 设置监听 53,以后作为 dnsmasq 的上游以后需要改变端口
+
overwrite_dns_config
echo_date "Clash 配置文件上传成功!"
From b042777acfd3d84915f03eb245855a243284f417 Mon Sep 17 00:00:00 2001
From: SukkaW
Date: Sat, 11 May 2019 15:21:24 +0800
Subject: [PATCH 5/6] docs(fake-ip): update
---
README.md | 3 ++-
docs/README.md | 7 ++++---
docs/img/ui-3.png | Bin 49454 -> 41475 bytes
docs/update-uninstall.md | 15 +++++++++------
docs/usage.md | 26 ++++++++++++++++++++++----
5 files changed, 37 insertions(+), 14 deletions(-)
diff --git a/README.md b/README.md
index e46dcad..58729df 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,8 @@ A rule based custom proxy for Koolshare OpenWrt/LEDE based on
-
+
@@ -31,6 +31,7 @@
+> KoolClash 尽可以在 Koolshare OpenWrt/LEDE x86_64 上使用。如果你使用的是原版 OpenWrt,请使用 [Clash for OpenWrt](https://github.com/frainzy1477/clash/)。
## 名词解释
@@ -47,8 +48,8 @@
除了 Clash 的这些特性,KoolClash 有以下特性:
-- 在 [Koolshare OpenWrt/LEDE X86](https://firmware.koolshare.cn/LEDE_X64_fw867/) 上安装、加载配置并运行 Clash
-- 实现透明代理
+- 在 [Koolshare OpenWrt/LEDE X86](https://firmware.koolshare.cn/LEDE_X64_fw867/) 上安装、上传配置并运行 Clash
+- 和 Surge 增强模式类似的代理网关
## 安装
diff --git a/docs/img/ui-3.png b/docs/img/ui-3.png
index b0828b87be4f86c2456d218f58efa104dfd761be..5544216965b6b594eb88d14662acf114b169ff00 100755
GIT binary patch
literal 41475
zcmce;1yogS+b+5QMJ1#`X+c3mx;q6$1*D}*KpN@p5&@Nv4iQkgyCp12x=ZPlW)bIJ
z_$j_bbe>sg_S^0K&C#V-e>DgpU==9TKx-EKO5Q-GR|j
z`TEWzdG{_?`7r^mg&)UVbt!$KT&AP(Q%OtDG;_Ng>MD%bB3`nvxG>3RU9`lG9+bns
z9dbFq_ABn&g~+1HD-Wt%4Kh;qX&QcX>ADxL1{iw}9Tk)tuO;iq;}e`8Z$4aj<#aLR
z@9~8K!-?+iamBDnUi$pFDSEpRaFPDd?l`6&;Uq7)35%bt7f*DESxoP-j&EY1X@
zA;v1LrJg?z?e=sOq)IthQb%)N1AKv?h7<{@%yDyw-I8OZDI2@n_>rQzfco=&i>Z
z94VCglsLq0T}1R)a~qBg<_{OyWpsF*mQjSem`(|4AU8E5Ywm~lElI1JGP=3D6I{C%
z(o@9##kd6R`$6sLofxbwL8?2#wVLaQ>_`Y6G@Shq>h+yU^RbG_W#%+UR)3IEuArK73ci&DCdfxYB9J``Ntw>T|t7$(e1gU#9|O
zqGy=?X!imGXBUnvpI(=HC|B$?hZ$*aGu1#sw?=SulrBZJf-?zL5S`Ansmuh}W&nXA0vRDE_U#bcRi
z>qHRosuZ)hWl6w|v}!?rjV?~o8P%Qq@bUaP|#4h|0D3{lNy+*hv^b+on3
zpxB@A_$RdA0TI*t1W|!65q@Dp@x-vR(Rk%OOv}-_>rC6quT#A*BVI>Eg_V>(
zyUoPZ+>T3O@R5V|tmj7K!k`)VaMg2qr}bgqg9DdFzOFSH`d96|iw=U36i!tG3UY!%
zf}4YrB8$t*E%p18VNXj<=MoDW+j}!)x8Sr!qk;d_{*^?x`x_np
zx$5r1rsW!&dt)~A%*@|&^N{wOg&C6?$y8Jajot?sHMO;ua7EqR-PoW1ym{P5q(G~Y
zzUfi2VPDW|_S$<9pBU?w+{1@&JohIQKdE?n({rZMw9eFd>G@{&4D$@zO}Z{ncc?6%g86(9WFQ7n=3(
zvCBsNK0YC#ACq$S5zEHmV^%41O>$oAsy`HT9+!62pFRz}7e*?Psg$0RgB2PY+GECz
zp+``;A)x29Hp!#-yzoeF!g+TpeRD3dcyFfs^`%RAHQsV^cZ@l&>w5ks`SojFGP}><
zBnVfLNra+td@3qBS|vKxx@|9i%!7~itItwjHa!aqZmsiL%bX`}iGV=0ZsVa=rPV!6
z&4eN3Tx*QbrR$hpc!5)Fbad}69xI_Ct+1`7!qYLY*b}n5JGJ;A1<~$y{%Fywu=yOA
zK>jE!jN&KDFSt75dXd5B_6C|+UmFp&{(k+12r8F9pR$kFGy0Y`OTEvo>mK!`woZQX
z)tpOpJ$fG5A+@AaJxN(#fAH&oF(fox!rq>1bW|G`+sex7;CQ>6fP^HlJxJ#6R}DX(
zCh@{Qy5SUvB>AQryzjI}2B#>rDqMs`7o8?j7Hb9imK+e68@~^_&kpb+JJyE=_1VRV
z2z6b!`e7&+m+3>q}V%a<=Vr~Px^#Km1`
zVruYSPimNK6{TVzs;FzYxV9z}x%OMn>k8t&d`j4*p}h9r-`_n^*9sfbbMKsU%~T2<
zuo%40z`wNSNJ~qL5IfBFmh{lBtD2ax1?P9&na09>cs2O*esfZRKAWg0wW_LKGYlwG
z#ntmPu)V;yjE=z(U_&zR4_IVk0GA*y?Ymxl>1)C#s>X-OSpxU
zd7ThDzcp;gn^9a$5Jt-4H)1LC#Nb9wZmvi}X=}-e`@%#6-lbVxF})=PW
zi#-z2-iNnLIuing$TIOX+pjRrcPlg>A2NOX#8Fitpfe>#{q%`^Hz%IhF}u^+XrNO@
zud`Hs-$2z_t3v99ajz}U25c!8@1wK)y-LHjmuRVg49KrMxVZY@>x27p^6T#02Uh8F
znXN=(o`i>o!J91`UVPIH)t+J>ii*N?z%N1`ICKQh$8e(
zm(N0W*QZ|ERKyi~j`7}(mNParbss;*z!;Yvr=9Xbvg~bm)9@yC8r621d`_9DMME?<
zH-kks=Z%!sf2-YJjoF*nIbHBRHf&OH@^vo^?7?8$>B87tG$1R;Ej+mpM2@lJCPJ;d
zvV6m#g=tcok%6J*iu$z5lPA8WDW`nJNjSr;#E%z
zw)w8)un*Gea&;rJSPjHgQ$L2h)$!u*BBIKpg0&|t?Jl}QQXMY0XGG9C-(#g-U-|0P
zeaEh4z=-j}ZxT-_xq#^(^_2<-)@XH&vH?CFB2;4{)8BQ9(IH0NzH@g63m=fpiz80O
zfaxX8tVKPRa!uSAxxgQJcVF2f^Bf)GiYki<%*#hjt6}`Y`^VeE4OSE{Uf2^1?du#b
z=X&prR(eNSD=QP_kz)J#lYGoM!b%9aeC*wL7~Z|{zB$p~Gb}9Z^M?1?rNXuKaQ4aF
zXgMw{MOD?n!aK|}4uV@-9W*zX1gw3M3#I`YU?Cf{Admx04PC7*75R22
zM$U4$sCUk$P3Myq#*gy*>ZW)AM#C||&XSXp`JLA(%SM^v@Ohdyyhuy07dHIC0<(XU
zkPw7R!S}Lx3$i2u1<{{myGJEF*|}kTY&Gu{2ZI
zxKxy!f!#r`n}6=
zp^Iv^f#A)X*)zVK%(RyxTb^W{_0E%}!L5!)4Z1iL
zL&7`wgi&v`3o|z^;%2_XLuAP(zr3Vg7^IXQ&}QB|W>f#WT*1VIw1l&?HBG3PZLvb*
zuFJNK4IMKx_S)Lo?Xwcf+@ZW6uyoR}>q|>vX#?hk{cRb}53$rIE4w1D5)%_o111QP
z%WQcS&-ErgKJ;~uVnAS^!QkqMt~Z5Wdl2SFl{?X~v67ie5)k2+m(9V`^Yj`gS5Cfu
z{d!MLE%us*d;<5CTBkKX8KRld;*A8{=q-fHRdqWB(Eg_vq;9i_LlsS4YdSBSnvHtK7K3?(A$dRG{-kn|9|b>Cr=F@C6^Wl|Ce68VI6Keze-7^L
z>%(XoXxjS9m`cmYH?-k_&cyWT;DqMXN2k`QS!7F$k&z5f`1Qh8H48H{hV8S-w-ps?
zmg8m5?>}Fsw-UGOpoW@?9QWK&34ulc9_JG&pSng<{y
zYp{?)g7!;qpSGtfcFG_Sa$aqsUm3i?%1XWD?3T4sef9-gY!kxI!SBLTyoy~B##i>-
z6%=jUF6kZPo^^FSMLj0mbV5QD$i21CT;0N9*{QCiV-;3y1<69U-h8`8d@Y1VWRHIJ
zGLH1uc&<1u)2nKEb$GtMXd1VpYX
z0MDO42avm6bx7hyAe-1`*}gT`v9(rhzqr2Kk}h?LV3o9NY?ar+*)je7dvvu#-0Rn`
zQ>WVHtA**E{!!HNcYo3q$#hTD;R83hGh%=h%}hhFlDFEx3T|SrlXZVrGX9C02m2MntlZ^KA1an$|I!
z#_-iu%O6Ps_B}`OohEggwNp2ESa6xu^2Fuk3;1KT7X@rAEQm^TS^N8^A@{eowz_x(
zUkhI|<06NI?UDIu-)7M+
z+EP9IHau-a%arRFt1r}vE%>a|yKc3S^$ZVRo|aRn?zx@UYqkmCj9%;v-}v>RrG9vL
z==DGB0qKV4VKnFo-f*Lcv;1m3saKh*|BwDPn@3rv0n`H3)ry~@VHN$AK1r*p#tcWX
zj9<_Z=;~=N5kRBt5(@y_@gXxSv|CkO9R)gKVq&QIOeE7LhlfKLQ{Aw(?6z#tLm~m&
z=?HBd9PJJl8PMM)<pbat2{PSfJUp^}h#wkdE*y6~`5M8A#a|LjUY&x1*>-;CIS18*
zXOO2e8JliEubH%x(%X*K7pHD-S#``Mot!FU<&GyS_jF62PwcIZgfA|dAz%fs5)wtx
zz9QF2h!0#0C9*r%G|1Df$Lto_ual)3SDroDoqy;{RIutxbGjK^q;a=MGarK2!D2=v
zJ|*R=rY7;Y+FB0R64Dv+?jLwDO1BCgaoD}Lc*~us6bNOQ3dDO}hP|4BF;sP3EKW2d
zRJ0ZNZhrJpVjs
zjOyAwi&zmGc`uhq=HP0=$P26E5j|)jwg(?cUV~NIqgk+FijgE5d(?s&41)M$t#)Ojlw^Nci_V
z`4B!CvXNj~L8@ZM>D`V^%6&hNl*W?{F{RH&CXkOME@k&E+1al?gin|Av1Z+5y1G$jpxBrAGK
zyG2)eX?aJxQbfX%le!Ch!j_;fZ
z>5-=8;24OW_NS9IEsz<{_UIOlP3g&g;PE|_ri)ShFCc=zIZZ~_3B3a
zTymJ5ixic#nEDe{US3XZukYctcQ?nnal$HsdQi{MQRCMil~
zVJ0$-nX0hLt*W0e3n^1oy
z9=!}DpmBC|oGBM`S7^F`h%z+9zlJ}(T~S*0q1EUu4T4%^)$erWG4@h6#%>XEHeh8Q
z`NnZ&bKLuk&(P3tvyU-#r{Rqgl58^tzi0oN)6!lO-cT>SEPlaNSsfiJ&eDRN0xcHO
zxX}{@ZFMaz=B}G~RenpSu;SQETMxNPTXm05>la!aVk=!b}rNdtN(N*mx8O`8V@KXr?PR
znU}W=^X@#mfk!PI;(rN`j)w=AqnM*dT3S3~i^dGOY;Z|CUb_2a|7<0eyXTQZYNMlCE-qwz_%|{#^0ASuK!npb)jrdsaBD_87WA7lj-uY`w(-+%O|wTnuq$ZX57?&uqH#^}S@
zRrh2)k5hs6PXp}bm8f}yiQ|mNdGMg%sh7~BtOko2tux10C;6$9-t|lAJ4Hw%Zt`Ns
z6*b7#X`N=R%xsOqi{(3Hw)damAj^L`ED>U1W4{r0W@V632xv2G4!H6}igiPDDXHm7
zcE^t`(RbS`jaEJ>_x2ww1klQTQZby!h(xn}UsC_mw3_0Uuy#0OiVHgU*=)u4&d!6)
z&v*ooEr5rhf8o=eEo6YRoz$1yNPi+)W08^h2iG9)r*fG2;@kn>`nj
z#Y&KTm6zfwHUBinWJ7s53FEHY@S2ldVzYkJC*^DuNxX7R#)!hu$gs%kGbRA_hpP_?
z3kur%&gM10W_SlBrhO>8&|bk?Xp!G5-DHU(lO-^(8yXpT#L~R#aTlZHQ}$x2gL1^Cy(>7sEz`
zm+Nodi6Im_WE^^R$e=8w>oRi@a3d`pCn28LpUeH`2EqkrD~lFXMtUNv;o-OiSA36N
zeF)ak#=6Z}!gfy`;G>9tx9~~XF9xHU-hj#N;K72nXeQ;&qm@E>M#f8WnUWr7mb^lD
zNyEn6-2;L4_Mbm(uIMzODKhoC*>Lxa(0y-Jrb-5*Tu}QsTBqih$n~-CUl-WzW~J@a
zcD}#Uk$C@k#%IF1<8XU{!)lb9n~%?^J4NI&&gFoS@o)iq!up6?JNnp6gZ@BmWBNDy
z08Zkc!7^95Lqd#o5z+nNM}Vu?xIbhm_Wo<*3?p@%+V>y5aYhzw4}HFx#^&Cn+Vuig
zX{Ru7eVuhka22XrKnzy-`3HN)m0!BLf*vtQIXjd2G*f&`vVEVof&2wgRo~J=3OXY$
zGl68UQ&L1fY&@GX8Ww3}2^L&RdRLejw>yCkYQ(kX*a*{X~u>$H?s@?3xhn!
zd^(5~f2-wfpxeonFVhM7b~ncp%>!-`2F75FtLIe@c-x1BEFQg)Zqn7$i-dX|(S+Qn
z4+cU487E*LJ9WZhGUV1SndZcQ*5mWN6b+-Wd0AA;RoeJh)12_sFkQp|saJclZMgph
zTFf;`{q+DMsB3iV)g==$iRABYJnW|KBz4`_ZRqJy9FKY9yFpIQF2GBgo}Mn1lh{bT
z2Uw0$(BZep%aB*C$_gTZVs!`a<6e%6#WXYmb_SCDN1OoBMH;V={xa^!Ch4kAgzXvR
zW8tU?geZB7gXkgvgr7>tx~&vssVU9Y9*KOQ`4%`H5=
zKH({q1<)wPyNd_=FiJs~zFz-oALq+NRilwkI0#(pM8wEZ@Okp(6#T_t}bU9pxa2pGsptnrU(AzCe|YpEY5`2|o?H^!u+PCeL?xWn)=yt!FsOpmyP8X3t^~Hv4Wcj-H#UyGZPI#ZyS+mmBXD7?Q
z0yYHq3bTnP@xn&@6e4J3WlcNMkP+Av!MCnoSInvFc!xc%SNX#zY{8LoRq%^P^!E6?
zSIo)w?!H}S-I@IZ-~B1f>BFyeC01!ei(dJj^)x5lb1OBUE%c_Qgw#dPQZ^zM+`WI}
zs7I_F4y#x9-t^DSKHQx7d{C2v1q2%~o}X6(F5J~?pyc4-kUFBQ_0C2jt*#&Je|AqS
zv^Vq-G4}elf96hdfbG#Ccs68^*7)YsTWWG6d_hQ1Sn6bg;IzSda6c#{q#&iuoZ^YV
zgA1$ceD{viGqjR7(rjsu6VtV#3VmW5>7kc;^Bz6!@U1t5Yy&AK?|W$jxz*nn`!owc
zJ9uKXj;xR2Z|C{_laBx2y2bz2f+ptv>BsVpP4BxK{)9@qNUG?lDlH$?*(aK{JE*34
zFUwtrB)9*my7960Ld$>;?-(2?EhOm
z=CQ)xR=-1EZNji?E1J7LVj&kgqNs!X%Rp-vy?iL1{=X)LJI%+(ha#2mpASh7;r*XT
z0seoSxqp{Ep!5Y37(j0fa=uy(r{_w0h$+2QN&*Kjb8mlV9A(Ft)kdZ>#X^s1O>c^aWz)
z)<&SCb?#)g*aDPS&DsNXB9CyErrNzY&Fq}4VUU-a4
zc+{<8r(1YiE|9`Cs%&qlLlpOS;nF4d`q-a8mFo6JE&Lni
zq28NIJv&T=LJCpkw<~tCq`>ceS~tb{2Dp8mKdOA*UVoxeajMaL%-E9^mhktKcFolN
z!Q-rN)Sb~XaXLBB(dr+Z{FWF>XXVq@)}|aR)WZYV4o|1Qzdiw-^|O~y7)atoYiVjK
zDl7Y|=BhO>IT)h;2CQDO+paluCeonmAmp^_^LeIewk^yvMK+^%I$P|7sU7;F-C}2y
z8;xh835kituG=PC!jd|E{{D7HJI`0A8fgp+3^Xb%e*sX`L
z2*i5rhA5DO86_n@ZJMa@@qM5j3=3>*Vj{`<&ImQ)`9z!7NlB}!?_Ryafu6$qtgQKj
zI{A#=kRd&9s{L_$ypqz=t#%3<{omhWfPB0(jn$&(zQ%L>i&2cAvU+>44;ytP
z*4@d!t5-?gBdmBSP~1v9m#JjF+T8KsHt@%ByjBSsGN39U
zYdp9}dG%6KS9&-hfJg=)m7gdp(_^l#3knGtaK^I(aJTqV1F*#lIX3k&lE!oA$?;xg
zBlPOYb8>Z_i#49^7Pbvd(76Ajt!j@*q|&MQ!`aD(6hjo6ZMfq;Pk{&j92Nk1bPNoU3Y{ujw6k5kvx^YCqrL_J_l%O-ctzUH
z|A?39h*d}xomg-Rm%&Ju51yShw97jY|Cc_C+i9E_t+w_G5yN!6X^MolcG9(^R8dcI
zxNi?oKVE;^Sn7_fxdSf&Jx5w;=BrUE=qV}rIZt_#K{oe7hE*LM8=JA^Z+$vz3N7)cr6#xOsOdKWl+Fql^
z;gh;zK2#A9CZO0KH67{iSFx+BEZjc&*~kiHMsCgn8da>9S3Za51>
z-GcOdgZXxlIB>D9y7dQ#SkwKl1K3rIdz{UisE#e_=ym*W0cZbJBt4&NjV|%vHIQr&*505Ow9&ty@)K3&7hHd!KoMHKjf)(`12m
zmLgQBg$+ko5W^y;=2mvyq-A92Zrm`CE;KFc9~#Q2s=6j1AfT8#FuQkr?6K%j!?EvH
z5c}0wQbGbPmPLy}7Z02iPxJr*C2Eg(IW-b40X#U~(lGSaW_Ne?<2mCWLDH0Qa^fY%
zYU6Q%G6xO^u4~F@wQ9L-N4qQa73!+0GdoLt8s+9OvWPoyvyb`t_Y4ef!1EPZPY9~0
zs-htX2?_PfHSMOG&=BI#A8{!d9o2-!=7;QTy>~-Kobg34u5qU^D|M2aczZ|4-2D8u
z{!hvxd-;Wh!4uZ99v;UbD;#P(+}yOhyiWIrfiXBL(wnqI7o_+
zhUJ=1baX__iV{HOf*RWH?k)@sf^<8of;&F2yKwQM!AQw7U6D^P>f3kkwnAJAe*d1X
zvHnj-B+WiWlOqJvCOK%n?<*+C>g%Uf)mK)M(Rdx)F!>SZ3sIsO
z&;<+;B}8y@b4ydX^XBbaziRsh^iAuKFWud;o}TqC!jRDg?B{8DcvOWI&O9M-6M*Wa
zEsPAgT3?}=f18a>7J}!n1@-mo0%o+HGc6Yp;%;t&(DGN*)s2W@R+mgy3~6?8ap8xq
z_a)(oCb%ak^8CLV6HZ0VaMPaqUT>%Ak4vjlp8He~$RHPC;@CoxK%p404Nv4=s01@&
zXJ?02OpL~dS%V0jEl~0XX5PwR{Qw#t^8yqOl%TB1
zAbkDx_lsY@eu?J}w3wHpn!iBBp(ZGS$D&mb*c%`Q+`e=;Dx5SxDib|DFp7?eF#u)Y
ztY~Lv=i>Uh%%ev*2z4o0EiDQZO$}Kc+L+VB#YUGeUlxa^TlaPqA00P0_w-_K#^U0l
zILHFJJyF6`&>rFId2C&@u3h6Toa5o+lVW{0SKLAEFPSdx=_w*7Cx_`--}EZXe_HZfC+>n!#7a4yggo#9m18Rhaum!7WgnT|ctTFDokc@J6cprm&(qegcz!f5V
zFu3`7lhh6r)q-UpZS|g7qCe7Z*`mTbrR&
zF!16S4uO)sz#`h=AgP?keNT}47>L2Vrx=LYYffNYuV3RwJUiEgzb_VgSO+aGJ39^~
zC6LbZCgQ@h6Ln-^2k0}=(@TvrTrkwCu#|9h6#&mGe)gU8*TMn-bPS(^;|5P8#FjVU
z?w}Hhdz57`@FY{|#@)M*#z{da4dR(@(<6^(&u%3oBoskH6FxndvlUD}SS{^FRJA9o
ztEtTbf^46Q6pIK6xlBw(7PebHVj1%4RVzd{lrqJp@q`pw0a7^&CC|S1jE)LU$F0mP
zgK^s079BvFD&y0q2b5U)r6c&n#J^%V!IYI!pC6pQq7kD;^b8KpZyy2-Dl03a6%-s@
zsfHE@fVIyirJ;rO<>jh*8QQEJ6V6lN;5J+K)AG3kbT@BafawK>D~yb-9SVisi3yQu
zZ3LXiRm=C2%OwA^auZelzSruGTQgw0dpAHndwY>Y7iy0PN`YC9l;L;KcEILp!;U1u
zy67O7%wKz?SXNnyx5CqzETm4^h+E|r94?d5AqrKMuP=yRzW8*S_-nJ0t?&UWj1X5*
zAqJ5tAk+G;8{BG_1JXD|L{JM2VTneq>8_cjrL>I=8-&K?4`|B2xF|rVA#`A)
z63)(i=;-J@eSQ89q8QN5^-WMsOhY0=6^Q^QK_x_Im$ajJNdB4i%h#_GUS17xnY15r
z@MNL2QpyxQ=#~3^An4%x?Sn6?Av7F)*|n;kZMJZ8%zHj%>$AP=C+O
z*RCeKbd^&4{(a~Jl&jm+6ut_1`<5^uAOJENDK0K9z&0}*n-1vQa5yga8w`wi{;Y=J
zkkxv=tD$!odpJxiw2dN`ElIO38_6cC3g1qAeGL6
z3$%j}nor*|_+eGSNiZo60}N&3;B;_M?OHhWaWX^4paukmlRun^yc-HF^7pm1?qBMU
zSy-TE2KPzrR)}LqgQguUwJut%&<%0DI+v~2U1I|Sfw8fqcXjKofgQvA`$8K6YU7@f
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
literal 49454
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