diff --git a/.github/workflows/main.tmp b/.github/workflows/main.tmp
new file mode 100644
index 000000000..afe3205a6
--- /dev/null
+++ b/.github/workflows/main.tmp
@@ -0,0 +1,15 @@
+name: purge jsdelivr cache
+
+on:
+ release:
+ types: [created]
+ push:
+ workflow_dispatch:
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: purge jsdelivr cache
+ run: |
+ curl https://purge.jsdelivr.net/gh/jacyl4/de_GWD@main/client
diff --git a/.github/workflows/sha256sum.yml b/.github/workflows/sha256sum.yml
new file mode 100644
index 000000000..bd9c3ccc4
--- /dev/null
+++ b/.github/workflows/sha256sum.yml
@@ -0,0 +1,28 @@
+name: checkSUM
+
+on:
+ workflow_dispatch:
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: sha256sum
+ run: |
+ chmod +x sha256sum
+ ./sha256sum
+
+ - name: Commit
+ run: |
+ git config --global user.email jacyl4@gmail.com
+ git config --global user.name jacyl4
+ git add ./resource
+ git commit -am "Auto sha256sum"
+
+ - name: Push
+ uses: ad-m/github-push-action@master
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 000000000..9bea4330f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+
+.DS_Store
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100755
index 000000000..e23ece2c8
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,277 @@
+Eclipse Public License - v 2.0
+
+ THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+ PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION
+ OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+ a) in the case of the initial Contributor, the initial content
+ Distributed under this Agreement, and
+
+ b) in the case of each subsequent Contributor:
+ i) changes to the Program, and
+ ii) additions to the Program;
+ where such changes and/or additions to the Program originate from
+ and are Distributed by that particular Contributor. A Contribution
+ "originates" from a Contributor if it was added to the Program by
+ such Contributor itself or anyone acting on such Contributor's behalf.
+ Contributions do not include changes or additions to the Program that
+ are not Modified Works.
+
+"Contributor" means any person or entity that Distributes the Program.
+
+"Licensed Patents" mean patent claims licensable by a Contributor which
+are necessarily infringed by the use or sale of its Contribution alone
+or when combined with the Program.
+
+"Program" means the Contributions Distributed in accordance with this
+Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement
+or any Secondary License (as applicable), including Contributors.
+
+"Derivative Works" shall mean any work, whether in Source Code or other
+form, that is based on (or derived from) the Program and for which the
+editorial revisions, annotations, elaborations, or other modifications
+represent, as a whole, an original work of authorship.
+
+"Modified Works" shall mean any work in Source Code or other form that
+results from an addition to, deletion from, or modification of the
+contents of the Program, including, for purposes of clarity any new file
+in Source Code form that contains any contents of the Program. Modified
+Works shall not include works that contain only declarations,
+interfaces, types, classes, structures, or files of the Program solely
+in each case in order to link to, bind by name, or subclass the Program
+or Modified Works thereof.
+
+"Distribute" means the acts of a) distributing or b) making available
+in any manner that enables the transfer of a copy.
+
+"Source Code" means the form of a Program preferred for making
+modifications, including but not limited to software source code,
+documentation source, and configuration files.
+
+"Secondary License" means either the GNU General Public License,
+Version 2.0, or any later versions of that license, including any
+exceptions or additional permissions as identified by the initial
+Contributor.
+
+2. GRANT OF RIGHTS
+
+ a) Subject to the terms of this Agreement, each Contributor hereby
+ grants Recipient a non-exclusive, worldwide, royalty-free copyright
+ license to reproduce, prepare Derivative Works of, publicly display,
+ publicly perform, Distribute and sublicense the Contribution of such
+ Contributor, if any, and such Derivative Works.
+
+ b) Subject to the terms of this Agreement, each Contributor hereby
+ grants Recipient a non-exclusive, worldwide, royalty-free patent
+ license under Licensed Patents to make, use, sell, offer to sell,
+ import and otherwise transfer the Contribution of such Contributor,
+ if any, in Source Code or other form. This patent license shall
+ apply to the combination of the Contribution and the Program if, at
+ the time the Contribution is added by the Contributor, such addition
+ of the Contribution causes such combination to be covered by the
+ Licensed Patents. The patent license shall not apply to any other
+ combinations which include the Contribution. No hardware per se is
+ licensed hereunder.
+
+ c) Recipient understands that although each Contributor grants the
+ licenses to its Contributions set forth herein, no assurances are
+ provided by any Contributor that the Program does not infringe the
+ patent or other intellectual property rights of any other entity.
+ Each Contributor disclaims any liability to Recipient for claims
+ brought by any other entity based on infringement of intellectual
+ property rights or otherwise. As a condition to exercising the
+ rights and licenses granted hereunder, each Recipient hereby
+ assumes sole responsibility to secure any other intellectual
+ property rights needed, if any. For example, if a third party
+ patent license is required to allow Recipient to Distribute the
+ Program, it is Recipient's responsibility to acquire that license
+ before distributing the Program.
+
+ d) Each Contributor represents that to its knowledge it has
+ sufficient copyright rights in its Contribution, if any, to grant
+ the copyright license set forth in this Agreement.
+
+ e) Notwithstanding the terms of any Secondary License, no
+ Contributor makes additional grants to any Recipient (other than
+ those set forth in this Agreement) as a result of such Recipient's
+ receipt of the Program under the terms of a Secondary License
+ (if permitted under the terms of Section 3).
+
+3. REQUIREMENTS
+
+3.1 If a Contributor Distributes the Program in any form, then:
+
+ a) the Program must also be made available as Source Code, in
+ accordance with section 3.2, and the Contributor must accompany
+ the Program with a statement that the Source Code for the Program
+ is available under this Agreement, and informs Recipients how to
+ obtain it in a reasonable manner on or through a medium customarily
+ used for software exchange; and
+
+ b) the Contributor may Distribute the Program under a license
+ different than this Agreement, provided that such license:
+ i) effectively disclaims on behalf of all other Contributors all
+ warranties and conditions, express and implied, including
+ warranties or conditions of title and non-infringement, and
+ implied warranties or conditions of merchantability and fitness
+ for a particular purpose;
+
+ ii) effectively excludes on behalf of all other Contributors all
+ liability for damages, including direct, indirect, special,
+ incidental and consequential damages, such as lost profits;
+
+ iii) does not attempt to limit or alter the recipients' rights
+ in the Source Code under section 3.2; and
+
+ iv) requires any subsequent distribution of the Program by any
+ party to be under a license that satisfies the requirements
+ of this section 3.
+
+3.2 When the Program is Distributed as Source Code:
+
+ a) it must be made available under this Agreement, or if the
+ Program (i) is combined with other material in a separate file or
+ files made available under a Secondary License, and (ii) the initial
+ Contributor attached to the Source Code the notice described in
+ Exhibit A of this Agreement, then the Program may be made available
+ under the terms of such Secondary Licenses, and
+
+ b) a copy of this Agreement must be included with each copy of
+ the Program.
+
+3.3 Contributors may not remove or alter any copyright, patent,
+trademark, attribution notices, disclaimers of warranty, or limitations
+of liability ("notices") contained within the Program from any copy of
+the Program which they Distribute, provided that Contributors may add
+their own appropriate notices.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities
+with respect to end users, business partners and the like. While this
+license is intended to facilitate the commercial use of the Program,
+the Contributor who includes the Program in a commercial product
+offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes
+the Program in a commercial product offering, such Contributor
+("Commercial Contributor") hereby agrees to defend and indemnify every
+other Contributor ("Indemnified Contributor") against any losses,
+damages and costs (collectively "Losses") arising from claims, lawsuits
+and other legal actions brought by a third party against the Indemnified
+Contributor to the extent caused by the acts or omissions of such
+Commercial Contributor in connection with its distribution of the Program
+in a commercial product offering. The obligations in this section do not
+apply to any claims or Losses relating to any actual or alleged
+intellectual property infringement. In order to qualify, an Indemnified
+Contributor must: a) promptly notify the Commercial Contributor in
+writing of such claim, and b) allow the Commercial Contributor to control,
+and cooperate with the Commercial Contributor in, the defense and any
+related settlement negotiations. The Indemnified Contributor may
+participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those performance
+claims and warranties, and if a court requires any other Contributor to
+pay any damages as a result, the Commercial Contributor must pay
+those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
+PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS"
+BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF
+TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+PURPOSE. Each Recipient is solely responsible for determining the
+appropriateness of using and distributing the Program and assumes all
+risks associated with its exercise of rights under this Agreement,
+including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs
+or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
+PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS
+SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
+PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
+EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further
+action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that the
+Program itself (excluding combinations of the Program with other software
+or hardware) infringes such Recipient's patent(s), then such Recipient's
+rights granted under Section 2(b) shall terminate as of the date such
+litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it
+fails to comply with any of the material terms or conditions of this
+Agreement and does not cure such failure in a reasonable period of
+time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use
+and distribution of the Program as soon as reasonably practicable.
+However, Recipient's obligations under this Agreement and any licenses
+granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement,
+but in order to avoid inconsistency the Agreement is copyrighted and
+may only be modified in the following manner. The Agreement Steward
+reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement
+Steward has the right to modify this Agreement. The Eclipse Foundation
+is the initial Agreement Steward. The Eclipse Foundation may assign the
+responsibility to serve as the Agreement Steward to a suitable separate
+entity. Each new version of the Agreement will be given a distinguishing
+version number. The Program (including Contributions) may always be
+Distributed subject to the version of the Agreement under which it was
+received. In addition, after a new version of the Agreement is published,
+Contributor may elect to Distribute the Program (including its
+Contributions) under the new version.
+
+Except as expressly stated in Sections 2(a) and 2(b) above, Recipient
+receives no rights or licenses to the intellectual property of any
+Contributor under this Agreement, whether expressly, by implication,
+estoppel or otherwise. All rights in the Program not expressly granted
+under this Agreement are reserved. Nothing in this Agreement is intended
+to be enforceable by any entity that is not a Contributor or Recipient.
+No third-party beneficiary rights are created under this Agreement.
+
+Exhibit A - Form of Secondary Licenses Notice
+
+"This Source Code may also be made available under the following
+Secondary Licenses when the conditions for such availability set forth
+in the Eclipse Public License, v. 2.0 are satisfied: {name license(s),
+version(s), and exceptions or additional permissions here}."
+
+ Simply including a copy of this Agreement, including this Exhibit A
+ is not sufficient to license the Source Code under Secondary Licenses.
+
+ If it is not possible or desirable to put the notice in a particular
+ file, then You may include the notice in a location (such as a LICENSE
+ file in a relevant directory) where a recipient would be likely to
+ look for such a notice.
+
+ You may add additional accurate notices of copyright ownership.
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..dbae4b4f2
--- /dev/null
+++ b/README.md
@@ -0,0 +1,61 @@
+# 寒月
+* 具备流量整形加速的旁路网关
+* 仅供学习与研究,不支持机场的双端自建方案
+
+[](https://t.me/de_GWD_DQ)
+
+
+## Server (amd64 & arm64) support kvm xen openvz lxc and so on:
+```
+apt install -y wget
+bash <(wget --no-check-certificate -qO- https://raw.githubusercontent.com/jacyl4/de_GWD/main/server)
+```
+
+
+
+## Client (amd64 & arm64):
+```
+apt install -y wget
+bash <(wget --no-check-certificate -qO- https://ghproxy.com/https://raw.githubusercontent.com/jacyl4/de_GWD/main/client)
+```
+或
+
+手动上传client文件与de_GWD压缩包后
+```
+chmod +x client
+./client
+```
+
+
+
+
+
+
+
+## Manual:
+没有文档
+
+## Thanks to
+* [ v2fly/v2ray-core ](https://github.com/v2fly/v2ray-core)
+* [ IrineSistiana/mosdns ](https://github.com/IrineSistiana/mosdns)
+* [ coredns/coredns ](https://github.com/coredns/coredns)
+* [ pymumu/smartdns ](https://github.com/pymumu/smartdns)
+* [ m13253/dns-over-https ](https://github.com/m13253/dns-over-https)
+* [ pi-hole/pi-hole ](https://github.com/pi-hole/pi-hole)
+* [ mmotti/pihole-regex ](https://github.com/mmotti/pihole-regex)
+* [ felixonmars/dnsmasq-china-list ](https://github.com/felixonmars/dnsmasq-china-list)
+* [ Loyalsoldier/v2ray-rules-dat ](https://github.com/Loyalsoldier/v2ray-rules-dat)
+* [ makotom/cfspeed ](https://github.com/makotom/cfspeed)
+* [ UJX6N/bbrplus-5.18 ](https://github.com/UJX6N/bbrplus-5.18)
+* [ mzz2017/lkl-haproxy ](https://github.com/mzz2017/lkl-haproxy)
+* [ xanmod/linux ](https://github.com/xanmod/linux)
+* [ tsl0922/ttyd ](https://github.com/tsl0922/ttyd)
+* [ mikefarah/yq ](https://github.com/mikefarah/yq)
+* [ nyanmisaka/jellyfin ](https://hub.docker.com/r/nyanmisaka/jellyfin)
+* [ dani-garcia/vaultwarden ](https://github.com/dani-garcia/vaultwarden)
+
+## Stargazers over time
+[](https://starchart.cc/jacyl4/de_GWD)
+
+## Donation:
+
diff --git a/client b/client
new file mode 100755
index 000000000..040f7ea29
--- /dev/null
+++ b/client
@@ -0,0 +1,2728 @@
+#!/bin/bash
+clear
+RED='\E[1;31m'
+GREEN='\E[1;32m'
+YELLOW='\E[1;33m'
+BLUE='\E[1;34m'
+PURPLE='\E[1;35m'
+CYAN='\E[1;36m'
+WHITE='\E[1;37m'
+cRES='\E[0m'
+
+chmod 777 /tmp
+architecture=$(dpkg --print-architecture)
+export DEBIAN_FRONTEND=noninteractive
+TTYD_Ver="1.7.1"
+branch="main"
+
+
+installCMD=`cat << EOF
+bash <(wget --no-check-certificate -qO- https://ghproxy.com/https://raw.githubusercontent.com/jacyl4/de_GWD/main/client)
+EOF
+`
+
+
+if [[ $architecture = "arm64" ]];then
+chnAPTsource="mirrors.tuna.tsinghua.edu.cn"
+elif [[ $architecture = "amd64" ]]; then
+chnAPTsource="mirrors.aliyun.com"
+fi
+
+pkgDEP1(){
+unset aptPKG
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^sudo$') ]] && aptPKG+=(sudo)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^wget$') ]] && aptPKG+=(wget)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^curl$') ]] && aptPKG+=(curl)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^git$') ]] && aptPKG+=(git)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^locales$') ]] && aptPKG+=(locales)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^netcat$') ]] && aptPKG+=(netcat)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^lsof$') ]] && aptPKG+=(lsof)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^dnsutils$') ]] && aptPKG+=(dnsutils)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^net-tools$') ]] && aptPKG+=(net-tools)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^resolvconf$') ]] && aptPKG+=(resolvconf)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^nftables$') ]] && aptPKG+=(nftables)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^ca-certificates$') ]] && aptPKG+=(ca-certificates)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^apt-transport-https$') ]] && aptPKG+=(apt-transport-https)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^gnupg2$') ]] && aptPKG+=(gnupg2)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^unzip$') ]] && aptPKG+=(unzip)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^jq$') ]] && aptPKG+=(jq)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^bc$') ]] && aptPKG+=(bc)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^moreutils$') ]] && aptPKG+=(moreutils)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^rng-tools$') ]] && aptPKG+=(rng-tools)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^irqbalance$') ]] && [[ $(nproc --all) -gt 1 ]] && aptPKG+=(irqbalance)
+[[ -n $aptPKG ]] && apt install $(echo ${aptPKG[@]})
+}
+
+pkgDEP2(){
+unset aptPKG
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^psmisc$') ]] && aptPKG+=(psmisc)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^dns-root-data$') ]] && aptPKG+=(dns-root-data)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^idn2$') ]] && aptPKG+=(idn2)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^ethtool$') ]] && aptPKG+=(ethtool)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^tmux$') ]] && aptPKG+=(tmux)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^socat$') ]] && aptPKG+=(socat)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^zip$') ]] && aptPKG+=(zip)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^lighttpd$') ]] && aptPKG+=(lighttpd)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-fpm$') ]] && aptPKG+=(php7.4-fpm)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-cgi$') ]] && aptPKG+=(php7.4-cgi)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-sqlite3$') ]] && aptPKG+=(php7.4-sqlite3)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-xml$') ]] && aptPKG+=(php7.4-xml)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-intl$') ]] && aptPKG+=(php7.4-intl)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-json$') ]] && aptPKG+=(php7.4-json)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^sqlite3$') ]] && aptPKG+=(sqlite3)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^redis-server$') ]] && aptPKG+=(redis-server)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^libjemalloc-dev$') ]] && aptPKG+=(libjemalloc-dev)
+[[ -n $aptPKG ]] && apt install $(echo ${aptPKG[@]})
+}
+
+checkSum(){
+sha256sumL=$(sha256sum $1 2>/dev/null | awk '{print$1}')
+if [[ $sha256sumL = $2 ]]; then
+ echo "true"
+elif [[ $sha256sumL != $2 ]]; then
+ echo "false"
+fi
+}
+
+
+
+preDL(){
+mkdir -p /opt/de_GWD
+mkdir -p /opt/de_GWD/.repo
+
+sha256sum_IPchnroute=$(curl -ksSLo- https://ghproxy.com/https://raw.githubusercontent.com/jacyl4/chnroute/main/IPchnroute.sha256sum)
+if [[ $(checkSum /opt/de_GWD/.repo/IPchnroute $sha256sum_IPchnroute) = "false" ]]; then
+rm -rf /tmp/IPchnroute
+wget --no-check-certificate --show-progress -cqO /tmp/IPchnroute https://ghproxy.com/https://raw.githubusercontent.com/jacyl4/chnroute/main/IPchnroute
+[[ $(checkSum /tmp/IPchnroute $sha256sum_IPchnroute) = "false" ]] && echo -e "${WHITE}IPchnroute${RED} Download Failed${cRES}" && exit
+[[ $(checkSum /tmp/IPchnroute $sha256sum_IPchnroute) = "true" ]] && mv -f /tmp/IPchnroute /opt/de_GWD/.repo/IPchnroute
+fi
+
+if [[ -f "./de_GWD_$architecture.zip" ]]; then
+ mv -f ./de_GWD_$architecture.zip /opt/de_GWD/.repo/de_GWD.zip
+else
+ sha256sum_de_GWD=$(curl -ksSLo- https://ghproxy.com/https://raw.githubusercontent.com/jacyl4/de_GWD/main/de_GWD_"$architecture".zip.sha256sum)
+ if [[ $(checkSum /opt/de_GWD/.repo/de_GWD.zip $sha256sum_de_GWD) = "false" ]]; then
+ rm -rf /tmp/de_GWD.zip
+ wget --no-check-certificate --show-progress -cqO /tmp/de_GWD.zip https://ghproxy.com/https://raw.githubusercontent.com/jacyl4/de_GWD/main/de_GWD_"$architecture".zip
+ [[ $(checkSum /tmp/de_GWD.zip $sha256sum_de_GWD) = "false" ]] && rm -rf /tmp/de_GWD.zip && wget --no-check-certificate --show-progress -cqO /tmp/de_GWD.zip https://de-gwd.accxio.workers.dev/de_GWD_"$architecture".zip
+ [[ $(checkSum /tmp/de_GWD.zip $sha256sum_de_GWD) = "false" ]] && echo -e "${WHITE}de_GWD Zip${RED} Download Failed${cRES}" && exit
+ [[ $(checkSum /tmp/de_GWD.zip $sha256sum_de_GWD) = "true" ]] && mv -f /tmp/de_GWD.zip /opt/de_GWD/.repo/de_GWD.zip
+ fi
+fi
+
+[[ -z $(unzip -tq /opt/de_GWD/.repo/de_GWD.zip | grep "No errors detected in compressed data") ]] && echo -e "${WHITE}de_GWD Zip${RED} Download Failed${cRES}" && exit
+
+cat << "EOF" >/opt/de_GWD/tcpTime
+#!/bin/bash
+echo
+date -s "$(curl -sI aliyun.com| grep -i '^date:'|cut -d' ' -f2-)"
+[[ $? -ne "0" ]] && date -s "$(wget -qSO- --max-redirect=0 --dns-timeout=3 baidu.com 2>&1 | grep Date: | cut -d' ' -f5-8)Z"
+hwclock -w
+echo
+EOF
+chmod +x /opt/de_GWD/tcpTime
+/opt/de_GWD/tcpTime
+}
+
+
+
+repoDL(){
+echo -e "${WHITE}[...]\c" && echo -e "\t${WHITE}Repo Download${cRES}\r\c"
+sha256sum_nginx=$(curl -sSLo- https://raw.githubusercontent.com/jacyl4/de_GWD/$branch/resource/nginx/nginx_"$architecture".sha256sum)
+sha256sum_nginxConf=$(curl -sSLo- https://raw.githubusercontent.com/jacyl4/de_GWD/$branch/resource/nginx/nginxConf.zip.sha256sum)
+sha256sum_client=$(curl -sSLo- https://raw.githubusercontent.com/jacyl4/de_GWD/$branch/resource/client/Archive.zip.sha256sum)
+
+if [[ $(checkSum /usr/sbin/nginx $sha256sum_nginx) = "false" ]]; then
+rm -rf /tmp/nginx
+wget --show-progress -cqO /tmp/nginx https://raw.githubusercontent.com/jacyl4/de_GWD/$branch/resource/nginx/nginx_"$architecture"
+[[ $(checkSum /tmp/nginx $sha256sum_nginx) = "false" ]] && echo -e "${WHITE}NGINX Core${RED} Download Failed${cRES}" && exit
+[[ $(checkSum /tmp/nginx $sha256sum_nginx) = "true" ]] && mv -f /tmp/nginx /usr/sbin/nginx && chmod +x /usr/sbin/nginx
+fi
+
+if [[ $(checkSum /opt/de_GWD/.repo/nginxConf.zip $sha256sum_nginxConf) = "false" ]]; then
+rm -rf /tmp/nginxConf.zip
+wget --show-progress -cqO /tmp/nginxConf.zip https://raw.githubusercontent.com/jacyl4/de_GWD/$branch/resource/nginx/nginxConf.zip
+[[ $(checkSum /tmp/nginxConf.zip $sha256sum_nginxConf) = "false" ]] && echo -e "${RED}Download Failed${cRES}" && exit
+[[ $(checkSum /tmp/nginxConf.zip $sha256sum_nginxConf) = "true" ]] && mv -f /tmp/nginxConf.zip /opt/de_GWD/.repo/nginxConf.zip
+fi
+
+if [[ $(ttyd -v 2>&1 | grep -o '[0-9]\.[0-9]\.[0-9]') != $TTYD_Ver ]]; then
+wget --show-progress -cqO /tmp/ttyd https://github.com/tsl0922/ttyd/releases/download/$TTYD_Ver/ttyd.$(uname -m)
+[[ $? -ne 0 ]] && echo -e "${WHITE}TTYD${RED} Download Failed${cRES}"
+[[ $(du -sk /tmp/ttyd 2>/dev/null | awk '{print$1}') -gt 1000 ]] && mv -f /tmp/ttyd /usr/bin/ttyd && chmod +x /usr/bin/ttyd && TTYD_UPDATE="true"
+fi
+
+if [[ $(checkSum /opt/de_GWD/.repo/client.zip $sha256sum_client) = "false" ]]; then
+rm -rf /tmp/client.zip
+wget --show-progress -cqO /tmp/client.zip https://raw.githubusercontent.com/jacyl4/de_GWD/$branch/resource/client/Archive.zip
+[[ $(checkSum /tmp/client.zip $sha256sum_client) = "false" ]] && echo -e "${WHITE}Client Zip${RED} Download Failed${cRES}" && exit
+[[ $(checkSum /tmp/client.zip $sha256sum_client) = "true" ]] && mv -f /tmp/client.zip /opt/de_GWD/.repo/client.zip
+fi
+
+localVer=$(awk 'NR==1' /opt/de_GWD/.repo/version.php 2>/dev/null)
+remoteVer=$(curl -sSLo- https://raw.githubusercontent.com/jacyl4/de_GWD/main/version.php | head -n 1)
+
+if [[ $localVer != $remoteVer ]] || [[ ! -f '/opt/de_GWD/.repo/version.php' ]]; then
+rm -rf /opt/de_GWD/.repo/version.php
+wget --show-progress -cqO /opt/de_GWD/.repo/version.php https://raw.githubusercontent.com/jacyl4/de_GWD/main/version.php
+[[ $? -ne 0 ]] && echo -e "${WHITE}Version file${RED} Download Failed${cRES}" && exit
+fi
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Repo Download${cRES}"
+}
+
+
+
+cleanDep(){
+echo -e "${WHITE}[...]\c" && echo -e "\t${WHITE}Clean-up${cRES}\r\c"
+service cron stop
+
+sed -i "/nfsvers/d" /etc/fstab >/dev/null 2>&1
+sed -i '/quic/d' /etc/nginx/conf.d/*.conf >/dev/null 2>&1
+
+[[ $(jq '.v2nodeDIV.nodeSM' /opt/de_GWD/0conf) = "[]" ]] && jq '.v2nodeDIV.nodeSM={}' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+[[ $(jq '.v2nodeDIV.nodeDT' /opt/de_GWD/0conf) = "[]" ]] && jq '.v2nodeDIV.nodeDT={}' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+[[ $(jq '.v2nodeDIV.nodeCU' /opt/de_GWD/0conf) = "[]" ]] && jq '.v2nodeDIV.nodeCU={}' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+
+[[ -n $(jq '.v2nodeDIV.nodeCU.custom' /opt/de_GWD/0conf | grep -v '^null$') ]] && jq 'del(.v2nodeDIV.nodeCU.custom)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+[[ -n $(jq '.v2nodeDIV.nodeDT.divert' /opt/de_GWD/0conf | grep -v '^null$') ]] && jq 'del(.v2nodeDIV.nodeDT.divert)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+[[ -n $(jq '.v2nodeDIV.nodeDT.ip' /opt/de_GWD/0conf | grep -v '^null$') ]] && jq 'del(.v2nodeDIV.nodeDT.ip)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+[[ -n $(jq '.listB' /opt/de_GWD/0conf | grep -v '^null$') ]] && jq 'del(.listB)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+[[ -n $(jq '.listW' /opt/de_GWD/0conf | grep -v '^null$') ]] && jq 'del(.listW)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+[[ -n $(jq '.listBlan' /opt/de_GWD/0conf | grep -v '^null$') ]] && jq 'del(.listBlan)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+[[ -n $(jq '.listWlan' /opt/de_GWD/0conf | grep -v '^null$') ]] && jq 'del(.listWlan)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+[[ -n $(jq '.dns.APPLEcn' /opt/de_GWD/0conf | grep -v '^null$') ]] && jq 'del(.dns.APPLEcn)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+[[ -n $(jq '.dns.STEAMcn' /opt/de_GWD/0conf | grep -v '^null$') ]] && jq 'del(.dns.STEAMcn)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+[[ -n $(jq '.v2nodeDIV.directApple' /opt/de_GWD/0conf | grep -v '^null$') ]] && jq 'del(.v2nodeDIV.directApple)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+[[ -n $(jq '.v2nodeDIV.directSteam' /opt/de_GWD/0conf | grep -v '^null$') ]] && jq 'del(.v2nodeDIV.directSteam)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+
+dohORI=$(jq -r '.dns.DOH' /opt/de_GWD/0conf | grep -v '^null$')
+dogORI=$(jq -r '.dns.DoG' /opt/de_GWD/0conf | grep -v '^null$')
+[[ -n $dohORI ]] && jq --argjson doh "$dohORI" '.dns.doh=$doh' /opt/de_GWD/0conf | jq 'del(.dns.DOH)' | sponge /opt/de_GWD/0conf
+[[ -n $dogORI ]] && jq --arg dog "$dogORI" '.dns.dog=$dog' /opt/de_GWD/0conf | jq 'del(.dns.DoG)' | sponge /opt/de_GWD/0conf
+
+adlists=$(jq -r '.dns.adlistsURL' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+[[ -n $(jq '.[]' <<< "$adlists") ]] && jq --argjson adlists "$adlists" '.dns.adlists=$adlists' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+
+adBlist=$(jq -r '.dns.adBlistURL' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+[[ -n $(jq '.[]' <<< "$adBlist") ]] && jq --argjson adBlist "$adBlist" '.dns.adBlist=$adBlist' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+
+adBregex=$(jq -r '.dns.regexRule' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+[[ -n $(jq '.[]' <<< "$adBregex") ]] && jq --argjson adBregex "$adBregex" '.dns.adBregex=$adBregex' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+
+adWlist=$(jq -r '.dns.adWlistURL' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+[[ -n $(jq '.[]' <<< "$adWlist") ]] && jq --argjson adWlist "$adWlist" '.dns.adWlist=$adWlist' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+
+jq 'del(.dns.adlistsURL)' /opt/de_GWD/0conf |\
+jq 'del(.dns.regexRule)' |\
+jq 'del(.dns.adWlistURL)' |\
+jq 'del(.dns.adBlistURL)' | sponge /opt/de_GWD/0conf
+
+[[ -d "/opt/bitwardenrs" ]] && mv -f /opt/bitwardenrs /opt/bitwarden
+
+if [[ -f "/etc/systemd/system/doh-client.service" ]] || [[ -f "/lib/systemd/system/doh-client.service" ]]; then
+ systemctl disable --now doh-client >/dev/null 2>&1
+ rm -rf /lib/systemd/system/doh-client.service
+ rm -rf /etc/systemd/system/doh-client.service
+ rm -rf /opt/de_GWD/doh-client*
+ rm -rf "/etc/NetworkManager/dispatcher.d"
+ systemctl daemon-reload >/dev/null
+fi
+
+if [[ -f "/etc/systemd/system/doh-server.service" ]] || [[ -f "/lib/systemd/system/doh-server.service" ]]; then
+ systemctl disable --now doh-server >/dev/null 2>&1
+ rm -rf /lib/systemd/system/doh-server.service
+ rm -rf /etc/systemd/system/doh-server.service
+ rm -rf /opt/de_GWD/doh-server*
+ rm -rf "/etc/NetworkManager/dispatcher.d"
+ systemctl daemon-reload >/dev/null
+fi
+
+if [[ -f "/etc/systemd/system/iptables-proxy.service" ]] || [[ -f "/lib/systemd/system/iptables-proxy.service" ]]; then
+ systemctl disable iptables-proxy >/dev/null 2>&1
+ rm -rf /etc/systemd/system/iptables-proxy.service >/dev/null 2>&1
+ rm -rf /lib/systemd/system/iptables-proxy.service >/dev/null 2>&1
+ systemctl daemon-reload >/dev/null
+ /opt/de_GWD/iptables-proxy-down
+ rm -rf /opt/de_GWD/iptables-proxy-down
+ rm -rf /opt/de_GWD/iptables-proxy-up
+fi
+
+
+if [[ -d "/opt/de_GWD/xDNSc" ]]; then
+ systemctl disable xDNSc >/dev/null 2>&1
+ systemctl stop xDNSc >/dev/null 2>&1
+ rm -rf /etc/systemd/system/xDNSc.service
+ rm -rf /lib/systemd/system/xDNSc.service
+ systemctl daemon-reload >/dev/null
+ rm -rf /opt/de_GWD/xDNSc
+ jq 'del(.dns.xDNS)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+fi
+
+if [[ -d "/opt/de_GWD/xDNSs" ]]; then
+ systemctl disable xDNSs >/dev/null 2>&1
+ systemctl stop xDNSs >/dev/null 2>&1
+ rm -rf /etc/systemd/system/xDNSs.service
+ rm -rf /lib/systemd/system/xDNSs.service
+ systemctl daemon-reload >/dev/null
+ rm -rf /opt/de_GWD/xDNSs
+ jq 'del(.FORWARD.xDNSs)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+fi
+
+if [[ `dpkg -l | grep php | grep fpm | awk '{print $2}'` = "php7.3-fpm" ]] || [[ `dpkg -l | grep php | grep fpm | awk '{print $2}'` = "php8.0-fpm" ]]; then
+ rm -rf /etc/php/7.3/
+ apt remove --purge '^php7.3.*'
+ rm -rf /etc/php/8.0/
+ apt remove --purge '^php8.0.*'
+fi
+
+[[ -n $(dpkg -l | awk '{print$2}' | grep '^ipset$') ]] && apt remove --purge ipset
+
+[[ -f "/etc/nginx/off" ]] && rm -rf /etc/nginx/off
+rm -rf /etc/dnsmasq.d/89-bogus-domains.china.conf
+rm -rf /etc/dnsmasq.d/89-bogus-nxdomains.china.conf
+[[ -n $(dpkg -l | awk '{print$2}' | grep '^smartdns$') ]] && rm -rf /etc/smartdns && apt remove --purge smartdns
+[[ -n $(systemctl cat v2dns 2>/dev/null) ]] && systemctl disable --now v2dns >/dev/null 2>&1 && \
+rm -rf /lib/systemd/system/v2dns.service && \
+rm -rf /etc/systemd/system/v2dns.service && \
+rm -rf /opt/de_GWD/v2dns
+[[ -n $(dpkg -l | awk '{print$2}' | grep '^haveged$') ]] && apt remove --purge haveged
+[[ -n $(dpkg -l | awk '{print$2}' | grep '^subversion$') ]] && apt remove --purge subversion
+
+rm -rf /etc/pihole/migration_backup
+rm -rf /etc/dnsmasq.d/89-bogus-nxdomain.china.conf
+rm -rf /etc/apt/sources.list.d/unstable.list
+rm -rf /etc/apt/preferences.d/limit-unstable
+rm -rf /opt/de_GWD/.repo/vtrui.zip
+rm -rf /opt/de_GWD/chnroute.txt
+rm -rf /opt/de_GWD/Q4am
+rm -rf /opt/de_GWD/Q4H
+rm -rf /opt/de_GWD/Q2H
+rm -rf /etc/dns-over-https
+rm -rf /usr/bin/vtrui
+rm -rf /usr/local/bin/yq
+rm -rf /usr/sbin/yq
+rm -rf /etc/vtrui
+rm -rf /opt/de_GWD/ttyd
+rm -rf /opt/de_GWD/IPxDNSSET
+rm -rf /opt/de_GWD/chnrouteSET
+rm -rf /opt/de_GWD/IPGlobalDNSSET
+rm -rf /opt/de_GWD/IPlistBlanSET
+rm -rf /opt/de_GWD/IPlistBSET
+rm -rf /opt/de_GWD/IPlistWlanSET
+rm -rf /opt/de_GWD/IPlistWSET
+rm -rf /opt/de_GWD/IPv2nodeSET
+rm -rf /opt/de_GWD/__MACOSX
+rm -rf /opt/de_GWD/clearKernel
+rm -rf /var/www/html/__MACOSX
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Clean-up${cRES}"
+}
+
+
+
+preUpdate(){
+echo -e "${BLUE}################################################################# ${cRES}"
+echo -e "${GREEN}DNS information${cRES}"
+echo
+
+ethernetnum=$(ip --oneline link show up | grep -v "lo" | grep -v "noqueue" | awk '{print$2;exit}' | cut -d':' -f1 | cut -d'@' -f1)
+gatewayAddr=$(jq -r '.address.upstreamIP' /opt/de_GWD/0conf | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
+localAddrCIDR=$(jq -r '.address.localIP' /opt/de_GWD/0conf | grep -v '^null$')
+localAddr=$(echo $localAddrCIDR | cut -d / -f1)
+netmask=$(echo $localAddrCIDR | sed -r 's/([0-9]{1,3}\.){3}[0-9]{1,3}//g')
+
+if [[ -n $netmask ]]; then
+localCIDR="$(echo $localAddr | cut -d . -f1-3).0$netmask"
+else
+netmask="/24"
+localAddrCIDR="$localAddr$netmask"
+localCIDR="$(echo $localAddr | cut -d . -f1-3).0$netmask"
+fi
+
+DoG=$(jq -r '.dns.dog' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+doh1=$(jq -r '.dns.doh[]' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$' | awk NR==1)
+doh2=$(jq -r '.dns.doh[]' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$' | awk NR==2)
+
+[[ -n $doh1 ]] && echo -e "\t${WHITE}DNS over Https 1: \c" && echo -e "${YELLOW}$doh1${cRES}"
+[[ -n $doh2 ]] && echo -e "\t${WHITE}DNS over Https 2: \c" && echo -e "${YELLOW}$doh2${cRES}"
+[[ -n $DoG ]] && echo -e "\t${WHITE}DNS over gRPC : \c" && echo -e "${YELLOW}$DoG${cRES}"
+
+
+domain=$(jq -r '.update.v2node.domain' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+tls=$(jq -r '.update.v2node.tls' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+port=$(jq -r '.update.v2node.port' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+uuid=$(jq -r '.update.v2node.uuid' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+path=$(jq -r '.update.v2node.path' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+if [[ -z $domain ]] || [[ -z $uuid ]]; then
+ cp -f /opt/de_GWD/0conf_bak /opt/de_GWD/0conf
+ clear
+ preUpdate
+fi
+
+[[ -z $tls ]] && tls=$domain
+
+piholePW=$(jq -r '.address.PWD' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+serverName=$(jq -r '.address.serverName' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+webUIport=$(jq -r '.address.webUIport' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+updatePort=$(jq -r '.update.updatePort' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+echo
+echo -e "${GREEN}v2ray node information${cRES}"
+echo
+echo -e "\t${WHITE}Domain : \c" && echo -e "${YELLOW}$domain${cRES}"
+echo -e "\t${WHITE}Port : \c" && echo -e "${YELLOW}$port${cRES}"
+echo -e "\t${WHITE}UUID : \c" && echo -e "${YELLOW}$uuid${cRES}"
+echo -e "\t${WHITE}Path : \c" && echo -e "${YELLOW}$path${cRES}"
+echo -e "${BLUE}################################################################# ${cRES}"
+echo
+}
+
+
+
+de_GWDconnect(){
+if [[ $1 = "u" ]]; then
+echo -e "${WHITE}de_GWD server connect ${cRES}\c" && echo -e "\t${WHITE}[...]${cRES}\r\c"
+else
+echo -e "\t${WHITE}de_GWD server connect${cRES}\r\c"
+fi
+
+local serverConnect1=$(curl -Is -m 5 google.com | grep 'HTTP')
+local serverConnect2=$(curl -Is -m 5 youtube.com | grep 'HTTP')
+
+if [[ $1 = "u" ]]; then
+ if [[ $2 = "a" ]]; then
+ preDL
+ updateGWD_Green
+ [[ -z $serverConnect1 ]] || [[ -z $serverConnect2 ]] && exit
+ else
+ if [[ -n $serverConnect1 ]] && [[ -n $serverConnect2 ]] && [[ $(systemctl is-active 'vtrui') = "active" ]]; then
+ echo -e "${WHITE}de_GWD server connect ${cRES}\c" && echo -e "\t${WHITE}[${GREEN} ✓ ${WHITE}]${cRES}"
+ de_GWDconnect_check="OK"
+ echo -e "${GREEN}================================= ${cRES}"
+ echo -e "${GREEN}[Y]: Full Update${cRES}"
+ echo -e "${GREEN}[*]: Any other key to Fast Update${cRES}"
+ echo -e "${GREEN}================================= ${cRES}"
+ read -s -n 1 updateDebian
+ echo -e "${WHITE}[...]\c" && echo -e "\t${WHITE}Start Updating de_GWD${cRES}\r\c"
+
+ if [[ $updateDebian = "Y" ]] || [[ $updateDebian = "y" ]]; then
+ preDL
+ updateAPT
+ fi
+ preDL
+ updateGWD_Green
+ else
+ echo -e "${WHITE}de_GWD server connect ${cRES}\c" && echo -e "\t${WHITE}[${RED} ✕ ${WHITE}]${cRES}"
+ updateGWD_Red
+ fi
+ fi
+else
+ if [[ -n $serverConnect1 ]] && [[ -n $serverConnect2 ]] && [[ $(systemctl is-active 'vtrui') = "active" ]]; then
+ echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}de_GWD server connect${cRES}"
+ else
+ echo -e "${WHITE}[ ${RED}✕ ${WHITE}]\c" && echo -e "\t${WHITE}de_GWD server connect${cRES}"
+ fi
+
+
+if [[ -z $serverConnect1 ]] || [[ -z $serverConnect2 ]]; then
+cat << EOF >/etc/resolv.conf
+nameserver 119.29.29.29
+nameserver 182.254.118.118
+nameserver 114.114.114.114
+nameserver 223.5.5.5
+EOF
+systemctl stop smartdns >/dev/null 2>&1
+systemctl stop nftables >/dev/null 2>&1
+exit
+fi
+fi
+}
+
+
+
+preInstall(){
+sync; echo 3 >/proc/sys/vm/drop_caches >/dev/null 2>&1
+
+cat << EOF >/etc/apt/apt.conf.d/01InstallLess
+APT::Get::Assume-Yes "true";
+APT::Install-Recommends "false";
+APT::Install-Suggests "false";
+EOF
+
+cat << EOF >/etc/apt/apt.conf.d/71debconf
+Dpkg::Options {
+ "--force-confdef";
+ "--force-confold";
+};
+EOF
+
+sed -i '/ulimit -SHn/d' /etc/profile
+sed -i '/ulimit -c/d' /etc/profile
+sed -i '/ulimit -d/d' /etc/profile
+sed -i '/ulimit -f/d' /etc/profile
+sed -i '/ulimit -m/d' /etc/profile
+sed -i '/ulimit -s/d' /etc/profile
+sed -i '/ulimit -t/d' /etc/profile
+sed -i '/ulimit -u/d' /etc/profile
+sed -i '/ulimit -v/d' /etc/profile
+sed -i '/HISTCONTROL=/d' /etc/profile
+sed -i '/alias reboot=/d' /etc/profile
+cat << EOF >>/etc/profile
+ulimit -SHn 1000000
+ulimit -c unlimited
+ulimit -d unlimited
+ulimit -f unlimited
+ulimit -m unlimited
+ulimit -s unlimited
+ulimit -t unlimited
+ulimit -u 1000000
+ulimit -v unlimited
+
+HISTCONTROL=ignoredups
+alias reboot="sudo systemctl reboot"
+EOF
+source /etc/profile
+
+cat << EOF >/etc/security/limits.conf
+root soft nofile 1000000
+root hard nofile 1000000
+root soft nproc 1000000
+root hard nproc 1000000
+root soft core 1000000
+root hard core 1000000
+root hard memlock unlimited
+root soft memlock unlimited
+
+* soft nofile 1000000
+* hard nofile 1000000
+* soft nproc 1000000
+* hard nproc 1000000
+* soft core 1000000
+* hard core 1000000
+* hard memlock unlimited
+* soft memlock unlimited
+EOF
+
+sed -i '/DefaultLimitCORE/d' /etc/systemd/system.conf
+sed -i '/DefaultLimitNOFILE/d' /etc/systemd/system.conf
+sed -i '/DefaultLimitNPROC/d' /etc/systemd/system.conf
+cat << EOF >>/etc/systemd/system.conf
+DefaultLimitCORE=1000000
+DefaultLimitNOFILE=1000000
+DefaultLimitNPROC=1000000
+EOF
+systemctl daemon-reload
+
+rm -f /var/lib/apt/lists/lock
+rm -f /var/cache/apt/archives/lock
+rm -f /var/lib/dpkg/lock
+dpkg --configure -a
+
+pkgDEP1
+
+cat << EOF >/etc/default/rng-tools-debian
+# -*- mode: sh -*-
+#-
+# Configuration for the rng-tools-debian initscript
+
+# Set to the input source for random data, leave undefined
+# for the initscript to attempt auto-detection. Set to /dev/null
+# for the viapadlock driver.
+#HRNGDEVICE=/dev/hwrng
+#HRNGDEVICE=/dev/null
+HRNGDEVICE=/dev/urandom
+
+# Additional options to send to rngd. See the rngd(8) manpage for
+# more information. Do not specify -r/--rng-device here, use
+# HRNGDEVICE for that instead.
+#RNGDOPTIONS="--hrng=intelfwh --fill-watermark=90% --feed-interval=1"
+#RNGDOPTIONS="--hrng=viakernel --fill-watermark=90% --feed-interval=1"
+#RNGDOPTIONS="--hrng=viapadlock --fill-watermark=90% --feed-interval=1"
+# For TPM (also add tpm-rng to /etc/initramfs-tools/modules or /etc/modules):
+#RNGDOPTIONS="--fill-watermark=90% --feed-interval=1"
+
+# If you need to configure which RNG to use, do it here:
+#HRNGSELECT="virtio_rng.0"
+# Use this instead of sysfsutils, which starts too late.
+EOF
+systemctl restart rng-tools
+
+rm -rf /etc/systemd/resolved.conf >/dev/null 2>&1
+systemctl daemon-reload >/dev/null
+systemctl mask --now systemd-resolved >/dev/null 2>&1
+
+[[ -n $(which setenforce) ]] && setenforce 0
+[[ -f "/etc/selinux/config" ]] && sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
+
+nft delete table ip de_GWD >/dev/null 2>&1
+ip rule del table 220 >/dev/null 2>&1
+ip route flush table 220 >/dev/null 2>&1
+ip route flush cache >/dev/null 2>&1
+ip route del local default dev lo table 220 >/dev/null 2>&1
+
+[[ -n $(systemctl cat nftables 2>/dev/null) ]] && systemctl stop nftables >/dev/null 2>&1
+[[ -n $(systemctl cat vtrui 2>/dev/null) ]] && systemctl stop vtrui >/dev/null 2>&1
+
+if [[ -n "$(ps -e | grep 'pihole-FTL' )" ]]; then
+cat << EOF >/etc/dnsmasq.conf
+conf-dir=/etc/dnsmasq.d
+listen-address=127.0.0.1
+port=0
+EOF
+pihole restartdns >/dev/null 2>&1
+fi
+
+cat << EOF >/etc/resolv.conf
+nameserver 119.29.29.29
+nameserver 182.254.118.118
+nameserver 114.114.114.114
+nameserver 223.5.5.5
+EOF
+}
+
+
+
+preConf(){
+echo -e "${WHITE}[...]\c" && echo -e "\t${WHITE}System Config${cRES}\r\c"
+localeSet=`cat << EOF
+LANG=en_US.UTF-8
+LANGUAGE=en_US.UTF-8
+LC_CTYPE="en_US.UTF-8"
+LC_NUMERIC="en_US.UTF-8"
+LC_TIME="en_US.UTF-8"
+LC_COLLATE="en_US.UTF-8"
+LC_MONETARY="en_US.UTF-8"
+LC_MESSAGES="en_US.UTF-8"
+LC_PAPER="en_US.UTF-8"
+LC_NAME="en_US.UTF-8"
+LC_ADDRESS="en_US.UTF-8"
+LC_TELEPHONE="en_US.UTF-8"
+LC_MEASUREMENT="en_US.UTF-8"
+LC_IDENTIFICATION="en_US.UTF-8"
+LC_ALL=en_US.UTF-8
+EOF
+`
+if [[ -z $(localectl list-locales | grep "en_US.UTF-8") ]]; then
+echo "$localeSet" >/etc/default/locale
+echo "en_US.UTF-8 UTF-8" >/etc/locale.gen
+locale-gen "en_US.UTF-8"
+localectl set-locale en_US.UTF-8
+update-locale LANG=en_US.UTF-8 LANGUAGE=en_US.UTF-8 LC_ALL=en_US.UTF-8
+fi
+
+[[ $(date +"%Z %z") != "CST +0800" ]] && timedatectl set-timezone "Asia/Shanghai"
+timedatectl set-local-rtc 1 >/dev/null 2>&1
+
+modprobe nf_conntrack
+sed -i '/nf_conntrack/d' /etc/modules-load.d/modules.conf
+cat << EOF >>/etc/modules-load.d/modules.conf
+nf_conntrack
+EOF
+
+cat << EOF >/etc/sysctl.conf
+vm.overcommit_memory = 1
+vm.swappiness = 10
+vm.dirty_ratio = 10
+vm.dirty_background_ratio = 5
+fs.nr_open = 1000000
+fs.file-max = 1000000
+fs.inotify.max_user_instances = 819200
+fs.inotify.max_queued_events = 32000
+fs.inotify.max_user_watches = 64000
+net.unix.max_dgram_qlen = 10240
+net.nf_conntrack_max = 131072
+net.netfilter.nf_conntrack_acct = 0
+net.netfilter.nf_conntrack_checksum = 0
+net.netfilter.nf_conntrack_events = 1
+net.netfilter.nf_conntrack_timestamp = 0
+net.netfilter.nf_conntrack_helper = 1
+net.netfilter.nf_conntrack_max = 16384
+net.netfilter.nf_conntrack_buckets = 65535
+net.netfilter.nf_conntrack_tcp_loose = 1
+net.netfilter.nf_conntrack_tcp_be_liberal = 1
+net.netfilter.nf_conntrack_tcp_max_retrans = 3
+net.netfilter.nf_conntrack_generic_timeout = 60
+net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 30
+net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 30
+net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30
+net.netfilter.nf_conntrack_tcp_timeout_close_wait = 15
+net.netfilter.nf_conntrack_tcp_timeout_close = 5
+net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
+net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 30
+net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 30
+net.netfilter.nf_conntrack_tcp_timeout_established = 3600
+net.netfilter.nf_conntrack_sctp_timeout_established = 3600
+net.netfilter.nf_conntrack_udp_timeout = 15
+net.netfilter.nf_conntrack_udp_timeout_stream = 45
+net.core.somaxconn = 65535
+net.core.netdev_max_backlog = 262144
+net.core.optmem_max = 8388608
+net.core.rmem_default = 8388608
+net.core.wmem_default = 8388608
+net.core.rmem_max = 8388608
+net.core.wmem_max = 8388608
+net.ipv4.conf.all.arp_accept = 0
+net.ipv4.conf.default.arp_accept = 0
+net.ipv4.conf.all.arp_announce = 2
+net.ipv4.conf.default.arp_announce = 2
+net.ipv4.conf.all.arp_ignore = 1
+net.ipv4.conf.default.arp_ignore = 1
+net.ipv4.conf.all.rp_filter = 0
+net.ipv4.conf.default.rp_filter = 0
+net.ipv4.conf.all.send_redirects = 0
+net.ipv4.conf.default.send_redirects = 0
+net.ipv4.conf.all.accept_redirects = 1
+net.ipv4.conf.default.accept_redirects = 1
+net.ipv4.conf.all.secure_redirects = 1
+net.ipv4.conf.default.secure_redirects = 1
+net.ipv4.conf.all.accept_source_route = 1
+net.ipv4.conf.default.accept_source_route = 1
+net.ipv4.ip_local_port_range = 1024 65535
+net.ipv4.ip_local_reserved_ports = 3000
+net.ipv4.ip_forward = 1
+net.ipv4.ip_no_pmtu_disc = 0
+net.ipv4.tcp_mtu_probing = 1
+net.ipv4.tcp_base_mss = 1152
+net.ipv4.udp_rmem_min = 16384
+net.ipv4.udp_wmem_min = 16384
+net.ipv4.tcp_mem = 8388608 8388608 8388608
+net.ipv4.tcp_rmem = 4096 87380 8388608
+net.ipv4.tcp_wmem = 4096 16384 8388608
+net.ipv4.tcp_max_tw_buckets = 65535
+net.ipv4.tcp_max_syn_backlog = 32768
+net.ipv4.tcp_max_orphans = 32768
+net.ipv4.tcp_adv_win_scale = 1
+net.ipv4.tcp_moderate_rcvbuf = 1
+net.ipv4.tcp_window_scaling = 1
+net.ipv4.tcp_workaround_signed_windows = 0
+net.ipv4.tcp_no_metrics_save = 0
+net.ipv4.tcp_no_ssthresh_metrics_save = 1
+net.ipv4.tcp_sack = 1
+net.ipv4.tcp_dsack = 1
+net.ipv4.tcp_frto = 2
+net.ipv4.tcp_recovery = 1
+net.ipv4.tcp_early_retrans = 3
+net.ipv4.tcp_min_rtt_wlen = 120
+net.ipv4.tcp_reordering = 6
+net.ipv4.tcp_ecn = 2
+net.ipv4.tcp_ecn_fallback = 1
+net.ipv4.tcp_fin_timeout = 15
+net.ipv4.tcp_fastopen = 0x403
+net.ipv4.tcp_fastopen_blackhole_timeout_sec = 0
+net.ipv4.tcp_keepalive_time = 1800
+net.ipv4.tcp_keepalive_intvl = 15
+net.ipv4.tcp_keepalive_probes = 4
+net.ipv4.tcp_timestamps = 0
+net.ipv4.tcp_syncookies = 0
+net.ipv4.tcp_tw_reuse = 2
+net.ipv4.tcp_syn_retries = 3
+net.ipv4.tcp_synack_retries = 2
+net.ipv4.tcp_retries1 = 3
+net.ipv4.tcp_retries2 = 5
+net.ipv4.tcp_orphan_retries = 3
+net.ipv4.tcp_challenge_ack_limit = 100000
+net.ipv4.tcp_slow_start_after_idle = 0
+net.ipv4.tcp_autocorking = 0
+net.ipv4.tcp_rfc1337 = 1
+net.core.default_qdisc = cake
+EOF
+
+sed -i '/net.ipv4.tcp_congestion_control/d' /etc/sysctl.conf
+if [[ $(uname -r) =~ "bbrplus" ]]; then
+ echo "net.ipv4.tcp_congestion_control = bbrplus" >>/etc/sysctl.conf
+else
+ echo "net.ipv4.tcp_congestion_control = bbr" >>/etc/sysctl.conf
+fi
+sysctl -p >/dev/null && sysctl -w net.ipv4.route.flush=1 >/dev/null 2>&1
+
+if [[ -n $(dpkg -l | awk '{print$2}' | grep '^docker-ce$') ]] && [[ -n $(dpkg -l | awk '{print$2}' | grep '^containerd.io$') ]]; then
+mkdir -p /etc/docker/
+systemctl stop docker docker.socket containerd
+cat << EOF >/etc/docker/daemon.json
+{
+ "iptables": false
+}
+EOF
+systemctl restart docker
+fi
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}System Config${cRES}"
+}
+
+
+
+installSmartDNS(){
+echo -e "${WHITE}[...]\c" && echo -e "\t${WHITE}Proxy Components Prepared${cRES}\r\c"
+if [[ -n $(unzip -tq /opt/de_GWD/.repo/de_GWD.zip | grep "No errors detected in compressed data") ]]; then
+rm -rf /opt/de_GWD/smartdns
+rm -rf /opt/de_GWD/coredns
+rm -rf /opt/de_GWD/mosdns
+rm -rf /opt/de_GWD/vtrui
+mkdir -p /opt/de_GWD/smartdns
+mkdir -p /opt/de_GWD/coredns
+mkdir -p /opt/de_GWD/mosdns
+mkdir -p /opt/de_GWD/vtrui
+
+rm -rf /tmp/de_GWD
+unzip /opt/de_GWD/.repo/de_GWD.zip -d /tmp/de_GWD >/dev/null
+cp -f /tmp/de_GWD/yq /usr/bin/yq
+cp -f /tmp/de_GWD/smartdns /opt/de_GWD/smartdns/smartdns
+cp -f /tmp/de_GWD/coredns /opt/de_GWD/coredns/coredns
+cp -f /tmp/de_GWD/mosdns /opt/de_GWD/mosdns/mosdns
+cp -f /tmp/de_GWD/v2ray /opt/de_GWD/vtrui/vtrui
+chmod +x /usr/bin/yq
+chmod +x /opt/de_GWD/smartdns/smartdns
+chmod +x /opt/de_GWD/coredns/coredns
+chmod +x /opt/de_GWD/mosdns/mosdns
+chmod +x /opt/de_GWD/vtrui/vtrui
+rm -rf /tmp/de_GWD*
+else
+rm -rf /opt/de_GWD/.repo/de_GWD.zip
+echo -e "${WHITE}de_GWD Zip${RED} Download Failed${cRES}" && exit
+fi
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Proxy Components prepared${cRES}"
+
+
+
+rm -rf /lib/systemd/system/coredns.service
+cat << EOF >/etc/systemd/system/coredns.service
+[Unit]
+Description=CoreDNS DNS server
+After=network.target
+
+[Service]
+User=root
+Type=simple
+ExecStart=/opt/de_GWD/coredns/coredns -conf /opt/de_GWD/coredns/corefile
+ExecReload=/bin/kill -SIGUSR1 \$MAINPID
+KillMode=process
+Restart=always
+RestartSec=2
+TimeoutStopSec=5
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl daemon-reload >/dev/null
+
+
+
+cat << EOF >/opt/de_GWD/smartdns/smartdns.conf
+bind :53 -group DNS_global
+bind-tcp :53 -group DNS_global
+
+bind 127.0.0.1:5331 -no-speed-check -no-cache -group DNS_chn
+bind-tcp 127.0.0.1:5331 -no-speed-check -no-cache -group DNS_chn
+
+bind 127.0.0.1:5332 -no-speed-check -no-cache -group DNS_global
+bind-tcp 127.0.0.1:5332 -no-speed-check -no-cache -group DNS_global
+
+server 114.114.114.114 -exclude-default-group -group DNS_chn
+server 114.114.115.115 -exclude-default-group -group DNS_chn
+server 119.29.29.29 -exclude-default-group -group DNS_chn
+server 119.28.28.28 -exclude-default-group -group DNS_chn
+server 182.254.118.118 -exclude-default-group -group DNS_chn
+server 223.5.5.5 -exclude-default-group -group DNS_chn
+server 223.6.6.6 -exclude-default-group -group DNS_chn
+EOF
+
+kill $(ps -e | grep 'smartdns' | awk '{print$1}') >/dev/null 2>&1
+touch /run/smartdns.pid
+rm -rf /lib/systemd/system/smartdns.service
+cat << EOF >/etc/systemd/system/smartdns.service
+[Unit]
+Description=SmartDNS
+After=network.target
+
+[Service]
+User=root
+Type=forking
+PIDFile=/run/smartdns.pid
+ExecStart=/opt/de_GWD/smartdns/smartdns -p /run/smartdns.pid -c /opt/de_GWD/smartdns/smartdns.conf
+ExecStopPost=$(which rm) -f /run/smartdns.pid
+ExecStop=/bin/kill -s STOP \$MAINPID
+KillMode=mixed
+Restart=always
+RestartSec=2
+TimeoutStopSec=5
+
+Nice=-12
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl daemon-reload >/dev/null
+systemctl restart smartdns
+if [[ $? -ne 0 ]]; then
+sed -i '/Nice=/d' /etc/systemd/system/smartdns.service
+systemctl daemon-reload >/dev/null
+systemctl restart smartdns
+fi
+systemctl enable smartdns >/dev/null 2>&1
+
+rm -rf /etc/resolvconf/resolv.conf.d/*
+>/etc/resolvconf/resolv.conf.d/original
+>/etc/resolvconf/resolv.conf.d/base
+>/etc/resolvconf/resolv.conf.d/tail
+rm -rf /etc/resolv.conf
+rm -rf /run/resolvconf/interface
+cat << EOF >/etc/resolvconf/resolv.conf.d/head
+nameserver 127.0.0.1
+EOF
+if [[ -f "/etc/resolvconf/run/resolv.conf" ]]; then
+ln -sf /etc/resolvconf/run/resolv.conf /etc/resolv.conf
+elif [[ -f "/run/resolvconf/resolv.conf" ]]; then
+ln -sf /run/resolvconf/resolv.conf /etc/resolv.conf
+fi
+sed -i '/dns-nameservers /d' /etc/network/interfaces
+resolvconf -u
+
+
+
+echo
+echo -e "${BLUE}################################################################# ${cRES}"
+echo
+
+if [[ -n $doh1 ]]; then
+echo -e "${WHITE}DNS over Https 1:\t${cRES}"
+echo -e "${WHITE}Domain: \c" && echo -e "\t${WHITE}IP: ${cRES}\r\c"
+doh1Domain=$(echo $doh1 | cut -d/ -f1 | cut -d: -f1)
+doh1IP=$(dig @127.0.0.1 $doh1Domain -4p 5331 +short | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' | grep -v "127.0.0.1" | xargs -n 1 | awk NR==1)
+
+if [[ -n $doh1IP ]]; then
+doh1Port=$(echo $doh1 | cut -d/ -f1 | cut -d: -f2 | grep '^[[:digit:]]*$')
+doh1Path=$(echo $doh1 | cut -d/ -f2)
+
+if [[ -z $doh1Port ]]; then
+ doh1Str="$doh1IP/$doh1Path"
+else
+ doh1Str="$doh1IP:$doh1Port/$doh1Path"
+fi
+
+cat << EOF >>/opt/de_GWD/smartdns/smartdns.conf
+server-https https://$doh1Str -host-name $doh1Domain -no-check-certificate -group DNS_global
+EOF
+fi
+
+echo -e "${WHITE}Domain: ${YELLOW}$doh1Domain\c" && echo -e "\t${WHITE}IP: ${YELLOW}$doh1IP${cRES}"
+echo
+fi
+
+if [[ -n $doh2 ]]; then
+echo -e "${WHITE}DNS over Https 2: ${cRES}"
+echo -e "${WHITE}Domain: \c" && echo -e "\t${WHITE}IP: ${cRES}\r\c"
+doh2Domain=$(echo $doh2 | cut -d/ -f1 | cut -d: -f1)
+doh2IP=$(dig @127.0.0.1 $doh2Domain -4p 5331 +short | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' | grep -v "127.0.0.1" | xargs -n 1 | awk NR==1)
+
+if [[ -n $doh2IP ]]; then
+doh2Port=$(echo $doh2 | cut -d/ -f1 | cut -d: -f2 | grep '^[[:digit:]]*$')
+doh2Path=$(echo $doh2 | cut -d/ -f2)
+
+if [[ -z $doh2Port ]]; then
+ doh2Str="$doh2IP/$doh2Path"
+else
+ doh2Str="$doh2IP:$doh2Port/$doh2Path"
+fi
+
+cat << EOF >>/opt/de_GWD/smartdns/smartdns.conf
+server-https https://$doh2Str -host-name $doh2Domain -no-check-certificate -group DNS_global
+EOF
+fi
+
+echo -e "${WHITE}Domain: ${YELLOW}$doh2Domain\c" && echo -e "\t${WHITE}IP: ${YELLOW}$doh2IP${cRES}"
+echo
+fi
+
+if [[ -n $DoG ]]; then
+echo -e "${WHITE}DNS over gRPC: ${cRES}"
+echo -e "${WHITE}Domain: \c" && echo -e "\t${WHITE}IP: ${cRES}\r\c"
+DoGcDomain=$(echo $DoG | cut -d: -f1)
+DoGcIP=$(dig @127.0.0.1 $DoGcDomain -4p 5331 +short | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' | grep -v "127.0.0.1" | xargs -n 1 | awk NR==1)
+DoGcPort=$(echo $DoG | cut -d: -f2 | grep '^[[:digit:]]*$')
+echo -e "${WHITE}Domain: ${YELLOW}$DoGcDomain\c" && echo -e "\t${WHITE}IP: ${YELLOW}$DoGcIP${cRES}"
+echo
+
+cat << EOF >>/opt/de_GWD/smartdns/smartdns.conf
+server 127.0.0.1:5333 -group DNS_global
+server-tcp 127.0.0.1:5333 -group DNS_global
+EOF
+fi
+
+systemctl restart smartdns
+
+if [[ -n $DoGcIP ]]; then
+cat << EOF >/opt/de_GWD/coredns/corefile
+# DoGc_START
+.:5333 {
+ bind 127.0.0.1
+ grpc . $DoGcIP:$DoGcPort {
+ tls_servername $DoGcDomain
+ }
+ template ANY AAAA {
+ rcode NXDOMAIN
+ }
+}
+# DoGc_END
+EOF
+systemctl enable coredns >/dev/null 2>&1
+systemctl restart coredns
+fi
+
+echo -e "${WHITE}V2 node: ${cRES}"
+echo -e "${WHITE}Domain: \c" && echo -e "\t${WHITE}IP: ${cRES}\r\c"
+domainIP=$(dig @127.0.0.1 $domain -4p 5332 +short | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' | grep -v "127.0.0.1" | xargs -n 1 | awk NR==1)
+echo -e "${WHITE}Domain: ${YELLOW}$domain\c" && echo -e "\t${WHITE}IP: ${YELLOW}$domainIP${cRES}"
+echo
+echo -e "${BLUE}################################################################# ${cRES}"
+echo
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Deploy SmartDNS${cRES}"
+
+[[ -z $domainIP ]] && echo -e "${WHITE}V2 node${RED} Failure to resolve${cRES}" && exit
+
+rm -rf /lib/systemd/system/mosdns.service
+cat << EOF >/etc/systemd/system/mosdns.service
+[Unit]
+Description=mosdns
+ConditionFileIsExecutable=/opt/de_GWD/mosdns/mosdns
+
+[Service]
+User=root
+Type=simple
+ExecStart=/opt/de_GWD/mosdns/mosdns start --as-service -d /opt/de_GWD/mosdns
+ExecStop=/bin/kill -s STOP \$MAINPID
+KillMode=process
+Restart=always
+RestartSec=2
+TimeoutStopSec=5
+
+Nice=-11
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl daemon-reload >/dev/null
+}
+
+
+
+installV2ray(){
+echo -e "${WHITE}[...]\c" && echo -e "\t${WHITE}Deploy vtrui${cRES}\r\c"
+
+cat << EOF >/opt/de_GWD/vtrui/config.json
+{
+ "log": {
+ "access":"none",
+ "error":"none",
+ "loglevel":"none"
+ },
+ "dns":{
+ "queryStrategy":"UseIP",
+ "disableCache":true,
+ "hosts":{"$domain":"$domainIP"},
+ "servers":["tcp+local://127.0.0.1:5332"]
+ },
+ "inbounds":[
+ {
+ "port":9896,
+ "listen":"127.0.0.1",
+ "protocol":"dokodemo-door",
+ "settings":{"network":"tcp,udp","followRedirect":true},
+ "streamSettings":{"sockopt":{"tcpFastOpen":true,"tproxy":"tproxy"}}
+ }
+ ],
+ "outbounds":[
+ {
+ "tag":"default"
+ },
+ {
+ "tag":"direct",
+ "protocol":"freedom",
+ "streamSettings":{"sockopt":{"mark":255}}
+ }
+ ]
+}
+EOF
+
+if [[ -z $path ]]; then
+OBdefault=`cat << EOF
+ {
+ "tag": "default",
+ "protocol": "vmess",
+ "settings": {
+ "vnext": [
+ {
+ "address": "$domain",
+ "port": $port,
+ "users": [
+ {
+ "id": "$uuid",
+ "alterId": 0,
+ "security": "auto"
+ }
+ ]
+ }
+ ]
+ },
+ "streamSettings": {
+ "network": "tcp",
+ "sockopt": {
+ "mark": 255,
+ "tcpFastOpen": true
+ }
+ }
+ }
+EOF
+`
+else
+OBdefault=`cat << EOF
+{
+ "tag": "default",
+ "protocol": "vmess",
+ "settings": {
+ "vnext": [
+ {
+ "address": "$domain",
+ "port": $port,
+ "users": [
+ {
+ "id": "$uuid",
+ "alterId": 0,
+ "security": "auto"
+ }
+ ]
+ }
+ ]
+ },
+ "streamSettings": {
+ "network": "ws",
+ "wsSettings": {
+ "path": "$path",
+ "headers": {
+ "Host": "$tls"
+ }
+ },
+ "security": "tls",
+ "tlsSettings": {
+ "serverName": "$tls",
+ "allowInsecure": false
+ },
+ "sockopt": {
+ "mark": 255,
+ "tcpFastOpen": true
+ }
+ }
+}
+EOF
+`
+fi
+
+jq --argjson OBdefault "$OBdefault" '.outbounds[0]=$OBdefault' /opt/de_GWD/vtrui/config.json | sponge /opt/de_GWD/vtrui/config.json
+
+rm -rf /lib/systemd/system/vtrui.service
+cat << EOF >/etc/systemd/system/vtrui.service
+[Unit]
+Description=vtrui
+After=network.target nss-lookup.target
+
+[Service]
+User=root
+Type=simple
+ExecStart=/opt/de_GWD/vtrui/vtrui run -config /opt/de_GWD/vtrui/config.json
+Restart=always
+RestartSec=2
+TimeoutStopSec=5
+
+Nice=-9
+AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN CAP_NET_BIND_SERVICE
+NoNewPrivileges=true
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl daemon-reload >/dev/null
+systemctl restart vtrui
+if [[ $? -ne 0 ]]; then
+sed -i '/Nice=/d' /etc/systemd/system/vtrui.service
+systemctl daemon-reload >/dev/null
+systemctl restart vtrui
+fi
+systemctl enable vtrui >/dev/null 2>&1
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Deploy vtrui${cRES}"
+}
+
+
+
+installNftables(){
+echo -e "${WHITE}[...]\c" && echo -e "\t${WHITE}Deploy nftables${cRES}\r\c"
+cat << EOF >/etc/network/interfaces
+source /etc/network/interfaces.d/*
+
+auto lo
+iface lo inet loopback
+
+auto $ethernetnum
+iface $ethernetnum inet static
+ address $localAddrCIDR
+ gateway $gatewayAddr
+EOF
+
+mkdir -p /opt/de_GWD/nftables
+echo $DoGcIP $doh1IP $doh2IP | xargs -n1 | sort | uniq | sed 's/$/,/g' >/opt/de_GWD/nftables/IP_GlobalDNS
+cat << EOF >/opt/de_GWD/nftables/SET_GlobalDNS.nft
+#!/usr/sbin/nft -f
+table ip de_GWD {
+ set GlobalDNS {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ elements = { $(cat /opt/de_GWD/nftables/IP_GlobalDNS) }
+ }
+}
+EOF
+chmod +x /opt/de_GWD/nftables/SET_GlobalDNS.nft
+/opt/de_GWD/nftables/SET_GlobalDNS.nft
+
+cat << EOF >/opt/de_GWD/nftables/SET_V2NODE.nft
+#!/usr/sbin/nft -f
+table ip de_GWD {
+ set V2NODE {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ elements = { $domainIP }
+ }
+}
+EOF
+chmod +x /opt/de_GWD/nftables/SET_V2NODE.nft
+/opt/de_GWD/nftables/SET_V2NODE.nft
+
+if [[ $(du -sk /opt/de_GWD/.repo/IPchnroute 2>/dev/null | awk '{print$1}') -gt 100 ]]; then
+cp -f /opt/de_GWD/.repo/IPchnroute /opt/de_GWD/nftables/IP_CHNROUTE
+sed -i '/^\s*$/d' /opt/de_GWD/nftables/IP_CHNROUTE
+sed -i 's/$/,/g' /opt/de_GWD/nftables/IP_CHNROUTE
+fi
+
+[[ -n $(cat /opt/de_GWD/nftables/IP_CHNROUTE 2>&1 | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') ]] && IP_CHNROUTE_elements="elements = { $(cat /opt/de_GWD/nftables/IP_CHNROUTE) }"
+cat << EOF >/opt/de_GWD/nftables/SET_CHNROUTE.nft
+#!/usr/sbin/nft -f
+table ip de_GWD {
+ set CHNROUTE {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ $IP_CHNROUTE_elements
+ }
+}
+EOF
+chmod +x /opt/de_GWD/nftables/SET_CHNROUTE.nft
+/opt/de_GWD/nftables/SET_CHNROUTE.nft
+
+[[ -n $(cat /opt/de_GWD/nftables/IP_listB 2>&1 | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') ]] && IP_listB_elements="elements = { $(cat /opt/de_GWD/nftables/IP_listB) }"
+cat << EOF >/opt/de_GWD/nftables/SET_listB.nft
+#!/usr/sbin/nft -f
+table ip de_GWD {
+ set listB {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ $IP_listB_elements
+ }
+}
+EOF
+chmod +x /opt/de_GWD/nftables/SET_listB.nft
+/opt/de_GWD/nftables/SET_listB.nft
+
+[[ -n $(cat /opt/de_GWD/nftables/IP_listW 2>&1 | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') ]] && IP_listW_elements="elements = { $(cat /opt/de_GWD/nftables/IP_listW) }"
+cat << EOF >/opt/de_GWD/nftables/SET_listW.nft
+#!/usr/sbin/nft -f
+table ip de_GWD {
+ set listW {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ $IP_listW_elements
+ }
+}
+EOF
+chmod +x /opt/de_GWD/nftables/SET_listW.nft
+/opt/de_GWD/nftables/SET_listW.nft
+
+[[ -n $(cat /opt/de_GWD/nftables/IP_listBlan 2>&1 | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') ]] && IP_listBlan_elements="elements = { $(cat /opt/de_GWD/nftables/IP_listBlan) }"
+cat << EOF >/opt/de_GWD/nftables/SET_listBlan.nft
+#!/usr/sbin/nft -f
+table ip de_GWD {
+ set listBlan {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ $IP_listBlan_elements
+ }
+}
+EOF
+chmod +x /opt/de_GWD/nftables/SET_listBlan.nft
+/opt/de_GWD/nftables/SET_listBlan.nft
+
+[[ -n $(cat /opt/de_GWD/nftables/IP_listWlan 2>&1 | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') ]] && IP_listWlan_elements="elements = { $(cat /opt/de_GWD/nftables/IP_listWlan) }"
+cat << EOF >/opt/de_GWD/nftables/SET_listWlan.nft
+#!/usr/sbin/nft -f
+table ip de_GWD {
+ set listWlan {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ $IP_listWlan_elements
+ }
+}
+EOF
+chmod +x /opt/de_GWD/nftables/SET_listWlan.nft
+/opt/de_GWD/nftables/SET_listWlan.nft
+
+cat << EOF >/opt/de_GWD/nftables/default.nft
+#!/usr/sbin/nft -f
+table ip filter {
+ chain INPUT {
+ type filter hook input priority 0; policy accept;
+ iifname lo accept
+ ct state established,related accept
+ tcp flags != syn ct state new drop
+ tcp flags & (fin|syn) == (fin|syn) drop
+ tcp flags & (syn|rst) == (syn|rst) drop
+ tcp flags & (fin|syn|rst|psh|ack|urg) < (fin) drop
+ tcp flags & (fin|syn|rst|psh|ack|urg) == (fin|psh|urg) drop
+ ct state invalid counter drop
+ # Drop 53 in
+ }
+ chain FORWARD {
+ type filter hook forward priority 0; policy accept;
+ tcp flags & (syn|rst) == syn counter tcp option maxseg size set rt mtu
+ # WireGuard traffic
+ iifname "wg0" accept
+ oifname "wg0" accept
+
+ # Docker traffic
+ counter jump DOCKER-USER
+ counter jump DOCKER-ISOLATION-STAGE-1
+ oifname "docker0" ct state established,related counter accept
+ oifname "docker0" counter jump DOCKER
+ iifname "docker0" oifname != "docker0" counter accept
+ iifname "docker0" oifname "docker0" counter accept
+ }
+ chain OUTPUT {
+ type filter hook output priority 0; policy accept;
+ }
+ chain DOCKER {
+ }
+ chain DOCKER-USER {
+ counter accept
+ }
+ chain DOCKER-ISOLATION-STAGE-1 {
+ iifname "docker0" oifname != "docker0" counter jump DOCKER-ISOLATION-STAGE-2
+ counter accept
+ }
+ chain DOCKER-ISOLATION-STAGE-2 {
+ oifname "docker0" counter drop
+ counter accept
+ }
+}
+
+table ip router {
+ chain PREROUTING {
+ type nat hook prerouting priority -100; policy accept;
+ # Docker
+ fib daddr type local counter jump DOCKER
+ }
+ chain POSTROUTING {
+ type nat hook postrouting priority 100; policy accept;
+ # Wireguard masquerade traffic
+ oifname $ethernetnum ip saddr 172.16.66.0/24 masquerade
+
+ # Docker
+ oifname != "docker0" ip saddr 172.17.0.0/16 counter masquerade
+ }
+ chain INPUT {
+ type nat hook input priority 100; policy accept;
+ }
+ chain OUTPUT {
+ type nat hook output priority -100; policy accept;
+ ip daddr != 127.0.0.0/8 fib daddr type local counter jump DOCKER
+ }
+ chain DOCKER {
+ iifname "docker0" counter accept
+ }
+}
+EOF
+chmod +x /opt/de_GWD/nftables/default.nft
+
+cat << EOF >/opt/de_GWD/nftables/nftables
+#!/usr/sbin/nft -f
+
+include "/opt/de_GWD/nftables/*.nft"
+
+define RESERVED_IP = {
+ $localCIDR,
+ 10.0.0.0/8,
+ 100.64.0.0/10,
+ 127.0.0.0/8,
+ 169.254.0.0/16,
+ 172.16.0.0/12,
+ 192.0.0.0/24,
+ 192.168.0.0/16,
+ 224.0.0.0/4,
+ 240.0.0.0/4,
+ 255.255.255.255/32,
+ 114.114.114.114/32,
+ 114.114.115.115/32,
+ 119.29.29.29/32,
+ 119.28.28.28/32,
+ 182.254.118.118/32,
+ 223.5.5.5/32,
+ 223.6.6.6/32
+}
+
+table ip de_GWD {
+ set CHNROUTE {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ }
+ set GlobalDNS {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ }
+ set V2NODE {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ }
+ set listB {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ }
+ set listW {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ }
+ set listBlan {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ }
+ set listWlan {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ }
+ chain prerouting {
+ type filter hook prerouting priority -310; policy accept;
+ meta l4proto { tcp, udp } th dport 53 accept
+ meta l4proto { tcp, udp } th dport 4711 accept
+ meta l4proto { tcp, udp } th dport 5331 accept
+ meta l4proto { tcp, udp } th dport 5332 accept
+ meta l4proto { tcp, udp } th dport 5333 accept
+ meta l4proto { tcp, udp } th dport 5341 accept
+ ip daddr @GlobalDNS accept
+ ip saddr @listBlan meta l4proto { tcp, udp } tproxy to 127.0.0.1:9896 meta mark set 0x9
+ ip saddr @listWlan accept
+ ip daddr \$RESERVED_IP accept
+ ip daddr @listB meta l4proto { tcp, udp } tproxy to 127.0.0.1:9896 meta mark set 0x9
+ ip daddr @listW accept
+ ip daddr @V2NODE accept
+ ip daddr @CHNROUTE accept
+ ip protocol { tcp, udp } tproxy to 127.0.0.1:9896 meta mark set 0x9
+ }
+ chain output {
+ type route hook output priority -311; policy accept;
+ meta l4proto { tcp, udp } th dport 53 accept
+ meta l4proto { tcp, udp } th dport 4711 accept
+ meta l4proto { tcp, udp } th dport 5331 accept
+ meta l4proto { tcp, udp } th dport 5332 accept
+ meta l4proto { tcp, udp } th dport 5333 accept
+ meta l4proto { tcp, udp } th dport 5341 accept
+ ip daddr @GlobalDNS accept
+ ip daddr \$RESERVED_IP accept
+ ip daddr @listB meta mark set 0x9
+ ip daddr @listW accept
+ ip daddr @V2NODE accept
+ ip daddr @CHNROUTE accept
+ meta mark 0xff accept
+ ip protocol { tcp, udp } meta mark set 0x9
+ }
+}
+EOF
+chmod +x /opt/de_GWD/nftables/nftables
+
+rm -rf /lib/systemd/system/nftables.service
+cat << EOF >/etc/systemd/system/nftables.service
+[Unit]
+Description=nftables
+Wants=network-pre.target
+Before=network-pre.target shutdown.target
+Conflicts=shutdown.target
+DefaultDependencies=no
+
+[Service]
+User=root
+Type=oneshot
+ExecStart=/usr/sbin/nft -f /opt/de_GWD/nftables/nftables ; $(which ip) route add local default dev lo scope host table 220 ; $(which ip) rule add fwmark 0x9 table 220 prio 100
+ExecStop=/usr/sbin/nft flush ruleset ; $(which ip) rule del table 220 ; $(which ip) route del local default dev lo table 220
+RemainAfterExit=yes
+
+StandardInput=null
+ProtectSystem=full
+ProtectHome=true
+
+[Install]
+WantedBy=sysinit.target
+EOF
+systemctl daemon-reload >/dev/null
+systemctl enable nftables >/dev/null 2>&1
+systemctl restart nftables
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Deploy nftables${cRES}"
+}
+
+
+
+updateAPT(){
+echo -e "${WHITE}[...]\c" && echo -e "\t${WHITE}Debian Updated${cRES}\r\c"
+cat << EOF >/etc/apt/sources.list
+deb http://cloudfront.debian.net/debian bullseye main contrib non-free
+deb http://cloudfront.debian.net/debian bullseye-updates main contrib non-free
+deb http://cloudfront.debian.net/debian bullseye-backports main contrib non-free
+deb http://cloudfront.debian.net/debian-security bullseye-security main contrib non-free
+EOF
+
+echo "deb https://packages.sury.org/php/ $(cat /etc/os-release | grep VERSION= | cut -d'(' -f2 | cut -d')' -f1) main" >/etc/apt/sources.list.d/php.list
+apt-key del 95BD4743 >/dev/null 2>&1
+wget --no-check-certificate -cqO /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
+[[ $? -ne 0 ]] && echo -e "${WHITE}PHP apt key${RED} Download Failed${cRES}"
+
+apt update --fix-missing && apt upgrade --allow-downgrades -y
+apt full-upgrade -y && apt autoremove --purge -y && apt clean -y && apt autoclean -y
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Debian ${GREEN}Updated${cRES}"
+}
+
+
+
+installDep(){
+echo -e "${WHITE}[...]\c" && echo -e "\t${WHITE}Dependencies${cRES}\r\c"
+sed -i "/www-data/d" /etc/sudoers
+sed -i "/Allow members of group sudo to execute any command/a\www-data ALL=(root) NOPASSWD:ALL" /etc/sudoers
+
+pkgDEP1
+
+pkgDEP2
+
+cat << EOF >/etc/ld.so.preload
+/usr/lib/$(uname -m)-linux-gnu/libjemalloc.so
+EOF
+ldconfig
+
+kill $(ps -e | grep 'redis-server' | awk '{print$1}') >/dev/null 2>&1
+rm -rf /dev/shm/redis-server.sock
+cat << EOF >/etc/redis/redis.conf
+bind 127.0.0.1
+protected-mode yes
+port 6379
+tcp-backlog 49152
+tcp-keepalive 0
+unixsocket /dev/shm/redis-server.sock
+unixsocketperm 777
+requirepass de_GWD
+daemonize yes
+supervised no
+pidfile /var/run/redis/redis-server.pid
+loglevel warning
+logfile ""
+databases 16
+save 3600 1
+save 300 100
+save 60 10000
+rdbcompression no
+rdbchecksum no
+appendonly no
+stop-writes-on-bgsave-error no
+dbfilename dump.rdb
+dir /var/lib/redis
+requirepass de_GWD
+maxclients 10000
+maxmemory 64mb
+maxmemory-policy allkeys-lfu
+maxmemory-samples 5
+lfu-log-factor 10
+lfu-decay-time 1
+auto-aof-rewrite-percentage 100
+auto-aof-rewrite-min-size 32mb
+EOF
+
+rm -rf /lib/systemd/system/redis-server.service
+cat << EOF >/etc/systemd/system/redis-server.service
+[Unit]
+Description=redis-server
+After=network.target
+
+[Service]
+User=redis
+Group=redis
+Type=forking
+ExecStart=/usr/bin/redis-server /etc/redis/redis.conf
+Restart=always
+RestartSec=2
+TimeoutStopSec=5
+
+Nice=-15
+
+UMask=007
+PrivateTmp=yes
+NoNewPrivileges=true
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl daemon-reload >/dev/null
+systemctl restart redis-server
+if [[ $? -ne 0 ]]; then
+sed -i '/Nice=/d' /etc/systemd/system/redis-server.service
+systemctl daemon-reload >/dev/null
+systemctl restart redis-server
+fi
+systemctl enable redis-server >/dev/null 2>&1
+
+
+
+if [[ -z $(dpkg -l | awk '{print$2}' | grep '^lighttpd-mod-deflate$') ]]; then
+[[ $(printf '%s\n' $(lighttpd -v 2>&1 | grep -Po '(\d+\.)+\d+') "1.4.42" | sort -rV | head -n 1) != "1.4.42" ]] && apt install lighttpd-mod-deflate
+fi
+
+DPKGclean=$(dpkg --list | grep "^rc" | cut -d " " -f 3)
+[[ -n $DPKGclean ]] && echo $DPKGclean | xargs sudo dpkg --purge
+
+rm -rf /var/log/journal/*
+systemctl restart systemd-journald >/dev/null 2>&1
+
+if [[ -d "/usr/local/ioncube" ]]; then
+echo "zend_extension = /usr/local/ioncube/ioncube_loader_lin_7.4.so" >/etc/php/7.4/mods-available/ioncube.ini
+ln -sf /etc/php/7.4/mods-available/ioncube.ini /etc/php/7.4/fpm/conf.d/00-ioncube.ini
+ln -sf /etc/php/7.4/mods-available/ioncube.ini /etc/php/7.4/cli/conf.d/00-ioncube.ini
+fi
+
+sed -i "/zend_extension/d" /etc/php/7.4/cli/php.ini
+sed -i "/zend_extension/d" /etc/php/7.4/fpm/php.ini
+sed -i "s/^opcache/;&/" /etc/php/7.4/cli/php.ini
+sed -i "s/^opcache/;&/" /etc/php/7.4/fpm/php.ini
+
+cat << EOF >/etc/php/00-init.ini
+expose_php = Off
+error_reporting = E_ALL & ~E_NOTICE
+display_errors = Off
+display_startup_errors = Off
+log_errors = On
+ignore_repeated_errors = Off
+
+allow_url_fopen = On
+allow_url_include = Off
+variables_order = "GPCS"
+allow_webdav_methods = On
+memory_limit = 128M
+max_execution_time = 300
+max_input_time = 300
+max_input_vars = 5000
+output_buffering = Off
+output_handler = ""
+zlib.output_compression = Off
+zlib.output_handler = ""
+safe_mode = Off
+register_globals = Off
+magic_quotes_gpc = Off
+date.timezone = "Asia/Shanghai"
+
+file_uploads = On
+upload_tmp_dir = /var/www/temp
+upload_max_filesize = 20M
+post_max_size = 20M
+
+engine = off
+enable_dl = Off
+disable_functions = ""
+disable_classes = ""
+
+session.save_handler = files
+session.use_cookies = 1
+session.use_only_cookies = 1
+session.auto_start = 0
+session.cookie_lifetime = 0
+session.cookie_httponly = 1
+session.cookie_secure = 1
+EOF
+ln -sf /etc/php/00-init.ini /etc/php/7.4/cli/conf.d/00-init.ini
+ln -sf /etc/php/00-init.ini /etc/php/7.4/fpm/conf.d/00-init.ini
+
+rm -rf /etc/php/7.4/fpm/pool.d
+cat << EOF >/etc/php/7.4/fpm/php-fpm.conf
+[global]
+pid = /run/php/php7.4-fpm.pid
+error_log = /var/log/php.log
+
+[www]
+user = www-data
+group = www-data
+listen.owner = www-data
+listen.group = www-data
+listen.mode = 0666
+listen = /run/php/php7.4-fpm.sock
+listen.backlog = -1
+listen.allowed_clients = 127.0.0.1
+
+pm = dynamic
+pm.max_children = 30
+pm.start_servers = 10
+pm.min_spare_servers = 5
+pm.max_spare_servers = 20
+pm.max_requests = 500
+request_terminate_timeout = 120
+request_slowlog_timeout = 0
+
+env[HOSTNAME] = \$HOSTNAME
+env[PATH] = /usr/local/bin:/usr/bin:/bin
+env[TMP] = /tmp
+env[TEMP] = /tmp
+env[TMPDIR] = /tmp
+EOF
+
+cat << EOF >/etc/php/7.4/mods-available/opcache.ini
+; configuration for php opcache module
+; priority=10
+zend_extension=opcache.so
+opcache.enable=1
+opcache.enable_cli=1
+opcache.jit = off
+opcache.jit_buffer_size=128M
+opcache.memory_consumption=128
+opcache.interned_strings_buffer=8
+opcache.max_accelerated_files=4000
+opcache.validate_timestamps=1
+opcache.revalidate_freq=60
+opcache.fast_shutdown=1
+opcache.save_comments=1
+EOF
+
+mkdir -p /var/www/temp/
+chown -R www-data:www-data /var/www/html
+
+rm -rf /var/log/php.log
+rm -rf /run/php7.4-fpm.pid
+rm -rf /lib/systemd/system/php7.4-fpm.service
+cat << EOF >/etc/systemd/system/php7.4-fpm.service
+[Unit]
+Description=The PHP 7.4 FastCGI Process Manager
+After=network.target
+
+[Service]
+Type=simple
+PIDFile=/run/php7.4-fpm.pid
+ExecStartPre=/usr/bin/touch /var/log/php.log
+ExecStart=/usr/sbin/php-fpm7.4 --nodaemonize --fpm-config /etc/php/7.4/fpm/php-fpm.conf
+ExecReload=/bin/kill -USR2 \$MAINPID
+Restart=always
+RestartSec=2
+TimeoutStopSec=5
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl daemon-reload >/dev/null
+systemctl enable php7.4-fpm >/dev/null 2>&1
+systemctl restart php7.4-fpm
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Dependencies${cRES}"
+}
+
+
+
+installNginx(){
+echo -e "${WHITE}[...]\c" && echo -e "\t${WHITE}Nginx${cRES}\r\c"
+mkdir -p "/var/www/html"
+mkdir -p "/var/www/ssl"
+mkdir -p "/etc/nginx"
+mkdir -p "/etc/nginx/conf.d"
+mkdir -p "/var/log/nginx"
+mkdir -p "/var/cache/nginx/client_temp"
+mkdir -p "/var/cache/nginx/proxy_temp"
+mkdir -p "/var/cache/nginx/fastcgi_temp"
+mkdir -p "/var/cache/nginx/scgi_temp"
+mkdir -p "/var/cache/nginx/uwsgi_temp"
+
+if [[ -n $(unzip -tq /opt/de_GWD/.repo/nginxConf.zip | grep "No errors detected in compressed data") ]]; then
+rm -rf /tmp/nginxConf
+find /etc/nginx/ -type f | grep -v "conf.d" | xargs -i rm {}
+unzip /opt/de_GWD/.repo/nginxConf.zip -d /etc/nginx >/dev/null
+rm -rf /tmp/nginxConf
+else
+rm -rf /opt/de_GWD/.repo/nginxConf.zip
+echo -e "${WHITE}NGINX Configure${RED} Download Failed${cRES}" && exit
+fi
+
+rm -rf /lib/systemd/system/nginx.service
+cat << EOF >/etc/systemd/system/nginx.service
+[Unit]
+Description=NGINX
+After=network.target
+
+[Service]
+User=root
+Type=forking
+PIDFile=/run/nginx.pid
+ExecStartPre=$(which mkdir) -p /var/log/nginx
+ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
+ExecReload=/usr/sbin/nginx -s reload
+ExecStop=/bin/kill -s QUIT \$MAINPID
+ExecStopPost=$(which rm) -f /run/nginx.pid
+KillMode=process
+Restart=always
+RestartSec=2
+TimeoutStopSec=5
+
+[Install]
+WantedBy=multi-user.target
+EOF
+mkdir -p "/etc/systemd/system/nginx.service.d"
+printf "[Service]\nExecStartPost=/bin/sleep 0.1\n" >/etc/systemd/system/nginx.service.d/override.conf
+systemctl daemon-reload >/dev/null
+systemctl restart nginx
+systemctl enable nginx >/dev/null 2>&1
+
+[[ ! -f "/var/www/ssl/dhparam.pem" ]] && openssl dhparam -out /var/www/ssl/dhparam.pem 2048
+}
+
+
+
+nginxSet(){
+if [[ ! -f "/var/www/ssl/de_GWD.cer" ]] || [[ ! -f "/var/www/ssl/de_GWD.key" ]]; then
+cd /var/www/ssl
+openssl req -x509 -nodes -days 3650 \
+ -subj "/C=CA/ST=QC/O=Company, Inc./CN=localhost.com" \
+ -config <(cat /etc/ssl/openssl.cnf \
+ <(printf '[SAN]\nsubjectAltName=DNS:localhost')) \
+ -newkey rsa:2048 \
+ -keyout de_GWD.key \
+ -out de_GWD.cer
+cd ~
+fi
+
+[[ -z $serverName ]] && serverName="de_GWD"
+
+[[ -z $(echo $webUIport | grep '^[[:digit:]]*$') ]] && webUIport="443"
+jq --arg webUIport $webUIport '.address.webUIport=$webUIport' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+
+if [[ $webUIport = 443 ]]; then
+cat << EOF >/etc/nginx/conf.d/80.conf
+server {
+ listen 80;
+ server_name $serverName;
+ return 301 https://\$host\$request_uri;
+}
+EOF
+else
+rm -rf /etc/nginx/conf.d/80.conf
+fi
+
+touch /etc/nginx/conf.d/default.conf
+sed -i '/SERVER_BASE_START/,/SERVER_BASE_END/d' /etc/nginx/conf.d/default.conf
+sed -i '/PHP_START/,/PHP_END/d' /etc/nginx/conf.d/default.conf
+sed -i '/TTYD_START/,/TTYD_END/d' /etc/nginx/conf.d/default.conf
+sed -i '/NETDATA_START/,/NETDATA_END/d' /etc/nginx/conf.d/default.conf
+sed -i '$s/}$//' /etc/nginx/conf.d/default.conf
+
+until [[ $(head -1 /etc/nginx/conf.d/default.conf | cat -e) != "$" ]]; do
+ sed -i '1d' /etc/nginx/conf.d/default.conf
+done
+
+until [[ $(tail -1 /etc/nginx/conf.d/default.conf | cat -e) != "$" ]]; do
+ sed -i '$d' /etc/nginx/conf.d/default.conf
+done
+
+cat << EOF >/etc/nginx/conf.d/ssl_certificate
+ssl_certificate /var/www/ssl/de_GWD.cer;
+ssl_certificate_key /var/www/ssl/de_GWD.key;
+ssl_dhparam /var/www/ssl/dhparam.pem;
+ssl_protocols TLSv1.2 TLSv1.3;
+ssl_ecdh_curve CECPQ2:X25519:P-256;
+ssl_prefer_server_ciphers off;
+ssl_ciphers [ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]:[ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256;
+ssl_session_tickets off;
+ssl_session_cache shared:SSL:10m;
+ssl_session_timeout 6h;
+ssl_buffer_size 4k;
+EOF
+
+if [[ -f "/var/www/ssl/ocsp.resp" ]] && [[ -f "/var/www/ssl/bundle.pem" ]]; then
+cat << EOF >>/etc/nginx/conf.d/ssl_certificate
+ssl_trusted_certificate /var/www/ssl/bundle.pem;
+
+ssl_stapling on;
+ssl_stapling_verify on;
+ssl_stapling_file /var/www/ssl/ocsp.resp;
+
+ssl_early_data on;
+proxy_set_header Early-Data \$ssl_early_data;
+EOF
+fi
+
+cat << EOF >/etc/nginx/conf.d/default.conf
+# SERVER_BASE_START
+server {
+ listen $webUIport ssl http2 fastopen=256 reuseport;
+ server_name $serverName;
+ root /var/www/html;
+ index index.php index.html index.htm;
+ error_page 497 https://\$host:$webUIport\$request_uri;
+
+ include /etc/nginx/conf.d/ssl_certificate;
+
+ add_header X-Cache \$upstream_cache_status;
+
+ add_header Referrer-Policy "origin" always;
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header X-Download-Options "noopen" always;
+ add_header X-Frame-Options "SAMEORIGIN" always;
+ add_header X-Permitted-Cross-Domain-Policies "none" always;
+ add_header X-Robots-Tag "none" always;
+ add_header X-XSS-Protection "1; mode=block" always;
+ add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
+# SERVER_BASE_END
+
+# PHP_START
+location ~ [^/]\.php(/|$) {
+ fastcgi_split_path_info ^(.+?\.php)(/.*)$;
+ if (!-f \$document_root\$fastcgi_script_name) {
+ return 404;
+ }
+
+ fastcgi_pass unix:/run/php/php7.4-fpm.sock;
+ fastcgi_index index.php;
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
+ fastcgi_param FQDN true;
+}
+# PHP_END
+
+# TTYD_START
+location ~ ^/ttyd(.*)$ {
+ proxy_pass http://127.0.0.1:3000/\$1;
+ proxy_http_version 1.1;
+ proxy_set_header Host \$host;
+ proxy_set_header Upgrade \$http_upgrade;
+ proxy_set_header Connection "upgrade";
+ proxy_set_header REMOTE-HOST \$remote_addr;
+ proxy_set_header X-Forwarded-Proto \$scheme;
+ proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
+ keepalive_timeout 600;
+ proxy_connect_timeout 600;
+ proxy_read_timeout 600;
+ proxy_send_timeout 600;
+ proxy_store off;
+ proxy_redirect off;
+ proxy_buffering off;
+ proxy_buffer_size 8k;
+}
+# TTYD_END
+
+$(cat /etc/nginx/conf.d/default.conf 2>/dev/null)
+}
+EOF
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Nginx${cRES}"
+}
+
+
+
+installWebUI(){
+rm -rf /tmp/ui-script
+rm -rf /tmp/ui-web
+unzip /opt/de_GWD/.repo/client.zip -d /tmp >/dev/null 2>&1
+
+rm -rf /opt/de_GWD/ui-*
+rm -rf /opt/de_GWD/ui_*
+rm -rf /var/www/html/*.php
+rm -rf /var/www/html/*.ico
+rm -rf /var/www/html/act
+rm -rf /var/www/html/vendor
+rm -rf /var/www/html/css
+rm -rf /var/www/html/js
+
+mv -f /tmp/ui-script/* /opt/de_GWD >/dev/null
+mv -f /tmp/ui-web/* /var/www/html >/dev/null
+
+mkdir -p /var/www/html/restore
+chown -R www-data:www-data /var/www/html
+chmod -R +x /var/www/html
+chmod +x /opt/de_GWD/*
+
+if [[ $TTYD_UPDATE = "true" ]]; then
+[[ -z $(echo $updatePort | grep '^[[:digit:]]*$') ]] && updatePort="3000"
+
+rm -rf /lib/systemd/system/updateGWD.service
+cat << EOF >/etc/systemd/system/updateGWD.service
+[Unit]
+Description=updateGWD
+After=network.target
+
+[Service]
+User=root
+Type=oneshot
+ExecStartPre=/usr/bin/chmod +x /opt/de_GWD/update
+ExecStart=/usr/bin/tmux new -ds 'updateGWD' /usr/bin/ttyd -p $updatePort -o /opt/de_GWD/update
+KillMode=process
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl daemon-reload >/dev/null
+fi
+
+if [[ $(du -sk /var/www/html/spt 2>/dev/null | awk '{print$1}') -lt 102400 ]]; then
+ dd if=/dev/zero of=/var/www/html/spt bs=1k count=100k status=progress
+fi
+
+cp -f /opt/de_GWD/.repo/version.php /var/www/html/act/version.php
+}
+
+
+
+piholeConf(){
+rm -rf /etc/pihole/setupVars*
+cat << EOF >/etc/pihole/setupVars.conf
+PIHOLE_INTERFACE=$ethernetnum
+WEBPASSWORD=$piholePW
+IPV4_ADDRESS=$localAddrCIDR
+PIHOLE_DNS_1=127.0.0.1#5341
+PIHOLE_DNS_2=127.0.0.1#5341
+API_EXCLUDE_DOMAINS=www.google.com,www.baidu.com,raw.githubusercontent.com,api.cloudflare.com,myip.ipip.net,v4.yinghualuo.cn,www.f3322.org,*.in-addr.arpa,*._udp.lan
+QUERY_LOGGING=false
+INSTALL_WEB_SERVER=true
+INSTALL_WEB_INTERFACE=true
+LIGHTTPD_ENABLED=false
+CACHE_SIZE=10000
+DNS_FQDN_REQUIRED=true
+DNS_BOGUS_PRIV=true
+DNSSEC=false
+REV_SERVER=false
+DNSMASQ_LISTENING=single
+BLOCKING_ENABLED=true
+EOF
+}
+
+
+
+installPihole(){
+echo -e "${WHITE}[...]\c" && echo -e "\t${WHITE}Install Pi-hole${cRES}\r\c"
+piholeCoreVer=$(pihole -v 2>/dev/null | awk -F'is ' '{print$2}' | awk 'NR==1{print$1}')
+piholeWebUIVer=$(pihole -v 2>/dev/null | awk -F'is ' '{print$2}' | awk 'NR==2{print$1}')
+piholeFTLVer=$(pihole -v 2>/dev/null | awk -F'is ' '{print$2}' | awk 'NR==3{print$1}')
+
+piholeCoreRelease=$(curl -sSL "https://api.github.com/repos/pi-hole/pi-hole/releases/latest" | jq -r '.tag_name' | grep -v '^null$')
+piholeWebUIRelease=$(curl -sSL "https://api.github.com/repos/pi-hole/AdminLTE/releases/latest" | jq -r '.tag_name' | grep -v '^null$')
+piholeFTLRelease=$(curl -sSL "https://api.github.com/repos/pi-hole/FTL/releases/latest" | jq -r '.tag_name' | grep -v '^null$')
+
+if [[ -n $piholeCoreRelease ]] && [[ -n piholeWebUIRelease ]] && [[ -n $piholeFTLRelease ]]; then
+[[ -z $piholePW ]] && piholePW="0000000000000000000000000000000000000000000000000000000000000000"
+
+[[ $piholeCoreVer = $piholeCoreRelease ]] && [[ $piholeFTLVer = $piholeFTLRelease ]] && [[ $piholeWebUIVer = $piholeWebUIRelease ]] && [[ $(systemctl is-active 'pihole-FTL') = "active" ]] && return
+
+export PIHOLE_SKIP_OS_CHECK=true
+rm -rf /etc/.pihole /etc/pihole /opt/pihole /usr/bin/pihole-FTL /usr/local/bin/pihole /var/www/html/pihole /var/www/html/admin /var/log/pihole* /etc/dnsmasq.d*
+systemctl unmask lighttpd >/dev/null 2>&1
+systemctl unmask dhcpcd >/dev/null 2>&1
+
+mkdir -p /etc/.pihole
+mkdir -p /etc/pihole
+cat << EOF >/etc/pihole/adlists.list
+https://ewpratten.github.io/youtube_ad_blocklist/hosts.ipv4.txt
+EOF
+
+piholeConf
+
+git clone https://github.com/pi-hole/pi-hole /etc/.pihole
+cat "/etc/.pihole/automated install/basic-install.sh" | bash /dev/stdin --unattended
+chmod -R 755 /var/www/html
+usermod -aG pihole www-data
+
+PIHOLE_UPDATE="true"
+fi
+}
+
+
+
+piholeSet(){
+systemctl disable --now lighttpd >/dev/null 2>&1
+systemctl disable --now dhcpcd >/dev/null 2>&1
+systemctl mask --now lighttpd >/dev/null 2>&1
+systemctl mask --now dhcpcd >/dev/null 2>&1
+systemctl daemon-reload >/dev/null
+
+rm -rf /var/www/html/index.lighttpd.orig
+update-rc.d -f dhcpd remove >/dev/null 2>&1
+
+cat << EOF >/etc/hosts
+127.0.0.1 localhost
+$localAddr $(hostname).local $(hostname)
+
+# The following lines are desirable for IPv6 capable hosts
+::1 localhost ip6-localhost ip6-loopback
+ff02::1 ip6-allnodes
+ff02::2 ip6-allrouters
+EOF
+
+piholeConf
+
+[[ -f "/etc/dnsmasq.conf" ]] && sed -i '/listen-address=/d' /etc/dnsmasq.conf && sed -i '/port=/d' /etc/dnsmasq.conf
+
+>/etc/pihole/dns-servers.conf
+cat << EOF >/etc/pihole/pihole-FTL.conf
+BLOCKINGMODE=NULL
+CNAME_DEEP_INSPECT=true
+BLOCK_ESNI=true
+EDNS0_ECS=true
+RATE_LIMIT=0/0
+MOZILLA_CANARY=true
+BLOCK_ICLOUD_PR=false
+REPLY_WHEN_BUSY=ALLOW
+
+MAXLOGAGE=24.0
+PRIVACYLEVEL=0
+IGNORE_LOCALHOST=no
+AAAA_QUERY_ANALYSIS=no
+ANALYZE_ONLY_A_AND_AAAA=false
+SHOW_DNSSEC=false
+
+SOCKET_LISTENING=localonly
+FTLPORT=4711
+RESOLVE_IPV6=no
+RESOLVE_IPV4=yes
+PIHOLE_PTR=HOSTNAME
+DELAY_STARTUP=0
+NICE=-10
+MAXNETAGE=3
+NAMES_FROM_NETDB=true
+REFRESH_HOSTNAMES=IPV4
+PARSE_ARP_CACHE=true
+CHECK_LOAD=false
+
+DBIMPORT=yes
+MAXDBDAYS=3
+DBINTERVAL=10.0
+EOF
+
+cat << "EOF" >/opt/de_GWD/pihole_hotfix
+#!/bin/bash
+localIP=$(jq -r '.address.localIP' /opt/de_GWD/0conf | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
+sed -i "/dhcp-option=/c\dhcp-option=6,$localIP,$localIP" /etc/dnsmasq.d/02-pihole-dhcp.conf
+pihole restartdns
+EOF
+chmod +x /opt/de_GWD/pihole_hotfix
+
+sed -i '/pihole_hotfix/d' /var/www/html/admin/scripts/pi-hole/php/savesettings.php
+sed -i "/sudo pihole -a enabledhcp/a\exec('sudo /opt/de_GWD/pihole_hotfix >/dev/null 2>&1');" /var/www/html/admin/scripts/pi-hole/php/savesettings.php
+
+[[ $PIHOLE_UPDATE = "true" ]] && /opt/de_GWD/ui-submitADList
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Pi-hole Config ${cRES}"
+}
+
+
+
+postInstall(){
+/opt/de_GWD/ui-NodeOne
+/opt/de_GWD/ui_4am
+/opt/de_GWD/ui_4h
+
+if [[ $(jq -r '.FORWARD.block53' /opt/de_GWD/0conf 2>/dev/null) = "on" ]]; then
+ /opt/de_GWD/ui-block53on
+fi
+
+if [[ -n $(find /sys/class/net | grep wg0) ]]; then
+ echo "interface=wg0" >/etc/dnsmasq.d/00-wg.conf
+else
+ rm -rf /etc/dnsmasq.d/00-wg.conf
+fi
+echo
+sed -i '/cache-size=/c\cache-size=10000' /etc/dnsmasq.d/01-pihole.conf
+sed -i '/log-facility=/c\log-facility=/var/log/pihole.log' /etc/dnsmasq.d/01-pihole.conf
+sed -i '/server=/d' /etc/dnsmasq.d/01-pihole.conf
+awk '/PIHOLE_DNS_/' /etc/pihole/setupVars.conf | cut -d = -f 2 | sed 's/^/server=/g' >>/etc/dnsmasq.d/01-pihole.conf
+
+cat << EOF >/etc/dnsmasq.d/99-extra.conf
+dns-forward-max=10000
+edns-packet-max=1280
+all-servers
+EOF
+
+if [[ $(jq -r '.address.dhcp' /opt/de_GWD/0conf 2>/dev/null) = "on" ]]; then
+ /opt/de_GWD/ui-DHCPon
+else
+ /opt/de_GWD/ui-DHCPoff
+fi
+
+if [[ -n $(jq -r '.address.alias' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$') ]]; then
+ /opt/de_GWD/ui-markThis >/dev/null 2>&1
+fi
+
+if [[ $(jq -r '.v2nodeDIV.nodeSM.status' /opt/de_GWD/0conf 2>/dev/null) = "on" ]]; then
+ /opt/de_GWD/ui-NodeSM >/dev/null 2>&1
+fi
+
+if [[ $(jq -r '.v2nodeDIV.nodeCU.status' /opt/de_GWD/0conf 2>/dev/null) = "on" ]]; then
+ /opt/de_GWD/ui-NodeCU >/dev/null 2>&1
+fi
+
+if [[ $(jq -r '.v2nodeDIV.nodeDT.status' /opt/de_GWD/0conf 2>/dev/null) = "on" ]]; then
+ /opt/de_GWD/ui-NodeDT >/dev/null 2>&1
+fi
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}V2 Split${cRES}"
+
+if [[ $(jq -r '.FORWARD.FWD1.status' /opt/de_GWD/0conf 2>/dev/null) = "on" ]];then
+ /opt/de_GWD/ui-FWD1save >/dev/null 2>&1
+fi
+
+if [[ $(jq -r '.FORWARD.DoGs.status' /opt/de_GWD/0conf 2>/dev/null) = "on" ]];then
+ /opt/de_GWD/ui-DoGsSave >/dev/null 2>&1
+fi
+
+if [[ $(jq -r '.FORWARD.Rproxy.client.status' /opt/de_GWD/0conf 2>/dev/null) = "on" ]];then
+ /opt/de_GWD/ui-RproxyCsave >/dev/null 2>&1
+fi
+
+if [[ $(jq -r '.FORWARD.Rproxy.server.status' /opt/de_GWD/0conf 2>/dev/null) = "on" ]];then
+ /opt/de_GWD/ui-RproxySsave >/dev/null 2>&1
+fi
+
+systemctl restart mosdns
+systemctl restart vtrui
+
+/opt/de_GWD/ui_2h
+
+
+[[ -f "/etc/rc.local" ]] && [[ -n $(grep 'tc qdisc' /etc/rc.local) ]] && rm -rf /etc/rc.local
+
+cat << EOF >/etc/rc_online.local
+#!/bin/bash
+find /sys/class/net ! -type d | xargs --max-args=1 realpath | grep 'device' | grep 'virtual' | grep -v 'ifb' | awk -F'/' '{print\$NF}' | while read line; do
+$(which ip) link set \$line txqueuelen 5000
+
+$(which tc) qdisc del dev \$line root >/dev/null 2>&1
+$(which tc) qdisc add dev \$line root cake unlimited lan diffserv4 triple-isolate nonat nowash no-split-gso no-ack-filter raw egress
+
+$(which ip) link add name ifb4\$line type ifb >/dev/null 2>&1
+$(which tc) qdisc del dev \$line ingress >/dev/null 2>&1
+$(which tc) qdisc add dev \$line handle ffff: ingress
+$(which tc) qdisc del dev ifb4\$line root >/dev/null 2>&1
+$(which tc) qdisc add dev ifb4\$line root cake unlimited lan diffserv4 triple-isolate nonat nowash no-split-gso no-ack-filter raw ingress
+$(which ip) link set ifb4\$line txqueuelen 5000
+$(which ip) link set ifb4\$line up
+$(which tc) filter add dev \$line parent ffff: matchall action mirred egress redirect dev ifb4\$line
+done
+
+find /sys/class/net ! -type d | xargs --max-args=1 realpath | grep 'device' | grep -v 'virtual' | awk -F'/' '{print\$NF}' | while read line; do
+$(which ethtool) -s \$line duplex full >/dev/null 2>&1
+$(which ethtool) -K \$line rx on tx on tx-checksum-ipv4 on tx-checksum-ipv6 on sg off tso off gso off gro off lro off >/dev/null 2>&1
+
+$(which ip) link set \$line txqueuelen 5000
+
+$(which tc) qdisc del dev \$line root >/dev/null 2>&1
+$(which tc) qdisc add dev \$line root cake unlimited metro diffserv4 triple-isolate nonat nowash split-gso ack-filter raw egress
+
+$(which ip) link add name ifb4\$line type ifb >/dev/null 2>&1
+$(which tc) qdisc del dev \$line ingress >/dev/null 2>&1
+$(which tc) qdisc add dev \$line handle ffff: ingress
+$(which tc) qdisc del dev ifb4\$line root >/dev/null 2>&1
+$(which tc) qdisc add dev ifb4\$line root cake unlimited metro besteffort dual-dsthost nonat wash split-gso ack-filter raw ingress
+$(which ip) link set ifb4\$line txqueuelen 5000
+$(which ip) link set ifb4\$line up
+$(which tc) filter add dev \$line parent ffff: matchall action mirred egress redirect dev ifb4\$line
+done
+
+$(which ip) route change local 127.0.0.0/8 dev lo initcwnd 1000 initrwnd 1000
+$(which ip) route | grep default | while read line; do $(which ip) route change \$line initcwnd 32 initrwnd 32; done
+EOF
+chmod +x /etc/rc_online.local
+/etc/rc_online.local
+
+cat << "EOF" >/etc/rc_kernel.local
+#!/bin/bash
+PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
+
+sed -i "/net.core.default_qdisc/d" /etc/sysctl.conf
+sed -i '/net.ipv4.tcp_congestion_control/d' /etc/sysctl.conf
+
+echo "net.core.default_qdisc = cake" >>/etc/sysctl.conf
+
+if [[ $(uname -r) =~ "bbrplus" ]]; then
+ echo "net.ipv4.tcp_congestion_control = bbrplus" >>/etc/sysctl.conf
+else
+ echo "net.ipv4.tcp_congestion_control = bbr" >>/etc/sysctl.conf
+fi
+sysctl -p >/dev/null && sysctl -w net.ipv4.route.flush=1 >/dev/null 2>&1
+
+rm -f /var/lib/apt/lists/lock
+rm -f /var/cache/apt/archives/lock
+rm -f /var/lib/dpkg/lock
+dpkg --configure -a
+
+dpkg --list | grep linux-image | awk '{print $2}' | grep -Fv $(uname -r) | while read line; do
+apt -y purge $line
+done
+
+dpkg --list | grep linux-headers | awk '{print $2}' | grep -Fv $(uname -r) | while read line; do
+apt -y purge $line
+done
+EOF
+chmod +x /etc/rc_kernel.local
+
+
+crontab -l 2>/dev/null >/tmp/now.cron
+sed -i '/\/opt\/de_GWD\/ui_4am/d' /tmp/now.cron
+sed -i '/\/opt\/de_GWD\/ui_4h/d' /tmp/now.cron
+sed -i '/\/opt\/de_GWD\/ui_2h/d' /tmp/now.cron
+sed -i '/\/opt\/de_GWD\/clearKernel/d' /tmp/now.cron
+sed -i '/\/etc\/rc_.*/d' /tmp/now.cron
+cat << EOF >>/tmp/now.cron
+0 4 * * * /opt/de_GWD/ui_4am u
+0 */4 * * * /opt/de_GWD/ui_4h
+0 */2 * * * /opt/de_GWD/ui_2h
+@reboot sleep 10 && /etc/rc_kernel.local
+@reboot sleep 30 && /etc/rc_online.local
+EOF
+crontab /tmp/now.cron
+rm -rf /tmp/now.cron
+service cron restart
+
+rm -rf /tmp/ui-script
+rm -rf /tmp/ui-web
+rm -rf /tmp/client.zip
+rm -rf /opt/de_GWD/update
+
+if [[ $(dpkg --list | grep linux-image | wc -l) != "1" ]]; then
+echo -e "${WHITE}[ ${YELLOW}! ${WHITE}]\c" && echo -e "\t${YELLOW}Kernel updated${cRES}"
+fi
+}
+
+
+
+install3rdKernel(){
+bash <(wget --show-progress -cqO- https://raw.githubusercontent.com/jacyl4/de_GWD/main/resource/kernel/install3rdKernel)
+}
+
+restoreKernel(){
+bash <(wget --show-progress -cqO- https://raw.githubusercontent.com/jacyl4/de_GWD/main/resource/kernel/installDefaultKernel)
+}
+
+
+
+changeWP(){
+ echo -e "${GREEN}=========================== ${cRES}"
+ echo -e "${GREEN} Web UI Port${cRES}"
+ echo -e "${GREEN}=========================== ${cRES}"
+ read webUIport
+
+ echo -e "${GREEN}=========================== ${cRES}"
+ echo -e "${GREEN} Web update Port${cRES}"
+ echo -e "${GREEN}=========================== ${cRES}"
+ read updatePort
+
+serverName=$(jq -r '.address.serverName' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+nginxSet
+systemctl force-reload nginx >/dev/null
+
+sed -i "/ExecStart=/c\ExecStart=/usr/bin/ttyd -p $updatePort -o /opt/de_GWD/update" /etc/systemd/system/updateGWD.service
+systemctl daemon-reload >/dev/null
+
+jq --arg updatePort $updatePort '.update.updatePort=$updatePort' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Web UI Port & Web update Port ${GREEN}Updated${cRES}"
+}
+
+
+
+changePWD(){
+sudo pihole -a -p
+
+piholePW=$(awk '/WEBPASSWORD/' /etc/pihole/setupVars.conf 2>/dev/null | cut -d= -f2)
+
+jq --arg piholePW "$piholePW" '.address.PWD = $piholePW' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+chmod 666 /opt/de_GWD/0conf
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Password ${GREEN}Changed${cRES}"
+}
+
+
+
+installGWD(){
+ echo -e "${GREEN}=========================== ${cRES}"
+ echo -e "${GREEN} de_GWD local IP address${cRES}"
+ echo -e "${GREEN}=========================== ${cRES}"
+ read localAddr
+
+ echo -e "${GREEN}=========================== ${cRES}"
+ echo -e "${GREEN} Upstream route IP address${cRES}"
+ echo -e "${GREEN}=========================== ${cRES}"
+ read gatewayAddr
+
+ echo -e "${GREEN}=========================== ${cRES}"
+ echo -e "${GREEN} DoG / DoH${cRES}"
+ echo -e "${GREEN}=========================== ${cRES}"
+ read DoGorDOH
+
+ echo -e "${GREEN}=========================== ${cRES}"
+ echo -e "${GREEN} Address${cRES}"
+ echo -e "${GREEN}=========================== ${cRES}"
+ read v2addr
+
+ echo -e "${GREEN}=========================== ${cRES}"
+ echo -e "${GREEN} UUID${cRES}"
+ echo -e "${GREEN}=========================== ${cRES}"
+ read uuid
+
+ echo -e "${GREEN}=========================== ${cRES}"
+ echo -e "${GREEN} Path${cRES}"
+ echo -e "${GREEN}=========================== ${cRES}"
+ read path
+
+ethernetnum=$(ip --oneline link show up | grep -v "lo" | grep -v "noqueue" | awk '{print$2;exit}' | cut -d':' -f1 | cut -d'@' -f1)
+netmask=$(ip route | grep "$ethernetnum" | awk 'NR==2{print$1}' | sed -r 's/([0-9]{1,3}\.){3}[0-9]{1,3}//g')
+localAddr=$(echo $localAddr | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
+localAddrCIDR=$(echo "$localAddr$netmask")
+localCIDR="$(echo $localAddr | cut -d . -f1-3).0$netmask"
+
+if [[ $DoGorDOH =~ "/" ]]; then
+doh1=$DoGorDOH
+else
+DoG=$DoGorDOH
+fi
+
+domain=$(echo $v2addr | cut -d: -f1)
+port=$(echo $v2addr | cut -d: -f2 | grep '^[[:digit:]]*$')
+[[ -z $port ]] && port="443"
+tls=$domain
+
+rm -rf /etc/resolv.conf
+cat << EOF >/etc/resolv.conf
+nameserver 119.29.29.29
+nameserver 182.254.118.118
+nameserver 114.114.114.114
+nameserver 223.5.5.5
+EOF
+
+[[ $architecture = "arm64" ]] && apt-mark hold $(dpkg -l | grep 'linux-image-' | awk '{print $2}'); rm -rf /etc/apt/sources.list.d/armbian.list
+
+if [[ $(cat /etc/os-release | grep VERSION= | cut -d'(' -f2 | cut -d')' -f1) = "stretch" ]]; then
+cat << EOF >/etc/apt/sources.list
+deb http://$chnAPTsource/debian buster main contrib non-free
+deb http://$chnAPTsource/debian buster-updates main contrib non-free
+deb http://$chnAPTsource/debian-security buster/updates main contrib non-free
+EOF
+
+sed -i "s/ stretch / buster /g" /etc/apt/sources.list.d/* >/dev/null 2>&1
+apt update --fix-missing && apt upgrade --allow-downgrades -y
+apt full-upgrade -y && apt autoremove --purge -y && apt clean -y && apt autoclean -y
+fi
+
+cat << EOF >/etc/apt/sources.list
+deb http://$chnAPTsource/debian bullseye main contrib non-free
+deb http://$chnAPTsource/debian bullseye-updates main contrib non-free
+deb http://$chnAPTsource/debian bullseye-backports main contrib non-free
+deb http://$chnAPTsource/debian-security bullseye-security main contrib non-free
+EOF
+
+sed -i "s/ buster / bullseye /g" /etc/apt/sources.list.d/* >/dev/null 2>&1
+apt update --fix-missing && apt upgrade --allow-downgrades -y
+apt full-upgrade -y && apt autoremove --purge -y && apt clean -y && apt autoclean -y
+
+preInstall
+
+preConf
+
+preDL
+
+installSmartDNS
+
+installV2ray
+
+installNftables
+
+echo "{}" >/opt/de_GWD/0conf
+jq '.address={}' /opt/de_GWD/0conf |\
+jq '.dns={}' |\
+jq '.v2node=[]' |\
+jq '.update={}' |\
+jq --arg localIP "$localAddrCIDR" '.address.localIP=$localIP' |\
+jq --arg upstreamIP "$gatewayAddr" '.address.upstreamIP=$upstreamIP' |\
+jq --arg domain "$v2addr" '.v2node[0].domain=$domain' |\
+jq --arg name "$v2addr" '.v2node[0].name=$name' |\
+jq --arg uuid "$uuid" '.v2node[0].uuid=$uuid' |\
+jq --arg path "$path" '.v2node[0].path=$path' |\
+jq --arg updateAddr "$localAddr" '.update.updateAddr=$updateAddr' |\
+jq --arg updatePort "3000" '.update.updatePort=$updatePort' |\
+jq --arg updateCMD "$installCMD" '.update.updateCMD=$updateCMD' |\
+jq --arg domain "$domain" '.update.v2node.domain=$domain' |\
+jq --arg port "$port" '.update.v2node.port=$port' |\
+jq --arg tls "$tls" '.update.v2node.tls=$tls' |\
+jq --arg uuid "$uuid" '.update.v2node.uuid=$uuid' |\
+jq --arg path "$path" '.update.v2node.path=$path' | sponge /opt/de_GWD/0conf
+[[ -n $DoG ]] && jq --arg DoG "$DoG" '.dns.DoG=$DoG' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+[[ -n $doh1 ]] && jq --arg doh1 "$doh1" '.dns.doh+=[$doh1]' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+chmod 666 /opt/de_GWD/0conf
+
+de_GWDconnect
+
+updateAPT
+
+apt --reinstall install ca-certificates
+
+installDep
+
+repoDL
+
+installNginx
+
+nginxSet
+
+installWebUI
+
+installPihole
+
+piholeSet
+
+postInstall
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}de_GWD ${GREEN}Installed${cRES}"
+}
+
+
+
+updateGWD(){
+[[ -f "/opt/de_GWD/version.php" ]] && echo -e "${RED}This is not client${cRES}" && exit
+
+cleanDep
+
+preUpdate
+
+if [[ $1 = "auto" ]]; then
+de_GWDconnect u a
+else
+de_GWDconnect u
+fi
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}de_GWD ${GREEN}Updated${cRES}"
+}
+
+
+
+updateGWD_Green(){
+repoDL
+
+installDep
+
+installNginx
+
+nginxSet
+
+installWebUI
+
+preInstall
+
+preConf
+
+installSmartDNS
+
+installV2ray
+
+installNftables
+
+installPihole
+
+piholeSet
+
+postInstall
+}
+
+updateGWD_Red(){
+preInstall
+
+preConf
+
+preDL
+
+installSmartDNS
+
+installV2ray
+
+installNftables
+
+de_GWDconnect
+
+installDep
+
+repoDL
+
+installNginx
+
+nginxSet
+
+installWebUI
+
+installPihole
+
+piholeSet
+
+postInstall
+}
+
+
+
+start_menu(){
+echo
+if [[ $(systemctl is-active 'smartdns') = "active" ]]; then
+ echo -e "${WHITE} SmartDNS \c" && echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]${cRES}"
+elif [[ ! -x "/opt/de_GWD/smartdns/smartdns" ]]; then
+ echo -e "${WHITE} SmartDNS \c" && echo -e "${WHITE}[ ${YELLOW}! ${WHITE}]${cRES}"
+else
+ echo -e "${WHITE} SmartDNS \c" && echo -e "${WHITE}[ ${RED}✕ ${WHITE}]${cRES}"
+fi
+
+if [[ $(systemctl is-active 'mosdns') = "active" ]]; then
+ echo -e "${WHITE} mosdns \c" && echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]${cRES}"
+elif [[ ! -x "/opt/de_GWD/mosdns/mosdns" ]]; then
+ echo -e "${WHITE} mosdns \c" && echo -e "${WHITE}[ ${YELLOW}! ${WHITE}]${cRES}"
+else
+ echo -e "${WHITE} mosdns \c" && echo -e "${WHITE}[ ${RED}✕ ${WHITE}]${cRES}"
+fi
+
+if [[ $(systemctl is-active 'pihole-FTL') = "active" ]]; then
+ echo -e "${WHITE} Pi-hole \c" && echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]${cRES}"
+elif [[ ! -x "/usr/local/bin/pihole" ]]; then
+ echo -e "${WHITE} Pi-hole \c" && echo -e "${WHITE}[ ${YELLOW}! ${WHITE}]${cRES}"
+else
+ echo -e "${WHITE} Pi-hole \c" && echo -e "${WHITE}[ ${RED}✕ ${WHITE}]${cRES}"
+fi
+
+if [[ $(systemctl is-active 'vtrui') = "active" ]]; then
+ echo -e "${WHITE} v2ray \c" && echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]${cRES}"
+elif [[ ! -x "/opt/de_GWD/vtrui/vtrui" ]]; then
+ echo -e "${WHITE} v2ray \c" && echo -e "${WHITE}[ ${YELLOW}! ${WHITE}]${cRES}"
+else
+ echo -e "${WHITE} v2ray \c" && echo -e "${WHITE}[ ${RED}✕ ${WHITE}]${cRES}"
+fi
+
+if [[ $(systemctl is-active 'nginx') = "active" ]]; then
+ echo -e "${WHITE} Nginx \c" && echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]${cRES}"
+elif [[ ! -x "/usr/sbin/nginx" ]]; then
+ echo -e "${WHITE} Nginx \c" && echo -e "${WHITE}[ ${YELLOW}! ${WHITE}]${cRES}"
+else
+ echo -e "${WHITE} Nginx \c" && echo -e "${WHITE}[ ${RED}✕ ${WHITE}]${cRES}"
+fi
+
+if [[ $(systemctl is-active 'php7.4-fpm') = "active" ]]; then
+ echo -e "${WHITE} php7.4-FPM \c" && echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]${cRES}"
+elif [ ! -f "/etc/php/7.4/fpm/php-fpm.conf" ]; then
+ echo -e "${WHITE} php7.4-FPM \c" && echo -e "${WHITE}[ ${YELLOW}! ${WHITE}]${cRES}"
+else
+ echo -e "${WHITE} php7.4-FPM \c" && echo -e "${WHITE}[ ${RED}✕ ${WHITE}]${cRES}"
+fi
+
+if [[ -n $(crontab -l 2>&1 | grep "autoUpdate") ]] && [[ -f "/opt/de_GWD/autoUpdate" ]]; then
+ echo -e "${WHITE} AutoUpdate \c" && echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]${cRES}"
+else
+ echo -e "${WHITE} AutoUpdate \c" && echo -e "${WHITE}[ ${WHITE}- ${WHITE}]${cRES}"
+fi
+
+echo -e "${WHITE}---------------------- ${cRES}"
+
+if [[ $(du -sk /opt/de_GWD/mosdns/geosite.dat 2>/dev/null | awk '{print$1}') -gt 4400 ]]; then
+ echo -e "${WHITE} GeoSite \c" && echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]${cRES}"
+else
+ echo -e "${WHITE} GeoSite \c" && echo -e "${WHITE}[ ${RED}✕ ${WHITE}]${cRES}"
+fi
+
+if [[ $(du -sk /opt/de_GWD/vtrui/geoip.dat 2>/dev/null | awk '{print$1}') -ge 8000 ]]; then
+ echo -e "${WHITE} GeoIP \c" && echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]${cRES}"
+else
+ echo -e "${WHITE} GeoIP \c" && echo -e "${WHITE}[ ${RED}✕ ${WHITE}]${cRES}"
+fi
+
+if [[ $(du -sk /opt/de_GWD/nftables/IP_CHNROUTE 2>/dev/null | awk '{print$1}') -gt 100 ]]; then
+ echo -e "${WHITE} ChnrouteIP \c" && echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]${cRES}"
+else
+ echo -e "${WHITE} ChnrouteIP \c" && echo -e "${WHITE}[ ${RED}✕ ${WHITE}]${cRES}"
+fi
+ echo
+ echo -e "${BLUE}---------------------------------------------------------------- ${cRES}"
+ echo -e "${BLUE}Debian Version: $(cat /etc/os-release | grep VERSION= | cut -d'(' -f2 | cut -d')' -f1) ${cRES}"
+ echo -e "${BLUE}Kernel: $(uname -r) ${cRES}"
+ echo -e "${BLUE}---------------------------------------------------------------- ${cRES}"
+
+ echo -e "${GREEN}============CLIENT============================================== ${cRES}"
+ echo -e "${GREEN} __ _______ ______ ${cRES}"
+ echo -e "${GREEN} ____/ /__ / ____/ | / / __ \ ${cRES}"
+ echo -e "${GREEN} / __ / _ \ / / __ | | /| / / / / / ${cRES}"
+ echo -e "${GREEN}/ /_/ / __/ / /_/ / | |/ |/ / /_/ / ${cRES}"
+ echo -e "${GREEN}\__,_/\___/____\____/ |__/|__/_____/ ${cRES}"
+ echo -e "${GREEN} /_____/ ${cRES}"
+ echo
+ echo -e "${GREEN}Require: Debian (amd64 && arm64) ${cRES}"
+ echo -e "${GREEN}Author: JacyL4${cRES}"
+ echo -e "${GREEN}================================================================ ${cRES}"
+ echo
+ echo -e "${GREEN}1. Install de_GWD${cRES}"
+ echo -e "${GREEN}2. Install BBRplus / Liquorix / XanMod kernel and reboot${cRES}"
+ echo -e "${BLUE}3. Restore default kernel and reboot${cRES}"
+echo -e "${YELLOW}8. Change Web UI port & Web update port${cRES}"
+echo -e "${YELLOW}9. Change de_GWD password${cRES}"
+echo -e "${YELLOW}0. Update de_GWD${cRES}"
+echo -e "${RED}CTRL+C EXIT${cRES}"
+echo ""
+read -p "Select:" num
+ case "$num" in
+ 1)
+ installGWD
+ start_menu
+ ;;
+ 2)
+ install3rdKernel
+ start_menu
+ ;;
+ 3)
+ restoreKernel
+ start_menu
+ ;;
+ 8)
+ changeWP
+ start_menu
+ ;;
+ 9)
+ changePWD
+ start_menu
+ ;;
+ 0)
+ updateGWD
+ start_menu
+ ;;
+ *)
+ clear
+ echo -e "${RED}Wrong number${cRES}"
+ sleep 1s
+ start_menu
+ ;;
+ esac
+}
+
+start_menu
\ No newline at end of file
diff --git a/de_GWD_amd64.zip b/de_GWD_amd64.zip
new file mode 100755
index 000000000..02f69e0f1
Binary files /dev/null and b/de_GWD_amd64.zip differ
diff --git a/de_GWD_amd64.zip.sha256sum b/de_GWD_amd64.zip.sha256sum
new file mode 100644
index 000000000..2a93365ac
--- /dev/null
+++ b/de_GWD_amd64.zip.sha256sum
@@ -0,0 +1 @@
+f8b7ed74b0caff3a89fd26f4edafbb415b2e969fe5e5c3a2cd61d7f201e1dcaf
diff --git a/de_GWD_arm64.zip b/de_GWD_arm64.zip
new file mode 100755
index 000000000..afa78d52d
Binary files /dev/null and b/de_GWD_arm64.zip differ
diff --git a/de_GWD_arm64.zip.sha256sum b/de_GWD_arm64.zip.sha256sum
new file mode 100644
index 000000000..a82ed7b02
--- /dev/null
+++ b/de_GWD_arm64.zip.sha256sum
@@ -0,0 +1 @@
+8ddc3666b148d6732c02e8306ca2ad99203afe2c52ee6ed60b865a36d0700884
diff --git a/resource/client/Archive.zip b/resource/client/Archive.zip
new file mode 100644
index 000000000..d49eabc6d
Binary files /dev/null and b/resource/client/Archive.zip differ
diff --git a/resource/client/Archive.zip.sha256sum b/resource/client/Archive.zip.sha256sum
new file mode 100755
index 000000000..ec0349f16
--- /dev/null
+++ b/resource/client/Archive.zip.sha256sum
@@ -0,0 +1 @@
+b86a57574132beb0fe01672c4a1d434257ca6e886195be7a294d16d8f6d6788e
diff --git a/resource/client/ui-script/ui-DHCPoff b/resource/client/ui-script/ui-DHCPoff
new file mode 100755
index 000000000..1011cb5e3
--- /dev/null
+++ b/resource/client/ui-script/ui-DHCPoff
@@ -0,0 +1,50 @@
+#!/bin/bash
+RED='\E[1;31m'
+GREEN='\E[1;32m'
+YELLOW='\E[1;33m'
+BLUE='\E[1;34m'
+PURPLE='\E[1;35m'
+CYAN='\E[1;36m'
+WHITE='\E[1;37m'
+cRES='\E[0m'
+
+
+
+sed -i '/REV_SERVER=/d' /etc/pihole/setupVars.conf
+sed -i '/REV_SERVER_CIDR=/d' /etc/pihole/setupVars.conf
+sed -i '/REV_SERVER_TARGET=/d' /etc/pihole/setupVars.conf
+sed -i '/REV_SERVER_DOMAIN=/d' /etc/pihole/setupVars.conf
+if [[ $(jq -r '.FORWARD.block53' /opt/de_GWD/0conf 2>/dev/null) = "on" ]]; then
+cat << EOF >> /etc/pihole/setupVars.conf
+REV_SERVER=false
+EOF
+else
+upstreamIP=$(jq -r '.address.upstreamIP' /opt/de_GWD/0conf | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
+localAddrCIDR=$(jq -r '.address.localIP' /opt/de_GWD/0conf | grep -v '^null$')
+localAddr=$(echo $localAddrCIDR | cut -d / -f1)
+netmask=$(echo $localAddrCIDR | sed -r 's/([0-9]{1,3}\.){3}[0-9]{1,3}//g')
+
+[[ -z $netmask ]] && netmask="/24" && localAddrCIDR="$localAddr$netmask"
+cat << EOF >> /etc/pihole/setupVars.conf
+REV_SERVER=true
+REV_SERVER_CIDR=$localAddrCIDR
+REV_SERVER_TARGET=$upstreamIP
+EOF
+fi
+
+pihole -a disabledhcp >/dev/null 2>&1
+
+jq '.address.dhcp="off"' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+chmod 666 /opt/de_GWD/0conf
+
+[[ -z $(lsof -i:53 | grep pihole) ]] && pihole restartdns
+
+piholeTEST(){
+if [[ -n $(lsof -i:53 | grep pihole) ]]; then
+ echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c"
+else
+ echo -e "${WHITE}[ ${RED}✕ ${WHITE}]\c"
+fi
+}
+echo
+piholeTEST && echo -e "\t${WHITE}Pi-hole online${cRES}"
diff --git a/resource/client/ui-script/ui-DHCPon b/resource/client/ui-script/ui-DHCPon
new file mode 100755
index 000000000..19ec4137b
--- /dev/null
+++ b/resource/client/ui-script/ui-DHCPon
@@ -0,0 +1,50 @@
+#!/bin/bash
+RED='\E[1;31m'
+GREEN='\E[1;32m'
+YELLOW='\E[1;33m'
+BLUE='\E[1;34m'
+PURPLE='\E[1;35m'
+CYAN='\E[1;36m'
+WHITE='\E[1;37m'
+cRES='\E[0m'
+
+
+
+localAddrCIDR=$(jq -r '.address.localIP' /opt/de_GWD/0conf | grep -v '^null$')
+localAddr=$(echo $localAddrCIDR | cut -d / -f1)
+netmask=$(echo $localAddrCIDR | sed -r 's/([0-9]{1,3}\.){3}[0-9]{1,3}//g')
+
+[[ -z $netmask ]] && netmask="/24" && localAddrCIDR="$localAddr$netmask"
+netmaskNUM=$(echo $netmask | cut -d / -f2)
+
+dhcpStart=$(jq -r '.address.dhcpStart' /opt/de_GWD/0conf | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
+dhcpEnd=$(jq -r '.address.dhcpEnd' /opt/de_GWD/0conf | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
+
+if [[ -n $dhcpStart ]] && [[ -n $dhcpEnd ]] && [[ -n $localAddr ]]; then
+sed -i '/REV_SERVER=/d' /etc/pihole/setupVars.conf
+sed -i '/REV_SERVER_CIDR=/d' /etc/pihole/setupVars.conf
+sed -i '/REV_SERVER_TARGET=/d' /etc/pihole/setupVars.conf
+sed -i '/REV_SERVER_DOMAIN=/d' /etc/pihole/setupVars.conf
+cat << EOF >> /etc/pihole/setupVars.conf
+REV_SERVER=false
+EOF
+
+sudo pihole -a enabledhcp "$dhcpStart" "$dhcpEnd" "$localAddr" "$netmaskNUM" "lan" >/dev/null 2>&1
+
+/opt/de_GWD/pihole_hotfix
+
+jq '.address.dhcp="on"' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+chmod 666 /opt/de_GWD/0conf
+fi
+
+[[ -z $(lsof -i:53 | grep pihole) ]] && pihole restartdns
+
+piholeTEST(){
+if [[ -n $(lsof -i:53 | grep pihole) ]]; then
+ echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c"
+else
+ echo -e "${WHITE}[ ${RED}✕ ${WHITE}]\c"
+fi
+}
+echo
+piholeTEST && echo -e "\t${WHITE}Pi-hole online${cRES}"
diff --git a/resource/client/ui-script/ui-DNSclear b/resource/client/ui-script/ui-DNSclear
new file mode 100755
index 000000000..a5dd144ac
--- /dev/null
+++ b/resource/client/ui-script/ui-DNSclear
@@ -0,0 +1,7 @@
+#!/bin/bash
+redis-cli -a de_GWD -s /dev/shm/redis-server.sock -n 0 flushdb >/dev/null 2>&1
+systemctl restart mosdns
+
+systemctl stop pihole-FTL
+rm -rf rm /etc/pihole/pihole-FTL.db
+pihole restartdns
diff --git a/resource/client/ui-script/ui-DNSsplit b/resource/client/ui-script/ui-DNSsplit
new file mode 100755
index 000000000..df0c56568
--- /dev/null
+++ b/resource/client/ui-script/ui-DNSsplit
@@ -0,0 +1,270 @@
+#!/bin/bash
+RED='\E[1;31m'
+GREEN='\E[1;32m'
+YELLOW='\E[1;33m'
+BLUE='\E[1;34m'
+PURPLE='\E[1;35m'
+CYAN='\E[1;36m'
+WHITE='\E[1;37m'
+cRES='\E[0m'
+
+
+
+echo -e "${WHITE}[...]\c" && echo -e "\t${WHITE}DNS Split${cRES}\r\c"
+/opt/de_GWD/ui-NodeSave
+
+/opt/de_GWD/ui-submitListBW
+
+
+
+doh1=$(jq -r '.dns.doh[0]' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+doh2=$(jq -r '.dns.doh[1]' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+DoG=$(jq -r '.dns.dog' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+if [[ -n $doh1 ]]; then
+doh1Domain=$(echo $doh1 | cut -d/ -f1 | cut -d: -f1)
+doh1IP=$(dig @127.0.0.1 $doh1Domain -4p 5331 +short | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' | grep -v "127.0.0.1" | xargs -n 1 | awk NR==1)
+doh1Port=$(echo $doh1 | cut -d/ -f1 | cut -d: -f2 | grep '^[[:digit:]]*$')
+[[ -z $doh1Port ]] && doh1Port="443"
+fi
+
+if [[ -n $doh2 ]]; then
+doh2Domain=$(echo $doh2 | cut -d/ -f1 | cut -d: -f1)
+doh2IP=$(dig @127.0.0.1 $doh2Domain -4p 5331 +short | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' | grep -v "127.0.0.1" | xargs -n 1 | awk NR==1)
+doh2Port=$(echo $doh2 | cut -d/ -f1 | cut -d: -f2 | grep '^[[:digit:]]*$')
+[[ -z $doh2Port ]] && doh2Port="443"
+fi
+
+dns_global_doh1=`if [[ -n $doh1 ]]; then
+cat << EOF
+ - tag: 'dns_global_doh1'
+ type: fast_forward
+ args:
+ upstream:
+ - addr: 'https://$doh1'
+ dial_addr: '$doh1IP:$doh1Port'
+ trusted: true
+ insecure_skip_verify: true
+EOF
+fi
+`
+
+dns_global_doh2=`if [[ -n $doh2 ]]; then
+cat << EOF
+ - tag: 'dns_global_doh2'
+ type: fast_forward
+ args:
+ upstream:
+ - addr: 'https://$doh2'
+ dial_addr: '$doh2IP:$doh2Port'
+ trusted: true
+ insecure_skip_verify: true
+EOF
+fi
+`
+
+dns_global_dog=`if [[ -n $DoG ]]; then
+cat << EOF
+ - tag: 'dns_global_dog'
+ type: fast_forward
+ args:
+ upstream:
+ - addr: '127.0.0.1:5333'
+ trusted: true
+ - addr: 'tcp://127.0.0.1:5333'
+ trusted: true
+EOF
+fi
+`
+
+cat << EOF >/opt/de_GWD/mosdns/forwarders.yaml
+plugins:
+ - tag: 'dns_chn'
+ type: fast_forward
+ args:
+ upstream:
+ - addr: '127.0.0.1:5331'
+ trusted: true
+ - addr: 'tcp://127.0.0.1:5331'
+ trusted: true
+
+$dns_global_doh1
+
+$dns_global_doh2
+
+$dns_global_dog
+EOF
+
+cat << EOF >/opt/de_GWD/mosdns/global_sequence.yaml
+plugins:
+ - tag: 'dns_global'
+ type: 'sequence'
+ args:
+ exec:
+ - parallel:
+EOF
+
+[[ -n $doh1IP ]] && yq eval -i '.plugins.[0].args.exec[0].parallel += ["dns_global_doh1"]' /opt/de_GWD/mosdns/global_sequence.yaml
+[[ -n $doh2IP ]] && yq eval -i '.plugins.[0].args.exec[0].parallel += ["dns_global_doh2"]' /opt/de_GWD/mosdns/global_sequence.yaml
+[[ -n $DoG ]] && yq eval -i '.plugins.[0].args.exec[0].parallel += ["dns_global_dog"]' /opt/de_GWD/mosdns/global_sequence.yaml
+
+
+
+cat << EOF >/opt/de_GWD/mosdns/matchers_hosts.yaml
+plugins:
+ - tag: 'de_GWD_hosts'
+ type: hosts
+ args:
+ hosts:
+ - localhost 127.0.0.1
+EOF
+
+[[ -n $doh1IP ]] && yq eval -i ".plugins.[0].args.hosts += [\"$doh1Domain $doh1IP\"]" /opt/de_GWD/mosdns/matchers_hosts.yaml
+[[ -n $doh2IP ]] && yq eval -i ".plugins.[0].args.hosts += [\"$doh2Domain $doh2IP\"]" /opt/de_GWD/mosdns/matchers_hosts.yaml
+
+if [[ -n $(jq -r '.dns.hosts' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$') ]]; then
+jq -r '.dns.hosts | to_entries[] | [.value, .key] | @tsv' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$' | sed 's/[[:space:]][[:space:]]*/ /g' >/etc/pihole/custom.list
+
+jq -r '.dns.hosts | to_entries[] | [.key, .value] | @tsv' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$' | sed 's/[[:space:]][[:space:]]*/ /g' | while read line; do
+ yq eval -i ".plugins.[0].args.hosts += [\"$line\"]" /opt/de_GWD/mosdns/matchers_hosts.yaml
+done
+fi
+
+
+
+cat << EOF >/opt/de_GWD/mosdns/config.yaml
+log:
+ level: error
+ file: ''
+
+data_providers:
+ - tag: geosite
+ file: ./geosite.dat
+ auto_reload: true
+ - tag: geoip
+ file: ./geoip.dat
+ auto_reload: true
+
+include:
+ - 'matchers_hosts.yaml'
+ - 'matchers_nodes.yaml'
+ - 'matchers_listB.yaml'
+ - 'matchers_listW.yaml'
+ - 'forwarders.yaml'
+ - 'global_sequence.yaml'
+
+plugins:
+ - tag: 'de_GWD_cache'
+ type: cache
+ args:
+ size: 100000
+ redis: 'unix://:de_GWD@/dev/shm/redis-server.sock?db=0'
+ redis_timeout: 50
+ lazy_cache_ttl: 86400
+ lazy_cache_reply_ttl: 30
+ cache_everything: true
+
+ - tag: 'ttl_c'
+ type: ttl
+ args:
+ minimal_ttl: 60
+ maximum_ttl: 3600
+
+ - tag: 'domains_chn'
+ type: query_matcher
+ args:
+ domain:
+ - 'provider:geosite:cn'
+ - 'provider:geosite:tld-cn'
+
+ - tag: 'IPs_chn'
+ type: response_matcher
+ args:
+ ip:
+ - 'provider:geoip:cn'
+
+ - tag: 'dns_global_sequence'
+ type: sequence
+ args:
+ exec:
+ - '_no_ecs'
+ - 'dns_global'
+ - 'ttl_c'
+
+ - tag: 'dns_chn_sequence'
+ type: sequence
+ args:
+ exec:
+ - '_no_ecs'
+ - 'dns_chn'
+ - 'ttl_c'
+
+ - tag: 'dns_chnFB_sequence'
+ type: sequence
+ args:
+ exec:
+ - primary:
+ - '_no_ecs'
+ - 'dns_chn'
+ - 'ttl_c'
+ - if: '!IPs_chn'
+ exec:
+ - _drop_response
+ secondary:
+ - '_no_ecs'
+ - 'dns_global'
+ - 'ttl_c'
+ stat_length: 10
+ threshold: 5
+ fast_fallback: 250
+ always_standby: true
+
+ - tag: 'de_GWD_dns_split'
+ type: sequence
+ args:
+ exec:
+ - 'de_GWD_hosts'
+ - '_misc_optm'
+ - 'de_GWD_cache'
+
+ - if: 'domains_listB'
+ exec:
+ - 'dns_global_sequence'
+ - _return
+
+ - if: 'domains_listW'
+ exec:
+ - 'dns_chn_sequence'
+ - _return
+
+ - if: 'domains_nodes'
+ exec:
+ - 'dns_global_sequence'
+ - _return
+
+ - if: 'domains_chn'
+ exec:
+ - 'dns_chnFB_sequence'
+ - _return
+
+ - 'dns_global_sequence'
+
+servers:
+ - exec: de_GWD_dns_split
+ listeners:
+ - protocol: udp
+ addr: 127.0.0.1:5341
+ - protocol: tcp
+ addr: 127.0.0.1:5341
+EOF
+
+systemctl restart mosdns
+
+if [[ $? -ne 0 ]]; then
+sed -i '/Nice=/d' /etc/systemd/system/mosdns.service
+systemctl daemon-reload >/dev/null
+systemctl restart mosdns
+fi
+systemctl enable mosdns >/dev/null 2>&1
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}DNS Split${cRES}"
diff --git a/resource/client/ui-script/ui-DoGsSave b/resource/client/ui-script/ui-DoGsSave
new file mode 100755
index 000000000..f72161fd3
--- /dev/null
+++ b/resource/client/ui-script/ui-DoGsSave
@@ -0,0 +1,25 @@
+#!/bin/bash
+DoGsPort=$(jq -r '.FORWARD.DoGs.port' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+if [[ -n $DoGsPort ]]; then
+touch /opt/de_GWD/coredns/corefile
+sed -i '/DoGs_START/,/DoGs_END/d' /opt/de_GWD/coredns/corefile
+tac /opt/de_GWD/coredns/corefile | awk 'NF>0{x=1}x' | tac | sponge /opt/de_GWD/coredns/corefile >/dev/null 2>&1
+cat << EOF >>/opt/de_GWD/coredns/corefile
+
+# DoGs_START
+grpc://.:$DoGsPort {
+ tls /var/www/ssl/de_GWD.cer /var/www/ssl/de_GWD.key
+ forward . 127.0.0.1:53 {
+ prefer_udp
+ }
+ template ANY AAAA {
+ rcode NXDOMAIN
+ }
+}
+# DoGs_END
+EOF
+
+systemctl enable coredns >/dev/null 2>&1
+systemctl restart coredns
+fi
diff --git a/resource/client/ui-script/ui-DoGsStop b/resource/client/ui-script/ui-DoGsStop
new file mode 100755
index 000000000..e872fb460
--- /dev/null
+++ b/resource/client/ui-script/ui-DoGsStop
@@ -0,0 +1,8 @@
+#!/bin/bash
+sed -i '/DoGs_START/,/DoGs_END/d' /opt/de_GWD/coredns/corefile
+if [[ $(cat /opt/de_GWD/coredns/corefile | wc -c) -lt 11 ]]; then
+systemctl disable coredns >/dev/null 2>&1
+systemctl stop coredns
+else
+systemctl restart coredns
+fi
diff --git a/resource/client/ui-script/ui-FWD0save b/resource/client/ui-script/ui-FWD0save
new file mode 100755
index 000000000..391efa385
--- /dev/null
+++ b/resource/client/ui-script/ui-FWD0save
@@ -0,0 +1,27 @@
+#!/bin/bash
+FWD0port=$(jq -r '.FORWARD.FWD0.port' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+FWD0uuid=$(jq -r '.FORWARD.FWD0.uuid[].FWD0uuid' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+FWD0in=`cat << EOF
+ {
+ "tag": "forward0",
+ "port": $FWD0port,
+ "protocol": "vmess",
+ "settings":{
+ "clients":[]
+ },
+ "streamSettings": {
+ "network": "tcp"
+ }
+ }
+EOF
+`
+jq --argjson FWD0in "$FWD0in" '.inbounds[1]=$FWD0in' /opt/de_GWD/vtrui/config.json | sponge /opt/de_GWD/vtrui/config.json
+
+for uuid in $FWD0uuid; do
+uuidStr='{"id":"'$uuid'","alterId":0}'
+jq --argjson uuidStr1 "$uuidStr" '.inbounds[1].settings.clients+=[$uuidStr1]' /opt/de_GWD/vtrui/config.json | sponge /opt/de_GWD/vtrui/config.json
+done
+chmod 644 /var/www/ssl/*.key
+
+[[ $1 = "r" ]] && systemctl restart vtrui >/dev/null
diff --git a/resource/client/ui-script/ui-FWD0stop b/resource/client/ui-script/ui-FWD0stop
new file mode 100755
index 000000000..1ab96514f
--- /dev/null
+++ b/resource/client/ui-script/ui-FWD0stop
@@ -0,0 +1,3 @@
+#!/bin/bash
+jq 'del(.inbounds[] | select(.tag == "forward0"))' /opt/de_GWD/vtrui/config.json | sponge /opt/de_GWD/vtrui/config.json
+systemctl restart vtrui >/dev/null
diff --git a/resource/client/ui-script/ui-FWD1save b/resource/client/ui-script/ui-FWD1save
new file mode 100755
index 000000000..0bbbd4b3a
--- /dev/null
+++ b/resource/client/ui-script/ui-FWD1save
@@ -0,0 +1,169 @@
+#!/bin/bash
+FWD1port=$(jq -r '.FORWARD.FWD1.port' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+FWD1uuid=$(jq -r '.FORWARD.FWD1.uuid[].FWD1uuid' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+FWD1upstream=$(jq -r '.FORWARD.FWD1.upstream' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+rm -rf /opt/de_GWD/vtrui1
+mkdir -p /opt/de_GWD/vtrui1
+cp -f /opt/de_GWD/vtrui/vtrui /opt/de_GWD/vtrui1/vtrui1
+chmod +x /opt/de_GWD/vtrui1/vtrui1
+
+v2nodeID=$(jq -r --arg FWD1upstream $FWD1upstream '.v2node | to_entries[] | select(.value.domain == $FWD1upstream) | .key' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+address=$(jq -r --arg v2nodeID "$v2nodeID" ".v2node[$v2nodeID].domain" /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+domain=$(echo $address | cut -d: -f1)
+port=$(echo $address | cut -d: -f2 | grep '^[[:digit:]]*$')
+[[ -z $port ]] && port="443"
+[[ -z $tls ]] && tls=$domain
+
+tls=$(jq -r --arg v2nodeID "$v2nodeID" ".v2node[$v2nodeID].tls" /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+uuid=$(jq -r --arg v2nodeID "$v2nodeID" ".v2node[$v2nodeID].uuid" /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+path=$(jq -r --arg v2nodeID "$v2nodeID" ".v2node[$v2nodeID].path" /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+cat << EOF >/opt/de_GWD/vtrui1/config.json
+{
+ "log": {
+ "access":"none",
+ "error":"none",
+ "loglevel":"none"
+ },
+ "dns":{
+ "queryStrategy":"UseIP",
+ "disableCache":true,
+ "servers":["localhost"]
+ },
+ "inbounds":[
+ {
+ "port": $FWD1port,
+ "protocol": "vmess",
+ "settings":{
+ "clients":[]
+ },
+ "streamSettings": {
+ "network": "tcp"
+ }
+ }
+ ]
+}
+EOF
+
+if [[ -z $path ]]; then
+OBfwd=`cat << EOF
+ {
+ "protocol": "vmess",
+ "settings": {
+ "vnext": [
+ {
+ "address": "$domain",
+ "port": $port,
+ "users": [
+ {
+ "id": "$uuid",
+ "alterId": 0,
+ "security": "auto"
+ }
+ ]
+ }
+ ]
+ },
+ "streamSettings": {
+ "network": "tcp",
+ "sockopt": {
+ "mark": 255,
+ "tcpFastOpen": true
+ }
+ }
+ }
+EOF
+`
+else
+OBfwd=`cat << EOF
+{
+ "protocol": "vmess",
+ "settings": {
+ "vnext": [
+ {
+ "address": "$domain",
+ "port": $port,
+ "users": [
+ {
+ "id": "$uuid",
+ "alterId": 0,
+ "security": "auto"
+ }
+ ]
+ }
+ ]
+ },
+ "streamSettings": {
+ "network": "ws",
+ "wsSettings": {
+ "path": "$path",
+ "headers": {
+ "Host": "$tls"
+ }
+ },
+ "security": "tls",
+ "tlsSettings": {
+ "serverName": "$tls",
+ "allowInsecure": false
+ },
+ "sockopt": {
+ "mark": 255,
+ "tcpFastOpen": true
+ }
+ }
+}
+EOF
+`
+fi
+
+OBdir=`cat << EOF
+{
+ "tag":"direct",
+ "protocol":"freedom",
+ "streamSettings":{"sockopt":{"mark":255}}
+}
+EOF
+`
+
+for uuid in $FWD1uuid; do
+uuidStr='{"id":"'$uuid'","alterId":0}'
+jq --argjson uuidStr "$uuidStr" '.inbounds[0].settings.clients+=[$uuidStr]' /opt/de_GWD/vtrui1/config.json | sponge /opt/de_GWD/vtrui1/config.json
+done
+jq '.outbounds=[]' /opt/de_GWD/vtrui1/config.json |\
+jq --argjson OBfwd "$OBfwd" '.outbounds+=[$OBfwd]' |\
+jq --argjson OBdir "$OBdir" '.outbounds+=[$OBdir]' | sponge /opt/de_GWD/vtrui1/config.json
+
+chmod 666 /opt/de_GWD/vtrui1/config.json
+chmod 644 /var/www/ssl/*.key
+
+rm -rf /lib/systemd/system/vtrui1.service
+cat << "EOF" >/etc/systemd/system/vtrui1.service
+[Unit]
+Description=vtrui1
+After=network.target nss-lookup.target
+
+[Service]
+User=root
+Type=simple
+ExecStart=/opt/de_GWD/vtrui1/vtrui1 run -config /opt/de_GWD/vtrui1/config.json
+Restart=always
+RestartSec=2
+TimeoutStopSec=5
+
+Nice=-9
+AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN CAP_NET_BIND_SERVICE
+NoNewPrivileges=true
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl daemon-reload >/dev/null
+systemctl restart vtrui1
+if [[ $? -ne 0 ]]; then
+sed -i '/Nice=/d' /etc/systemd/system/vtrui1.service
+systemctl daemon-reload >/dev/null
+systemctl restart vtrui1
+fi
+systemctl enable vtrui1 >/dev/null 2>&1
diff --git a/resource/client/ui-script/ui-FWD1stop b/resource/client/ui-script/ui-FWD1stop
new file mode 100755
index 000000000..dcc3c44ae
--- /dev/null
+++ b/resource/client/ui-script/ui-FWD1stop
@@ -0,0 +1,8 @@
+#!/bin/bash
+systemctl stop vtrui1 >/dev/null
+systemctl disable vtrui1 >/dev/null
+rm -rf /lib/systemd/system/vtrui1.service
+rm -rf /etc/systemd/system/vtrui1.service
+systemctl daemon-reload >/dev/null
+
+rm -rf /opt/de_GWD/vtrui1
diff --git a/resource/client/ui-script/ui-NFSoff b/resource/client/ui-script/ui-NFSoff
new file mode 100755
index 000000000..a45a9d476
--- /dev/null
+++ b/resource/client/ui-script/ui-NFSoff
@@ -0,0 +1,9 @@
+#!/bin/bash
+NFSpoint=$(echo "$1" | sed 's/\//\\\//g')
+sed -i "/$NFSpoint/d" /etc/auto.nfs
+
+systemctl restart autofs
+
+awk '{print$1}' /etc/auto.nfs | while read line; do
+cd $line
+done
\ No newline at end of file
diff --git a/resource/client/ui-script/ui-NFSon b/resource/client/ui-script/ui-NFSon
new file mode 100755
index 000000000..8b042c34a
--- /dev/null
+++ b/resource/client/ui-script/ui-NFSon
@@ -0,0 +1,22 @@
+#!/bin/bash
+>/etc/auto.nfs
+
+nfsNUM=$(jq -r '.app.NFS | length' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+for ((i=0; i<$nfsNUM; i++)); do
+NFSpoint=$(jq -r --argjson i "$i" '.app.NFS[$i].NFSpoint' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+NFSserver=$(jq -r --argjson i "$i" '.app.NFS[$i].NFSserver' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+NFSaddress=$(jq -r --argjson i "$i" '.app.NFS[$i].NFSaddress' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+mkdir -p $NFSpoint
+echo "$NFSpoint -soft,rw,noatime,noresvport,nosuid,sync,timeout=0 $NFSserver:$NFSaddress" >>/etc/auto.nfs
+done
+
+awk '!i[$1]++' /etc/auto.nfs | sponge /etc/auto.nfs
+
+systemctl enable autofs
+systemctl restart autofs
+
+awk '{print$1}' /etc/auto.nfs | while read line; do
+cd $line
+done
+
diff --git a/resource/client/ui-script/ui-NodeCU b/resource/client/ui-script/ui-NodeCU
new file mode 100755
index 000000000..a10bbc11d
--- /dev/null
+++ b/resource/client/ui-script/ui-NodeCU
@@ -0,0 +1,38 @@
+#!/bin/bash
+tag="custom"
+
+jq 'del(.outbounds[] | select(.tag == "custom"))' /opt/de_GWD/vtrui/config.json |\
+jq 'del(.routing.rules[] | select(.outboundTag == "custom"))' | sponge /opt/de_GWD/vtrui/config.json
+
+if [[ -n $2 ]]; then
+address=$(jq -r --argjson nodecheck $2 '.v2node | to_entries[] | select(.key == $nodecheck) | .value.domain' /opt/de_GWD/0conf)
+tls=$(jq -r --argjson nodecheck $2 '.v2node | to_entries[] | select(.key == $nodecheck) | .value.tls' /opt/de_GWD/0conf)
+uuid=$(jq -r --argjson nodecheck $2 '.v2node | to_entries[] | select(.key == $nodecheck) | .value.uuid' /opt/de_GWD/0conf)
+path=$(jq -r --argjson nodecheck $2 '.v2node | to_entries[] | select(.key == $nodecheck) | .value.path' /opt/de_GWD/0conf)
+/opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+
+jq --arg address $address '.v2nodeDIV.nodeCU.address=$address' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+else
+address=$(jq -r '.v2nodeDIV.nodeCU.address' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+ if [[ -n $address ]]; then
+ tls=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.tls' /opt/de_GWD/0conf)
+ uuid=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.uuid' /opt/de_GWD/0conf)
+ path=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.path' /opt/de_GWD/0conf)
+ /opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+ fi
+fi
+
+jq -r '.v2nodeDIV.nodeCU.rulesDomain[]' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$' >/tmp/routingDomain
+jq -r '.v2nodeDIV.nodeCU.rulesIP[]' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$' >/tmp/routingIP
+routingDomain=$(echo $(jq -R -s -c 'split("\n")' < /tmp/routingDomain) | jq -c '.[:-1]')
+routingIP=$(echo $(jq -R -s -c 'split("\n")' < /tmp/routingIP) | jq -c '.[:-1]')
+
+[[ -n $(cat /tmp/routingDomain) ]] && /opt/de_GWD/ui-V2routingDomain $tag $routingDomain
+[[ -n $(cat /tmp/routingIP) ]] && /opt/de_GWD/ui-V2routingIP $tag $routingIP
+
+jq '.v2nodeDIV.nodeCU.status="on"' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+
+[[ $1 = "r" ]] && systemctl restart vtrui >/dev/null
+chmod 666 /opt/de_GWD/0conf
+rm -rf /tmp/routingDomain
+rm -rf /tmp/routingIP
diff --git a/resource/client/ui-script/ui-NodeCUcheck b/resource/client/ui-script/ui-NodeCUcheck
new file mode 100755
index 000000000..2c2b225f0
--- /dev/null
+++ b/resource/client/ui-script/ui-NodeCUcheck
@@ -0,0 +1,11 @@
+#!/bin/bash
+domain=$(jq -r '.outbounds[] | select(.tag == "custom") | .settings.vnext[0].address' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+port=$(jq -r '.outbounds[] | select(.tag == "custom") | .settings.vnext[0].port' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+
+if [[ $port = "443" ]]; then
+nodecheck=$domain
+else
+nodecheck=$domain:$port
+fi
+
+jq -r --arg nodecheck $nodecheck '.v2node[] | select(.domain == $nodecheck) | .name' /opt/de_GWD/0conf
diff --git a/resource/client/ui-script/ui-NodeCUhide b/resource/client/ui-script/ui-NodeCUhide
new file mode 100755
index 000000000..707bf84cc
--- /dev/null
+++ b/resource/client/ui-script/ui-NodeCUhide
@@ -0,0 +1,8 @@
+#!/bin/bash
+jq 'del(.outbounds[] | select(.tag == "custom"))' /opt/de_GWD/vtrui/config.json |\
+jq 'del(.routing.rules[] | select(.outboundTag == "custom"))' | sponge /opt/de_GWD/vtrui/config.json
+
+jq '.v2nodeDIV.nodeCU.status="off"' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+chmod 666 /opt/de_GWD/0conf
+
+[[ $1 = "r" ]] && systemctl restart vtrui >/dev/null
diff --git a/resource/client/ui-script/ui-NodeChange b/resource/client/ui-script/ui-NodeChange
new file mode 100755
index 000000000..c8052d6f7
--- /dev/null
+++ b/resource/client/ui-script/ui-NodeChange
@@ -0,0 +1,98 @@
+#!/bin/bash
+address=$(jq -r --argjson domainNUM "$1" '.v2node | to_entries[] | select(.key == $domainNUM) | .value.domain' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+tls=$(jq -r --argjson domainNUM "$1" '.v2node | to_entries[] | select(.key == $domainNUM) | .value.tls' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+uuid=$(jq -r --argjson domainNUM "$1" '.v2node | to_entries[] | select(.key == $domainNUM) | .value.uuid' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+path=$(jq -r --argjson domainNUM "$1" '.v2node | to_entries[] | select(.key == $domainNUM) | .value.path' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+domain=$(echo -e $address | cut -d: -f1)
+port=$(echo -e $address | cut -d: -f2 | grep '^[[:digit:]]*$')
+[[ -z $port ]] && port="443"
+[[ -z $tls ]] && tls=$domain
+
+jq '.update.v2node={}' /opt/de_GWD/0conf |\
+jq --arg domain "$domain" '.update.v2node.domain=$domain' |\
+jq --arg tls "$tls" '.update.v2node.tls=$tls' |\
+jq --arg port "$port" '.update.v2node.port=$port' |\
+jq --arg uuid "$uuid" '.update.v2node.uuid=$uuid' |\
+jq --arg path "$path" '.update.v2node.path=$path' | sponge /opt/de_GWD/0conf
+chmod 666 /opt/de_GWD/0conf
+
+
+if [[ -z $path ]]; then
+OBdefault=`cat << EOF
+ {
+ "tag": "default",
+ "protocol": "vmess",
+ "settings": {
+ "vnext": [
+ {
+ "address": "$domain",
+ "port": $port,
+ "users": [
+ {
+ "id": "$uuid",
+ "alterId": 0,
+ "security": "auto"
+ }
+ ]
+ }
+ ]
+ },
+ "streamSettings": {
+ "network": "tcp",
+ "sockopt": {
+ "mark": 255,
+ "tcpFastOpen": true
+ }
+ },
+ "mux":{"enabled":false,"concurrency":-1}
+ }
+EOF
+`
+else
+OBdefault=`cat << EOF
+ {
+ "tag": "default",
+ "protocol": "vmess",
+ "settings": {
+ "vnext": [
+ {
+ "address": "$domain",
+ "port": $port,
+ "users": [
+ {
+ "id": "$uuid",
+ "alterId": 0,
+ "security": "auto"
+ }
+ ]
+ }
+ ]
+ },
+ "streamSettings": {
+ "network": "ws",
+ "wsSettings": {
+ "path": "$path",
+ "headers": {
+ "Host": "$tls"
+ }
+ },
+ "security": "tls",
+ "tlsSettings": {
+ "serverName": "$tls",
+ "allowInsecure": false
+ },
+ "sockopt": {
+ "mark": 255,
+ "tcpFastOpen": true
+ }
+ },
+ "mux":{"enabled":true,"concurrency":8}
+ }
+EOF
+`
+fi
+
+jq --argjson OBdefault "$OBdefault" '.outbounds[0]=$OBdefault' /opt/de_GWD/vtrui/config.json | sponge /opt/de_GWD/vtrui/config.json
+
+systemctl restart vtrui
diff --git a/resource/client/ui-script/ui-NodeDT b/resource/client/ui-script/ui-NodeDT
new file mode 100755
index 000000000..3f2696822
--- /dev/null
+++ b/resource/client/ui-script/ui-NodeDT
@@ -0,0 +1,81 @@
+#!/bin/bash
+tag="divert"
+
+jq 'del(.outbounds[] | select(.tag == "divert"))' /opt/de_GWD/vtrui/config.json |\
+jq 'del(.routing.rules[] | select(.outboundTag == "divert"))' | sponge /opt/de_GWD/vtrui/config.json
+
+if [[ -n $2 ]]; then
+address=$(jq -r --argjson nodecheck $2 '.v2node | to_entries[] | select(.key == $nodecheck) | .value.domain' /opt/de_GWD/0conf)
+tls=$(jq -r --argjson nodecheck $2 '.v2node | to_entries[] | select(.key == $nodecheck) | .value.tls' /opt/de_GWD/0conf)
+uuid=$(jq -r --argjson nodecheck $2 '.v2node | to_entries[] | select(.key == $nodecheck) | .value.uuid' /opt/de_GWD/0conf)
+path=$(jq -r --argjson nodecheck $2 '.v2node | to_entries[] | select(.key == $nodecheck) | .value.path' /opt/de_GWD/0conf)
+/opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+
+jq --arg address $address '.v2nodeDIV.nodeDT.address=$address' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+else
+address=$(jq -r '.v2nodeDIV.nodeDT.address' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+ if [[ -n $address ]]; then
+ tls=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.tls' /opt/de_GWD/0conf)
+ uuid=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.uuid' /opt/de_GWD/0conf)
+ path=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.path' /opt/de_GWD/0conf)
+ /opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+ else
+ address=$(jq -r '.update.v2node.domain' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+ tls=$(jq -r '.update.v2node.tls' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+ port=$(jq -r '.update.v2node.port' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+ uuid=$(jq -r '.update.v2node.uuid' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+ path=$(jq -r '.update.v2node.path' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+ /opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+ fi
+fi
+
+jq -r '.v2nodeDIV.nodeDT.CHNlistProxyIP[]' /opt/de_GWD/0conf 2>/dev/null | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' >/tmp/CHNlistProxyIP
+jq -r '.v2nodeDIV.nodeDT.globalProxyIP[]' /opt/de_GWD/0conf 2>/dev/null | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' | tee /tmp/globalProxyIP /opt/de_GWD/nftables/IP_listBlan >/dev/null 2>&1
+jq -r '.v2nodeDIV.nodeDT.directProxyIP[]' /opt/de_GWD/0conf 2>/dev/null | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' | tee /tmp/directProxyIP /opt/de_GWD/nftables/IP_listWlan >/dev/null 2>&1
+divertIP=$(cat /tmp/CHNlistProxyIP /tmp/globalProxyIP | jq -R -s -c 'split("\n")' | jq -c '.[:-1]')
+
+[[ -n $(jq '.[]' <<< "$divertIP") ]] && /opt/de_GWD/ui-V2routingSip $tag $divertIP
+
+jq '.v2nodeDIV.nodeDT.status="on"' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+
+sed -i '/^\s*$/d' /opt/de_GWD/nftables/IP_listBlan
+sed -i 's/$/,/g' /opt/de_GWD/nftables/IP_listBlan
+[[ -n $(cat /opt/de_GWD/nftables/IP_listBlan 2>&1 | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') ]] && IP_listBlan_elements="elements = { $(cat /opt/de_GWD/nftables/IP_listBlan) }"
+nft flush set ip de_GWD listBlan
+cat << EOF >/opt/de_GWD/nftables/SET_listBlan.nft
+#!/usr/sbin/nft -f
+table ip de_GWD {
+ set listBlan {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ $IP_listBlan_elements
+ }
+}
+EOF
+chmod +x /opt/de_GWD/nftables/SET_listBlan.nft
+/opt/de_GWD/nftables/SET_listBlan.nft
+
+sed -i '/^\s*$/d' /opt/de_GWD/nftables/IP_listWlan
+sed -i 's/$/,/g' /opt/de_GWD/nftables/IP_listWlan
+[[ -n $(cat /opt/de_GWD/nftables/IP_listWlan 2>&1 | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') ]] && IP_listWlan_elements="elements = { $(cat /opt/de_GWD/nftables/IP_listWlan) }"
+nft flush set ip de_GWD listWlan
+cat << EOF >/opt/de_GWD/nftables/SET_listWlan.nft
+#!/usr/sbin/nft -f
+table ip de_GWD {
+ set listWlan {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ $IP_listWlan_elements
+ }
+}
+EOF
+chmod +x /opt/de_GWD/nftables/SET_listWlan.nft
+/opt/de_GWD/nftables/SET_listWlan.nft
+
+[[ $1 = "r" ]] && systemctl restart vtrui >/dev/null
+chmod 666 /opt/de_GWD/0conf
+rm -rf /tmp/CHNlistProxyIP
+rm -rf /tmp/globalProxyIP
+rm -rf /tmp/directProxyIP
diff --git a/resource/client/ui-script/ui-NodeDTcheck b/resource/client/ui-script/ui-NodeDTcheck
new file mode 100755
index 000000000..6f2c3501c
--- /dev/null
+++ b/resource/client/ui-script/ui-NodeDTcheck
@@ -0,0 +1,11 @@
+#!/bin/bash
+domain=$(jq -r '.outbounds[] | select(.tag == "divert") | .settings.vnext[0].address' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+port=$(jq -r '.outbounds[] | select(.tag == "divert") | .settings.vnext[0].port' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+
+if [[ $port = "443" ]]; then
+nodecheck=$domain
+else
+nodecheck=$domain:$port
+fi
+
+jq -r --arg nodecheck $nodecheck '.v2node[] | select(.domain == $nodecheck) | .name' /opt/de_GWD/0conf
diff --git a/resource/client/ui-script/ui-NodeDThide b/resource/client/ui-script/ui-NodeDThide
new file mode 100755
index 000000000..a073792b1
--- /dev/null
+++ b/resource/client/ui-script/ui-NodeDThide
@@ -0,0 +1,8 @@
+#!/bin/bash
+jq 'del(.outbounds[] | select(.tag == "divert"))' /opt/de_GWD/vtrui/config.json |\
+jq 'del(.routing.rules[] | select(.outboundTag == "divert"))' | sponge /opt/de_GWD/vtrui/config.json
+
+jq '.v2nodeDIV.nodeDT.status="off"' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+chmod 666 /opt/de_GWD/0conf
+
+[[ $1 = "r" ]] && systemctl restart vtrui >/dev/null
diff --git a/resource/client/ui-script/ui-NodeOne b/resource/client/ui-script/ui-NodeOne
new file mode 100755
index 000000000..a1f63107a
--- /dev/null
+++ b/resource/client/ui-script/ui-NodeOne
@@ -0,0 +1,65 @@
+#!/bin/bash
+tag="default"
+domain=$(jq -r '.update.v2node.domain' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+port=$(jq -r '.update.v2node.port' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+tls=$(jq -r '.update.v2node.tls' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+uuid=$(jq -r '.update.v2node.uuid' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+path=$(jq -r '.update.v2node.path' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+address="$domain:$port"
+
+cat << EOF >/opt/de_GWD/vtrui/config.json
+{
+"log": {
+ "access":"none",
+ "error":"none",
+ "loglevel":"none"
+},
+"dns":{
+ "queryStrategy":"UseIP",
+ "disableCache":true,
+ "servers":["tcp+local://127.0.0.1:5341"]
+},
+"routing":{
+ "rules":[]
+},
+"inbounds":[
+ {
+ "port":9896,
+ "listen":"127.0.0.1",
+ "protocol":"dokodemo-door",
+ "settings":{"network":"tcp,udp","followRedirect":true},
+ "streamSettings":{"sockopt":{"tcpFastOpen":true,"tproxy":"tproxy"}},
+ "sniffing":{"enabled":true,"destOverride":["http","tls","quic"]}
+ }
+]
+}
+EOF
+
+/opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+
+OBdirect=`cat << EOF
+ {
+ "tag":"direct",
+ "protocol":"freedom",
+ "streamSettings":{"sockopt":{"mark":255}}
+ }
+EOF
+`
+jq --argjson OBdirect "$OBdirect" '.outbounds+=[$OBdirect]' /opt/de_GWD/vtrui/config.json | sponge /opt/de_GWD/vtrui/config.json
+
+
+if [[ $(jq -r '.FORWARD.FWD0.status' /opt/de_GWD/0conf 2>/dev/null) = "on" ]];then
+ /opt/de_GWD/ui-FWD0save >/dev/null 2>&1
+fi
+
+
+if [[ $1 = "f" ]]; then
+ jq '.v2nodeDIV.nodeCU.status="off"' /opt/de_GWD/0conf |\
+ jq '.v2nodeDIV.nodeDT.status="off"' | sponge /opt/de_GWD/0conf
+ chmod 666 /opt/de_GWD/0conf
+fi
+
+if [[ $2 = "r" ]]; then
+ systemctl restart vtrui
+fi
diff --git a/resource/client/ui-script/ui-NodeSM b/resource/client/ui-script/ui-NodeSM
new file mode 100755
index 000000000..49754d555
--- /dev/null
+++ b/resource/client/ui-script/ui-NodeSM
@@ -0,0 +1,202 @@
+#!/bin/bash
+jq 'del(.outbounds[] | select(.tag == "nodeSMyoutube"))' /opt/de_GWD/vtrui/config.json |\
+jq 'del(.outbounds[] | select(.tag == "nodeSMnetflix"))' |\
+jq 'del(.outbounds[] | select(.tag == "nodeSMhdh"))' |\
+jq 'del(.outbounds[] | select(.tag == "nodeSMtvb"))' |\
+jq 'del(.outbounds[] | select(.tag == "nodeSMbahamut"))' |\
+jq 'del(.outbounds[] | select(.tag == "nodeSMapple"))' |\
+jq 'del(.routing.rules[] | select(.outboundTag == "nodeSMyoutube"))' |\
+jq 'del(.routing.rules[] | select(.outboundTag == "nodeSMnetflix"))' |\
+jq 'del(.routing.rules[] | select(.outboundTag == "nodeSMhdh"))' |\
+jq 'del(.routing.rules[] | select(.outboundTag == "nodeSMtvb"))' |\
+jq 'del(.routing.rules[] | select(.outboundTag == "nodeSMbahamut"))' |\
+jq 'del(.routing.rules[] | select(.outboundTag == "nodeSMapple"))' |\
+jq 'del(.routing.rules[] | select(.domain == ["geosite:apple","geosite:apple-ads","geosite:apple-dev","geosite:apple-update","geosite:icloud","geosite:apple@cn","geosite:apple-cn"]))' |\
+jq 'del(.routing.rules[] | select(.domain == ["geosite:category-games@cn"]))' | sponge /opt/de_GWD/vtrui/config.json
+
+
+
+if [[ -n $2 ]] && [[ $2 != "0" ]]; then
+nodeSMnumYoutube=$[$2-1]
+address=$(jq -r --argjson nodecheck $nodeSMnumYoutube '.v2node | to_entries[] | select(.key == $nodecheck) | .value.domain' /opt/de_GWD/0conf)
+tls=$(jq -r --argjson nodecheck $nodeSMnumYoutube '.v2node | to_entries[] | select(.key == $nodecheck) | .value.tls' /opt/de_GWD/0conf)
+uuid=$(jq -r --argjson nodecheck $nodeSMnumYoutube '.v2node | to_entries[] | select(.key == $nodecheck) | .value.uuid' /opt/de_GWD/0conf)
+path=$(jq -r --argjson nodecheck $nodeSMnumYoutube '.v2node | to_entries[] | select(.key == $nodecheck) | .value.path' /opt/de_GWD/0conf)
+jq --arg address $address '.v2nodeDIV.nodeSM.youtube=$address' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+tag="nodeSMyoutube"
+routingDomain='["geosite:youtube"]'
+/opt/de_GWD/ui-V2routingDomain $tag $routingDomain
+/opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+elif [[ $2 = "0" ]]; then
+ jq 'del(.v2nodeDIV.nodeSM.youtube)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+else
+address=$(jq -r '.v2nodeDIV.nodeSM.youtube' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+ if [[ -n $address ]]; then
+ tls=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.tls' /opt/de_GWD/0conf)
+ uuid=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.uuid' /opt/de_GWD/0conf)
+ path=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.path' /opt/de_GWD/0conf)
+ tag="nodeSMyoutube"
+ routingDomain='["geosite:youtube"]'
+ /opt/de_GWD/ui-V2routingDomain $tag $routingDomain
+ /opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+ fi
+fi
+
+if [[ -n $3 ]] && [[ $3 != "0" ]]; then
+nodeSMnumNetflix=$[$3-1]
+address=$(jq -r --argjson nodecheck $nodeSMnumNetflix '.v2node | to_entries[] | select(.key == $nodecheck) | .value.domain' /opt/de_GWD/0conf)
+tls=$(jq -r --argjson nodecheck $nodeSMnumNetflix '.v2node | to_entries[] | select(.key == $nodecheck) | .value.tls' /opt/de_GWD/0conf)
+uuid=$(jq -r --argjson nodecheck $nodeSMnumNetflix '.v2node | to_entries[] | select(.key == $nodecheck) | .value.uuid' /opt/de_GWD/0conf)
+path=$(jq -r --argjson nodecheck $nodeSMnumNetflix '.v2node | to_entries[] | select(.key == $nodecheck) | .value.path' /opt/de_GWD/0conf)
+jq --arg address $address '.v2nodeDIV.nodeSM.netflix=$address' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+tag="nodeSMnetflix"
+routingDomain='["geosite:netflix"]'
+/opt/de_GWD/ui-V2routingDomain $tag $routingDomain
+/opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+elif [[ $3 = "0" ]]; then
+ jq 'del(.v2nodeDIV.nodeSM.netflix)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+else
+address=$(jq -r '.v2nodeDIV.nodeSM.netflix' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+ if [[ -n $address ]]; then
+ tls=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.tls' /opt/de_GWD/0conf)
+ uuid=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.uuid' /opt/de_GWD/0conf)
+ path=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.path' /opt/de_GWD/0conf)
+ tag="nodeSMnetflix"
+ routingDomain='["geosite:netflix"]'
+ /opt/de_GWD/ui-V2routingDomain $tag $routingDomain
+ /opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+ fi
+fi
+
+if [[ -n $4 ]] && [[ $4 != "0" ]]; then
+nodeSMnumHDH=$[$4-1]
+address=$(jq -r --argjson nodecheck $nodeSMnumHDH '.v2node | to_entries[] | select(.key == $nodecheck) | .value.domain' /opt/de_GWD/0conf)
+tls=$(jq -r --argjson nodecheck $nodeSMnumHDH '.v2node | to_entries[] | select(.key == $nodecheck) | .value.tls' /opt/de_GWD/0conf)
+uuid=$(jq -r --argjson nodecheck $nodeSMnumHDH '.v2node | to_entries[] | select(.key == $nodecheck) | .value.uuid' /opt/de_GWD/0conf)
+path=$(jq -r --argjson nodecheck $nodeSMnumHDH '.v2node | to_entries[] | select(.key == $nodecheck) | .value.path' /opt/de_GWD/0conf)
+jq --arg address $address '.v2nodeDIV.nodeSM.hdh=$address' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+tag="nodeSMhdh"
+routingDomain='["geosite:hbo","geosite:disney","geosite:hulu"]'
+/opt/de_GWD/ui-V2routingDomain $tag $routingDomain
+/opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+elif [[ $4 = "0" ]]; then
+ jq 'del(.v2nodeDIV.nodeSM.hdh)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+else
+address=$(jq -r '.v2nodeDIV.nodeSM.hdh' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+ if [[ -n $address ]]; then
+ tls=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.tls' /opt/de_GWD/0conf)
+ uuid=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.uuid' /opt/de_GWD/0conf)
+ path=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.path' /opt/de_GWD/0conf)
+ tag="nodeSMhdh"
+ routingDomain='["geosite:hbo","geosite:disney","geosite:hulu"]'
+ /opt/de_GWD/ui-V2routingDomain $tag $routingDomain
+ /opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+ fi
+fi
+
+if [[ -n $5 ]] && [[ $5 != "0" ]]; then
+nodeSMnumTVB=$[$5-1]
+address=$(jq -r --argjson nodecheck $nodeSMnumTVB '.v2node | to_entries[] | select(.key == $nodecheck) | .value.domain' /opt/de_GWD/0conf)
+tls=$(jq -r --argjson nodecheck $nodeSMnumTVB '.v2node | to_entries[] | select(.key == $nodecheck) | .value.tls' /opt/de_GWD/0conf)
+uuid=$(jq -r --argjson nodecheck $nodeSMnumTVB '.v2node | to_entries[] | select(.key == $nodecheck) | .value.uuid' /opt/de_GWD/0conf)
+path=$(jq -r --argjson nodecheck $nodeSMnumTVB '.v2node | to_entries[] | select(.key == $nodecheck) | .value.path' /opt/de_GWD/0conf)
+jq --arg address $address '.v2nodeDIV.nodeSM.tvb=$address' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+tag="nodeSMtvb"
+routingDomain='["geosite:tvb"]'
+/opt/de_GWD/ui-V2routingDomain $tag $routingDomain
+/opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+elif [[ $5 = "0" ]]; then
+ jq 'del(.v2nodeDIV.nodeSM.tvb)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+else
+address=$(jq -r '.v2nodeDIV.nodeSM.tvb' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+ if [[ -n $address ]]; then
+ tls=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.tls' /opt/de_GWD/0conf)
+ uuid=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.uuid' /opt/de_GWD/0conf)
+ path=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.path' /opt/de_GWD/0conf)
+ tag="nodeSMtvb"
+ routingDomain='["geosite:tvb"]'
+ /opt/de_GWD/ui-V2routingDomain $tag $routingDomain
+ /opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+ fi
+fi
+
+if [[ -n $6 ]] && [[ $6 != "0" ]]; then
+nodeSMnumBahamut=$[$6-1]
+address=$(jq -r --argjson nodecheck $nodeSMnumBahamut '.v2node | to_entries[] | select(.key == $nodecheck) | .value.domain' /opt/de_GWD/0conf)
+tls=$(jq -r --argjson nodecheck $nodeSMnumBahamut '.v2node | to_entries[] | select(.key == $nodecheck) | .value.tls' /opt/de_GWD/0conf)
+uuid=$(jq -r --argjson nodecheck $nodeSMnumBahamut '.v2node | to_entries[] | select(.key == $nodecheck) | .value.uuid' /opt/de_GWD/0conf)
+path=$(jq -r --argjson nodecheck $nodeSMnumBahamut '.v2node | to_entries[] | select(.key == $nodecheck) | .value.path' /opt/de_GWD/0conf)
+jq --arg address $address '.v2nodeDIV.nodeSM.bahamut=$address' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+tag="nodeSMbahamut"
+routingDomain='["geosite:bahamut"]'
+/opt/de_GWD/ui-V2routingDomain $tag $routingDomain
+/opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+elif [[ $6 = "0" ]]; then
+ jq 'del(.v2nodeDIV.nodeSM.bahamut)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+else
+address=$(jq -r '.v2nodeDIV.nodeSM.bahamut' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+ if [[ -n $address ]]; then
+ tls=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.tls' /opt/de_GWD/0conf)
+ uuid=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.uuid' /opt/de_GWD/0conf)
+ path=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.path' /opt/de_GWD/0conf)
+ tag="nodeSMbahamut"
+ routingDomain='["geosite:bahamut"]'
+ /opt/de_GWD/ui-V2routingDomain $tag $routingDomain
+ /opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+ fi
+fi
+
+if [[ -n $7 ]] && [[ $7 != "0" ]]; then
+nodeSMnumApple=$[$7-1]
+address=$(jq -r --argjson nodecheck $nodeSMnumApple '.v2node | to_entries[] | select(.key == $nodecheck) | .value.domain' /opt/de_GWD/0conf)
+tls=$(jq -r --argjson nodecheck $nodeSMnumApple '.v2node | to_entries[] | select(.key == $nodecheck) | .value.tls' /opt/de_GWD/0conf)
+uuid=$(jq -r --argjson nodecheck $nodeSMnumApple '.v2node | to_entries[] | select(.key == $nodecheck) | .value.uuid' /opt/de_GWD/0conf)
+path=$(jq -r --argjson nodecheck $nodeSMnumApple '.v2node | to_entries[] | select(.key == $nodecheck) | .value.path' /opt/de_GWD/0conf)
+jq --arg address $address '.v2nodeDIV.nodeSM.apple=$address' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+tag="nodeSMapple"
+routingDomain='["geosite:apple","geosite:apple-ads","geosite:apple-dev","geosite:apple-update","geosite:icloud","geosite:apple@cn","geosite:apple-cn"]'
+/opt/de_GWD/ui-V2routingDomain $tag $routingDomain
+/opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+elif [[ $7 = "0" ]]; then
+ jq 'del(.v2nodeDIV.nodeSM.apple)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+ /opt/de_GWD/ui-V2routingDomain 'direct' '["geosite:apple","geosite:apple-ads","geosite:apple-dev","geosite:apple-update","geosite:icloud","geosite:apple@cn","geosite:apple-cn"]'
+else
+address=$(jq -r '.v2nodeDIV.nodeSM.apple' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+ if [[ -n $address ]]; then
+ sed -i '/apple.china.conf/d' /opt/de_GWD/smartdns/smartdns.conf && systemctl restart smartdns
+ tls=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.tls' /opt/de_GWD/0conf)
+ uuid=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.uuid' /opt/de_GWD/0conf)
+ path=$(jq -r --arg nodecheck $address '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .value.path' /opt/de_GWD/0conf)
+ tag="nodeSMapple"
+ routingDomain='["geosite:apple","geosite:apple-ads","geosite:apple-dev","geosite:apple-update","geosite:icloud","geosite:apple@cn","geosite:apple-cn"]'
+ /opt/de_GWD/ui-V2routingDomain $tag $routingDomain
+ /opt/de_GWD/ui-V2outbound $tag $address $tls $uuid $path
+ fi
+fi
+
+if [[ -n $8 ]] && [[ $8 != "0" ]]; then
+jq '.v2nodeDIV.nodeSM.steam="proxy"' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+elif [[ $8 = "0" ]]; then
+ jq 'del(.v2nodeDIV.nodeSM.steam)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+ /opt/de_GWD/ui-V2routingDomain 'direct' '["geosite:category-games@cn"]'
+else
+ if [[ -z $(jq -r '.v2nodeDIV.nodeSM.steam' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$') ]]; then
+ /opt/de_GWD/ui-V2routingDomain 'direct' '["geosite:category-games@cn"]'
+ fi
+fi
+
+/opt/de_GWD/ui-submitListBWsm
+
+if [[ $2 = "0" ]] && [[ $3 = "0" ]] && [[ $4 = "0" ]] && [[ $5 = "0" ]] && [[ $6 = "0" ]] && [[ $7 = "0" ]] && [[ $8 = "0" ]]; then
+ jq '.v2nodeDIV.nodeSM.status="off"' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+else
+ jq '.v2nodeDIV.nodeSM.status="on"' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+fi
+
+
+if [[ $1 = "r" ]]; then
+ systemctl restart mosdns
+ systemctl restart vtrui
+fi
+
+chmod 666 /opt/de_GWD/0conf
diff --git a/resource/client/ui-script/ui-NodeSMcheck b/resource/client/ui-script/ui-NodeSMcheck
new file mode 100755
index 000000000..d10c8b867
--- /dev/null
+++ b/resource/client/ui-script/ui-NodeSMcheck
@@ -0,0 +1,165 @@
+#!/bin/bash
+domain=$(jq -r '.outbounds[] | select(.tag == "nodeSMyoutube") | .settings.vnext[0].address' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+port=$(jq -r '.outbounds[] | select(.tag == "nodeSMyoutube") | .settings.vnext[0].port' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+
+if [[ $port = "443" ]]; then
+nodecheck=$domain
+else
+nodecheck="$domain:$port"
+fi
+
+checkNum=$(jq -r --arg nodecheck $nodecheck '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .key' /opt/de_GWD/0conf)
+checkName=$(jq -r --arg nodecheck $nodecheck '.v2node[] | select(.domain == $nodecheck) | .name' /opt/de_GWD/0conf)
+
+if [[ -z $checkNum ]]; then
+echo "0"
+else
+echo $((checkNum+=1))
+fi
+
+if [[ -z $checkName ]]; then
+echo "-none-"
+else
+echo $checkName
+fi
+
+
+
+
+domain=$(jq -r '.outbounds[] | select(.tag == "nodeSMnetflix") | .settings.vnext[0].address' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+port=$(jq -r '.outbounds[] | select(.tag == "nodeSMnetflix") | .settings.vnext[0].port' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+
+if [[ $port = "443" ]]; then
+nodecheck=$domain
+else
+nodecheck="$domain:$port"
+fi
+
+checkNum=$(jq -r --arg nodecheck $nodecheck '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .key' /opt/de_GWD/0conf)
+checkName=$(jq -r --arg nodecheck $nodecheck '.v2node[] | select(.domain == $nodecheck) | .name' /opt/de_GWD/0conf)
+
+if [[ -z $checkNum ]]; then
+echo "0"
+else
+echo $((checkNum+=1))
+fi
+
+if [[ -z $checkName ]]; then
+echo "-none-"
+else
+echo $checkName
+fi
+
+
+
+domain=$(jq -r '.outbounds[] | select(.tag == "nodeSMhdh") | .settings.vnext[0].address' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+port=$(jq -r '.outbounds[] | select(.tag == "nodeSMhdh") | .settings.vnext[0].port' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+
+if [[ $port = "443" ]]; then
+nodecheck=$domain
+else
+nodecheck="$domain:$port"
+fi
+
+checkNum=$(jq -r --arg nodecheck $nodecheck '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .key' /opt/de_GWD/0conf)
+checkName=$(jq -r --arg nodecheck $nodecheck '.v2node[] | select(.domain == $nodecheck) | .name' /opt/de_GWD/0conf)
+
+if [[ -z $checkNum ]]; then
+echo "0"
+else
+echo $((checkNum+=1))
+fi
+
+if [[ -z $checkName ]]; then
+echo "-none-"
+else
+echo $checkName
+fi
+
+
+
+domain=$(jq -r '.outbounds[] | select(.tag == "nodeSMtvb") | .settings.vnext[0].address' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+port=$(jq -r '.outbounds[] | select(.tag == "nodeSMtvb") | .settings.vnext[0].port' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+
+if [[ $port = "443" ]]; then
+nodecheck=$domain
+else
+nodecheck="$domain:$port"
+fi
+
+checkNum=$(jq -r --arg nodecheck $nodecheck '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .key' /opt/de_GWD/0conf)
+checkName=$(jq -r --arg nodecheck $nodecheck '.v2node[] | select(.domain == $nodecheck) | .name' /opt/de_GWD/0conf)
+
+if [[ -z $checkNum ]]; then
+echo "0"
+else
+echo $((checkNum+=1))
+fi
+
+if [[ -z $checkName ]]; then
+echo "-none-"
+else
+echo $checkName
+fi
+
+
+
+domain=$(jq -r '.outbounds[] | select(.tag == "nodeSMbahamut") | .settings.vnext[0].address' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+port=$(jq -r '.outbounds[] | select(.tag == "nodeSMbahamut") | .settings.vnext[0].port' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+
+if [[ $port = "443" ]]; then
+nodecheck=$domain
+else
+nodecheck="$domain:$port"
+fi
+
+checkNum=$(jq -r --arg nodecheck $nodecheck '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .key' /opt/de_GWD/0conf)
+checkName=$(jq -r --arg nodecheck $nodecheck '.v2node[] | select(.domain == $nodecheck) | .name' /opt/de_GWD/0conf)
+
+if [[ -z $checkNum ]]; then
+echo "0"
+else
+echo $((checkNum+=1))
+fi
+
+if [[ -z $checkName ]]; then
+echo "-none-"
+else
+echo $checkName
+fi
+
+
+
+domain=$(jq -r '.outbounds[] | select(.tag == "nodeSMapple") | .settings.vnext[0].address' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+port=$(jq -r '.outbounds[] | select(.tag == "nodeSMapple") | .settings.vnext[0].port' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+
+if [[ $port = "443" ]]; then
+nodecheck=$domain
+else
+nodecheck="$domain:$port"
+fi
+
+checkNum=$(jq -r --arg nodecheck $nodecheck '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .key' /opt/de_GWD/0conf)
+checkName=$(jq -r --arg nodecheck $nodecheck '.v2node[] | select(.domain == $nodecheck) | .name' /opt/de_GWD/0conf)
+
+if [[ -z $checkNum ]]; then
+echo "0"
+else
+echo $((checkNum+=1))
+fi
+
+if [[ -z $checkName ]]; then
+echo "-none-"
+else
+echo $checkName
+fi
+
+
+
+if [[ -z $(jq -r '.v2nodeDIV.nodeSM.steam' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$') ]]; then
+echo "0"
+echo "-none-"
+else
+echo "1"
+echo "默认代理"
+fi
diff --git a/resource/client/ui-script/ui-NodeSave b/resource/client/ui-script/ui-NodeSave
new file mode 100755
index 000000000..684dbb53e
--- /dev/null
+++ b/resource/client/ui-script/ui-NodeSave
@@ -0,0 +1,53 @@
+#!/bin/bash
+RED='\E[1;31m'
+GREEN='\E[1;32m'
+YELLOW='\E[1;33m'
+BLUE='\E[1;34m'
+PURPLE='\E[1;35m'
+CYAN='\E[1;36m'
+WHITE='\E[1;37m'
+cRES='\E[0m'
+
+
+
+echo -e "${WHITE}[...]\c" && echo -e "\t${WHITE}Collect V2 node${cRES}\r\c"
+
+cat << EOF >/opt/de_GWD/mosdns/matchers_nodes.yaml
+plugins:
+ - tag: 'domains_nodes'
+ type: query_matcher
+ args:
+ domain:
+EOF
+
+jq -r '.v2node[].domain' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$' | cut -d: -f1 | xargs -n 1 | sort | uniq | sed '/^\s*$/d' | while read line; do
+ yq eval -i ".plugins.[0].args.domain += [\"full:$line\"]" /opt/de_GWD/mosdns/matchers_nodes.yaml
+done
+
+
+
+>/opt/de_GWD/nftables/IP_V2NODE
+jq -r '.v2node[].domain' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$' | cut -d: -f1 | sort | uniq | xargs -n 1 | sed '/^\s*$/d' | while read line; do
+ dig @127.0.0.1 $line -4p 5332 +short | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' | grep -v "127.0.0.1" | xargs -n 1 | sed '/^\s*$/d' >>/opt/de_GWD/nftables/IP_V2NODE
+done
+
+sed -i '/^\s*$/d' /opt/de_GWD/nftables/IP_V2NODE
+sed -i 's/$/,/g' /opt/de_GWD/nftables/IP_V2NODE
+nft flush set ip de_GWD V2NODE
+cat << EOF >/opt/de_GWD/nftables/SET_V2NODE.nft
+#!/usr/sbin/nft -f
+table ip de_GWD {
+ set V2NODE {
+ type ipv4_addr
+ flags interval
+ auto-merge
+ elements = { $(cat /opt/de_GWD/nftables/IP_V2NODE) }
+ }
+}
+EOF
+chmod +x /opt/de_GWD/nftables/SET_V2NODE.nft
+/opt/de_GWD/nftables/SET_V2NODE.nft
+
+[[ $1 = "r" ]] && systemctl restart mosdns
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Collect V2 node${cRES}"
diff --git a/resource/client/ui-script/ui-RproxyCsave b/resource/client/ui-script/ui-RproxyCsave
new file mode 100755
index 000000000..461422533
--- /dev/null
+++ b/resource/client/ui-script/ui-RproxyCsave
@@ -0,0 +1,147 @@
+#!/bin/bash
+rm -rf /opt/de_GWD/RproxyC
+mkdir -p /opt/de_GWD/RproxyC
+cp -f /opt/de_GWD/vtrui/vtrui /opt/de_GWD/RproxyC/RproxyC
+chmod +x /opt/de_GWD/RproxyC/RproxyC
+
+RproxyCoutStatus=$(jq -r '.FORWARD.Rproxy.client.outStatus' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+RproxyCmappingStatus=$(jq -r '.FORWARD.Rproxy.client.mappingStatus' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+RproxyStunnelAddress=$(jq -r '.FORWARD.Rproxy.client.tunnel.address' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+RproxyStunnelUUID=$(jq -r '.FORWARD.Rproxy.client.tunnel.uuid' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+RproxyCmappingList=$(jq -r '.FORWARD.Rproxy.client.mapping' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+domain=$(echo -e $RproxyStunnelAddress | cut -d: -f1)
+port=$(echo -e $RproxyStunnelAddress | cut -d: -f2 | grep '^[[:digit:]]*$')
+[[ -z $port ]] && port="443"
+
+cat << EOF >/opt/de_GWD/RproxyC/config.json
+{
+ "log": {
+ "access":"none",
+ "error":"none",
+ "loglevel":"none"
+ },
+ "dns":{
+ "queryStrategy":"UseIP",
+ "disableCache":true,
+ "servers":["localhost"]
+ },
+ "routing":{
+ "rules":[
+ {"type":"field","inboundTag":["bridge"],"domain":["full:reverse.localhost"],"outboundTag":"reverseTunnel"}
+ ]
+ },
+ "reverse": {
+ "bridges": [{
+ "tag": "bridge",
+ "domain": "reverse.localhost"
+ }]
+ },
+ "outbounds": [
+ {
+ "tag": "reverseTunnel",
+ "protocol": "vmess",
+ "settings": {
+ "vnext": [
+ {
+ "address": "$domain",
+ "port": $port,
+ "users": [
+ {
+ "id": "$RproxyStunnelUUID",
+ "alterId": 0,
+ "security": "auto"
+ }
+ ]
+ }
+ ]
+ },
+ "streamSettings": {
+ "network": "tcp",
+ "sockopt": {
+ "mark": 255,
+ "tcpFastOpen": true
+ }
+ }
+ }
+ ]
+}
+EOF
+
+
+if [[ $RproxyCmappingStatus = "on" ]]; then
+
+len=$(echo $RproxyCmappingList | jq length)
+
+for (( i=0; i<$len; i++ )); do
+extPort=$(echo $RproxyCmappingList | jq -r --argjson i "$i" '.[$i].extPort')
+extProtocol=$(echo $RproxyCmappingList | jq -r --argjson i "$i" '.[$i].extProtocol')
+intIP=$(echo $RproxyCmappingList | jq -r --argjson i "$i" '.[$i].intIP')
+intPort=$(echo $RproxyCmappingList | jq -r --argjson i "$i" '.[$i].intPort')
+
+RontingMapping=`cat << EOF
+ {"type":"field","inboundTag":["bridge"],"port":"$extPort","network":"$extProtocol","outboundTag":"mapping$i"}
+EOF
+`
+
+OBmapping=`cat << EOF
+ {
+ "tag": "mapping$i",
+ "protocol": "freedom",
+ "settings": {
+ "redirect": "$intIP:$intPort"
+ }
+ }
+EOF
+`
+jq --argjson RontingMapping "$RontingMapping" '.routing.rules+=[$RontingMapping]' /opt/de_GWD/RproxyC/config.json |\
+jq --argjson OBmapping "$OBmapping" '.outbounds+=[$OBmapping]' | sponge /opt/de_GWD/RproxyC/config.json
+done
+fi
+
+
+if [[ $RproxyCoutStatus = "on" ]]; then
+RontingOut=`cat << EOF
+ {"type":"field","inboundTag":["bridge"],"outboundTag":"directOut"}
+EOF
+`
+
+OBout=`cat << EOF
+ {
+ "tag": "directOut",
+ "protocol": "freedom"
+ }
+EOF
+`
+
+jq --argjson RontingOut "$RontingOut" '.routing.rules+=[$RontingOut]' /opt/de_GWD/RproxyC/config.json |\
+jq --argjson OBout "$OBout" '.outbounds+=[$OBout]' | sponge /opt/de_GWD/RproxyC/config.json
+fi
+
+chmod 666 /opt/de_GWD/RproxyC/config.json
+chmod 644 /var/www/ssl/*.key
+
+rm -rf /lib/systemd/system/RproxyC.service
+cat << "EOF" >/etc/systemd/system/RproxyC.service
+[Unit]
+Description=Rproxy client
+After=network.target nss-lookup.target
+
+[Service]
+User=root
+Type=simple
+ExecStart=/opt/de_GWD/RproxyC/RproxyC run -config /opt/de_GWD/RproxyC/config.json
+Restart=always
+RestartSec=2
+TimeoutStopSec=5
+
+AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN CAP_NET_BIND_SERVICE
+NoNewPrivileges=true
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl daemon-reload >/dev/null
+systemctl enable RproxyC >/dev/null
+systemctl restart RproxyC
diff --git a/resource/client/ui-script/ui-RproxyCstop b/resource/client/ui-script/ui-RproxyCstop
new file mode 100755
index 000000000..e012abafe
--- /dev/null
+++ b/resource/client/ui-script/ui-RproxyCstop
@@ -0,0 +1,6 @@
+#!/bin/bash
+systemctl disable --now RproxyC >/dev/null
+rm -rf /lib/systemd/system/RproxyC.service
+rm -rf /etc/systemd/system/RproxyC.service
+rm -rf /opt/de_GWD/RproxyC
+systemctl daemon-reload >/dev/null
diff --git a/resource/client/ui-script/ui-RproxySsave b/resource/client/ui-script/ui-RproxySsave
new file mode 100755
index 000000000..161996508
--- /dev/null
+++ b/resource/client/ui-script/ui-RproxySsave
@@ -0,0 +1,128 @@
+#!/bin/bash
+rm -rf /opt/de_GWD/RproxyS
+mkdir -p /opt/de_GWD/RproxyS
+cp -f /opt/de_GWD/vtrui/vtrui /opt/de_GWD/RproxyS/RproxyS
+chmod +x /opt/de_GWD/RproxyS/RproxyS
+
+RproxySinStatus=$(jq -r '.FORWARD.Rproxy.server.inStatus' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+RproxySmappingStatus=$(jq -r '.FORWARD.Rproxy.server.mappingStatus' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+RproxyStunnelPort=$(jq -r '.FORWARD.Rproxy.server.tunnel.port' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+RproxyStunnelUUID=$(jq -r '.FORWARD.Rproxy.server.tunnel.uuid' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+RproxySinUUID=$(jq -r '.FORWARD.Rproxy.server.inUUID[].RproxyS0uuid' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+RproxySmappingList=$(jq -r '.FORWARD.Rproxy.server.mapping' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+cat << EOF >/opt/de_GWD/RproxyS/config.json
+{
+ "log": {
+ "access":"none",
+ "error":"none",
+ "loglevel":"none"
+ },
+ "dns":{
+ "queryStrategy":"UseIP",
+ "disableCache":true,
+ "servers":["localhost"]
+ },
+ "routing":{
+ "rules":[
+ {"type":"field","inboundTag":["reverseTunnel"],"domain":["full:reverse.localhost"],"outboundTag":"portal"},
+ {"type":"field","inboundTag":["reverseTunnel"],"outboundTag":"portal"}
+ ]
+ },
+ "reverse": {
+ "portals": [{
+ "tag": "portal",
+ "domain": "reverse.localhost"
+ }]
+ },
+ "inbounds": [
+ {
+ "tag": "reverseTunnel",
+ "port": $RproxyStunnelPort,
+ "protocol": "vmess",
+ "settings":{
+ "clients":[
+ {
+ "id":"$RproxyStunnelUUID",
+ "alterId": 0
+ }
+ ]
+ },
+ "streamSettings": {
+ "network": "tcp"
+ }
+ }
+ ]
+}
+EOF
+
+
+if [[ $RproxySinStatus = "on" ]]; then
+for uuid in $RproxySinUUID; do
+uuidStr='{"id":"'$uuid'", "alterId":0}'
+jq --argjson uuidStr "$uuidStr" '.inbounds[0].settings.clients+=[$uuidStr]' /opt/de_GWD/RproxyS/config.json | sponge /opt/de_GWD/RproxyS/config.json
+done
+
+uniqueClient=$(jq -r '.inbounds[0].settings.clients | unique' /opt/de_GWD/RproxyS/config.json 2>/dev/null | grep -v '^null$')
+jq --argjson uniqueClient "$uniqueClient" '.inbounds[0].settings.clients=$uniqueClient' /opt/de_GWD/RproxyS/config.json | sponge /opt/de_GWD/RproxyS/config.json
+fi
+
+
+if [[ $RproxySmappingStatus = "on" ]]; then
+
+len=$(echo $RproxySmappingList | jq length)
+
+for (( i=0; i<$len; i++ )); do
+port=$(echo $RproxySmappingList | jq -r --argjson i "$i" '.[$i].port')
+protocol=$(echo $RproxySmappingList | jq -r --argjson i "$i" '.[$i].protocol')
+
+RontingMapping=`cat << EOF
+ {"type":"field","inboundTag":["mapping$i"],"outboundTag":"portal"}
+EOF
+`
+
+IBmapping=`cat << EOF
+ {
+ "tag": "mapping$i",
+ "port": $port,
+ "protocol": "dokodemo-door",
+ "settings": {
+ "address": "127.0.0.1",
+ "port": $port,
+ "network": "$protocol"
+ }
+ }
+EOF
+`
+jq --argjson RontingMapping "$RontingMapping" '.routing.rules+=[$RontingMapping]' /opt/de_GWD/RproxyS/config.json |\
+jq --argjson IBmapping "$IBmapping" '.inbounds+=[$IBmapping]' | sponge /opt/de_GWD/RproxyS/config.json
+done
+fi
+
+chmod 666 /opt/de_GWD/RproxyS/config.json
+chmod 644 /var/www/ssl/*.key
+
+rm -rf /lib/systemd/system/RproxyS.service
+cat << "EOF" >/etc/systemd/system/RproxyS.service
+[Unit]
+Description=Rproxy Service
+After=network.target nss-lookup.target
+
+[Service]
+User=root
+Type=simple
+ExecStart=/opt/de_GWD/RproxyS/RproxyS run -config /opt/de_GWD/RproxyS/config.json
+Restart=always
+RestartSec=2
+TimeoutStopSec=5
+
+AmbientCapabilities=CAP_NET_RAW CAP_NET_ADMIN CAP_NET_BIND_SERVICE
+NoNewPrivileges=true
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl daemon-reload >/dev/null
+systemctl enable RproxyS >/dev/null 2>&1
+systemctl restart RproxyS
diff --git a/resource/client/ui-script/ui-RproxySstop b/resource/client/ui-script/ui-RproxySstop
new file mode 100755
index 000000000..e6645de29
--- /dev/null
+++ b/resource/client/ui-script/ui-RproxySstop
@@ -0,0 +1,6 @@
+#!/bin/bash
+systemctl disable --now RproxyS >/dev/null
+rm -rf /lib/systemd/system/RproxyS.service
+rm -rf /etc/systemd/system/RproxyS.service
+rm -rf /opt/de_GWD/RproxyS
+systemctl daemon-reload >/dev/null
diff --git a/resource/client/ui-script/ui-V2outbound b/resource/client/ui-script/ui-V2outbound
new file mode 100755
index 000000000..af207843d
--- /dev/null
+++ b/resource/client/ui-script/ui-V2outbound
@@ -0,0 +1,108 @@
+#!/bin/bash
+tag=$1
+address=$2
+tls=$3
+uuid=$4
+path=$5
+
+if [[ -z $tag ]] || [[ -z $address ]] || [[ -z $uuid ]]; then
+exit
+fi
+
+domain=$(echo $address | cut -d: -f1)
+port=$(echo $address | cut -d: -f2 | grep '^[[:digit:]]*$')
+[[ -z $port ]] && port="443"
+[[ -z $tls ]] && tls=$domain
+
+
+if [[ $tag = "default" ]]; then
+muxEnable="true"
+muxCconcurrency="8"
+else
+muxEnable="false"
+muxCconcurrency="-1"
+fi
+
+
+if [[ -z $path ]]; then
+OBadd=`cat << EOF
+ {
+ "tag": "$tag",
+ "protocol": "vmess",
+ "settings": {
+ "vnext": [
+ {
+ "address": "$domain",
+ "port": $port,
+ "users": [
+ {
+ "id": "$uuid",
+ "alterId": 0,
+ "security": "auto"
+ }
+ ]
+ }
+ ]
+ },
+ "streamSettings": {
+ "network": "tcp",
+ "sockopt": {
+ "mark": 255,
+ "tcpFastOpen": true
+ }
+ },
+ "mux": {
+ "enabled": $muxEnable,
+ "concurrency": $muxCconcurrency
+ }
+ }
+EOF
+`
+else
+OBadd=`cat << EOF
+ {
+ "tag": "$tag",
+ "protocol": "vmess",
+ "settings": {
+ "vnext": [
+ {
+ "address": "$domain",
+ "port": $port,
+ "users": [
+ {
+ "id": "$uuid",
+ "alterId": 0,
+ "security": "auto"
+ }
+ ]
+ }
+ ]
+ },
+ "streamSettings": {
+ "network": "ws",
+ "wsSettings": {
+ "path": "$path",
+ "headers": {
+ "Host": "$tls"
+ }
+ },
+ "security": "tls",
+ "tlsSettings": {
+ "serverName": "$tls",
+ "allowInsecure": false
+ },
+ "sockopt": {
+ "mark": 255,
+ "tcpFastOpen": true
+ }
+ },
+ "mux": {
+ "enabled": $muxEnable,
+ "concurrency": $muxCconcurrency
+ }
+ }
+EOF
+`
+fi
+
+jq --argjson OBadd "$OBadd" '.outbounds+=[$OBadd]' /opt/de_GWD/vtrui/config.json | sponge /opt/de_GWD/vtrui/config.json
diff --git a/resource/client/ui-script/ui-V2routingDomain b/resource/client/ui-script/ui-V2routingDomain
new file mode 100755
index 000000000..929068a19
--- /dev/null
+++ b/resource/client/ui-script/ui-V2routingDomain
@@ -0,0 +1,17 @@
+#!/bin/bash
+if [[ -n $1 ]] && [[ -n $2 ]]; then
+tag=$1
+domain=$2
+
+RoutingADD=`cat << EOF
+{
+ "type": "field",
+ "domain": $domain,
+ "network": "tcp,udp",
+ "outboundTag": "$tag"
+}
+EOF
+`
+
+jq --argjson RoutingADD "$RoutingADD" '.routing.rules+=[$RoutingADD]' /opt/de_GWD/vtrui/config.json | sponge /opt/de_GWD/vtrui/config.json
+fi
diff --git a/resource/client/ui-script/ui-V2routingIP b/resource/client/ui-script/ui-V2routingIP
new file mode 100755
index 000000000..60e43f0cc
--- /dev/null
+++ b/resource/client/ui-script/ui-V2routingIP
@@ -0,0 +1,17 @@
+#!/bin/bash
+if [[ -n $1 ]] && [[ -n $2 ]]; then
+tag=$1
+IP=$2
+
+RoutingADD=`cat << EOF
+{
+ "type": "field",
+ "ip": $IP,
+ "network": "tcp,udp",
+ "outboundTag": "$tag"
+}
+EOF
+`
+
+jq --argjson RoutingADD "$RoutingADD" '.routing.rules+=[$RoutingADD]' /opt/de_GWD/vtrui/config.json | sponge /opt/de_GWD/vtrui/config.json
+fi
diff --git a/resource/client/ui-script/ui-V2routingSip b/resource/client/ui-script/ui-V2routingSip
new file mode 100755
index 000000000..ca891f3a3
--- /dev/null
+++ b/resource/client/ui-script/ui-V2routingSip
@@ -0,0 +1,17 @@
+#!/bin/bash
+if [[ -n $1 ]] && [[ -n $2 ]]; then
+tag=$1
+IP=$2
+
+RoutingADD=`cat << EOF
+{
+ "type": "field",
+ "source": $IP,
+ "network": "tcp,udp",
+ "outboundTag": "$tag"
+}
+EOF
+`
+
+jq --argjson RoutingADD "$RoutingADD" '.routing.rules+=[$RoutingADD]' /opt/de_GWD/vtrui/config.json | sponge /opt/de_GWD/vtrui/config.json
+fi
diff --git a/resource/client/ui-script/ui-WGgenCkey b/resource/client/ui-script/ui-WGgenCkey
new file mode 100755
index 000000000..e18454c4f
--- /dev/null
+++ b/resource/client/ui-script/ui-WGgenCkey
@@ -0,0 +1,19 @@
+#!/bin/bash
+i=$1
+
+mkdir -p /etc/wireguard
+cd /etc/wireguard
+
+wg genkey | tee cprivatekey | wg pubkey > cpublickey
+
+cprivatekey=$(cat /etc/wireguard/cprivatekey)
+cpublickey=$(cat /etc/wireguard/cpublickey)
+
+jq --argjson i "$i" --arg cprivatekey "$cprivatekey" '.wireguard.clients[$i].cprivatekey=$cprivatekey' /opt/de_GWD/0conf |\
+jq --argjson i "$i" --arg cpublickey "$cpublickey" '.wireguard.clients[$i].cpublickey=$cpublickey' | sponge /opt/de_GWD/0conf
+chmod 666 /opt/de_GWD/0conf
+
+rm -rf /etc/wireguard/c*key
+
+echo $cprivatekey
+echo $cpublickey
\ No newline at end of file
diff --git a/resource/client/ui-script/ui-WGgenSkey b/resource/client/ui-script/ui-WGgenSkey
new file mode 100755
index 000000000..7b7d213c9
--- /dev/null
+++ b/resource/client/ui-script/ui-WGgenSkey
@@ -0,0 +1,14 @@
+#!/bin/bash
+mkdir -p /etc/wireguard
+cd /etc/wireguard
+
+wg genkey | tee sprivatekey | wg pubkey > spublickey
+
+sprivatekey=$(cat /etc/wireguard/sprivatekey)
+spublickey=$(cat /etc/wireguard/spublickey)
+
+jq --arg sprivatekey "$sprivatekey" '.wireguard.server.sprivatekey=$sprivatekey' /opt/de_GWD/0conf |\
+jq --arg spublickey "$spublickey" '.wireguard.server.spublickey=$spublickey' | sponge /opt/de_GWD/0conf
+chmod 666 /opt/de_GWD/0conf
+
+rm -rf /etc/wireguard/s*key
diff --git a/resource/client/ui-script/ui-WGoff b/resource/client/ui-script/ui-WGoff
new file mode 100755
index 000000000..45ae67871
--- /dev/null
+++ b/resource/client/ui-script/ui-WGoff
@@ -0,0 +1,6 @@
+#!/bin/bash
+systemctl stop wg-quick@wg0 >/dev/null 2>&1
+systemctl disable wg-quick@wg0 >/dev/null 2>&1
+
+rm -rf /etc/dnsmasq.d/00-wg.conf
+pihole restartdns
diff --git a/resource/client/ui-script/ui-WGon b/resource/client/ui-script/ui-WGon
new file mode 100755
index 000000000..8092d38df
--- /dev/null
+++ b/resource/client/ui-script/ui-WGon
@@ -0,0 +1,71 @@
+#!/bin/bash
+WGaddress=$(jq -r '.wireguard.server.WGaddress' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+WGport=$(jq -r '.wireguard.server.WGport' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+sprivatekey=$(jq -r '.wireguard.server.sprivatekey' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+spublickey=$(jq -r '.wireguard.server.spublickey' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+clientsNUM=$(jq -r '.wireguard.clients | length' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+clientsNUMinvalid=$(jq -r '.wireguard.clients[].cprivatekey' /opt/de_GWD/0conf | grep '^undefined$' | wc -l)
+clientsNUMgood=$[$clientsNUM-$clientsNUMinvalid]
+
+rm -rf /etc/wireguard/client*.conf
+
+cat << EOF >/etc/wireguard/wg0.conf
+[Interface]
+PrivateKey = $sprivatekey
+Address = 172.16.66.1/32
+ListenPort = $WGport
+DNS = 127.0.0.1
+MTU = 1420
+EOF
+
+for ((i=0; i<$clientsNUMgood; i++)); do
+cat << EOF >>/etc/wireguard/wg0.conf
+
+[Peer]
+PublicKey = $(jq -r --argjson i "$i" '.wireguard.clients[$i].cpublickey' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+AllowedIPs = 172.16.66.$[$i+11]/32
+EOF
+
+cat << EOF >/etc/wireguard/client$[$i+1].conf
+[Interface]
+PrivateKey = $(jq -r --argjson i "$i" '.wireguard.clients[$i].cprivatekey' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+Address = 172.16.66.$[$i+11]/32
+DNS = 172.16.66.1
+MTU = 1420
+
+[Peer]
+PublicKey = $spublickey
+Endpoint = $WGaddress:$WGport
+AllowedIPs = 0.0.0.0/0
+EOF
+done
+chmod 600 /etc/wireguard/wg0.conf
+chmod 600 /etc/wireguard/client*.conf
+
+rm -rf /lib/systemd/system/wg-quick@.service
+cat << "EOF" >/etc/systemd/system/wg-quick@.service
+[Unit]
+Description=WireGuard via wg-quick(8) for %I
+After=network-online.target nss-lookup.target
+Wants=network-online.target nss-lookup.target
+PartOf=wg-quick.target
+
+[Service]
+User=root
+Type=oneshot
+ExecStart=/usr/bin/wg-quick up %i
+ExecStop=/usr/bin/wg-quick down %i
+ExecReload=/bin/bash -c 'exec /usr/bin/wg syncconf %i <(exec /usr/bin/wg-quick strip %i)'
+Environment=WG_ENDPOINT_RESOLUTION_RETRIES=infinity
+RemainAfterExit=yes
+
+[Install]
+WantedBy=multi-user.target
+EOF
+systemctl daemon-reload >/dev/null
+systemctl enable wg-quick@wg0 >/dev/null 2>&1
+systemctl restart wg-quick@wg0
+
+echo "interface=wg0" >/etc/dnsmasq.d/00-wg.conf
+pihole restartdns
diff --git a/resource/client/ui-script/ui-autoUpdateHour b/resource/client/ui-script/ui-autoUpdateHour
new file mode 100755
index 000000000..f6692d556
--- /dev/null
+++ b/resource/client/ui-script/ui-autoUpdateHour
@@ -0,0 +1,46 @@
+#!/bin/bash
+if [[ $1 = "off" ]]; then
+crontab -l 2>/dev/null > /tmp/now.cron
+sed -i '/autoUpdate/d' /tmp/now.cron
+crontab /tmp/now.cron
+rm -rf /tmp/now.cron
+rm -rf /opt/de_GWD/autoUpdate
+else
+cat << "EOF" >/opt/de_GWD/autoUpdate
+#!/bin/bash
+localVer=$(awk 'NR==1' /var/www/html/act/version.php)
+remoteVer=$(curl -sSLo- https://raw.githubusercontent.com/jacyl4/de_GWD/main/version.php | head -n 1)
+
+echo $localVer >/tmp/de_GWD_Ver
+echo $remoteVer >>/tmp/de_GWD_Ver
+
+VerCP=$(cat /tmp/de_GWD_Ver | sort -rV | uniq | awk NR==2)
+
+if [[ $VerCP = $localVer ]]; then
+systemctl stop php7.4-fpm
+
+rm -rf /tmp/autoUpdate
+wget -cqO /tmp/autoUpdate https://raw.githubusercontent.com/jacyl4/de_GWD/main/client
+
+if [[ $(du -sk /tmp/autoUpdate 2>/dev/null | awk '{print$1}') -gt 70 ]]; then
+sed -i '$d' /tmp/autoUpdate
+echo "updateGWD auto" >>/tmp/autoUpdate
+chmod +x /tmp/autoUpdate
+/tmp/autoUpdate
+rm -rf /tmp/autoUpdate
+fi
+
+systemctl restart php7.4-fpm
+fi
+
+rm -rf /tmp/de_GWD_Ver
+rm -rf /tmp/autoUpdate
+EOF
+chmod +x /opt/de_GWD/autoUpdate
+
+crontab -l 2>/dev/null > /tmp/now.cron
+sed -i '/autoUpdate/d' /tmp/now.cron
+echo "0 $1 * * * /opt/de_GWD/autoUpdate" >> /tmp/now.cron
+crontab /tmp/now.cron
+rm -rf /tmp/now.cron
+fi
diff --git a/resource/client/ui-script/ui-block53off b/resource/client/ui-script/ui-block53off
new file mode 100755
index 000000000..a09f7192a
--- /dev/null
+++ b/resource/client/ui-script/ui-block53off
@@ -0,0 +1,14 @@
+#!/bin/bash
+sed -i "/net.ipv4.ip_forward =/c\net.ipv4.ip_forward = 1" /etc/sysctl.conf
+sed -i "/net.ipv4.conf.all.accept_redirects =/c\net.ipv4.conf.all.accept_redirects = 1" /etc/sysctl.conf
+sed -i "/net.ipv4.conf.default.accept_redirects =/c\net.ipv4.conf.default.accept_redirects = 1" /etc/sysctl.conf
+sed -i "/net.ipv4.conf.all.secure_redirects =/c\net.ipv4.conf.all.secure_redirects = 1" /etc/sysctl.conf
+sed -i "/net.ipv4.conf.default.secure_redirects =/c\net.ipv4.conf.default.secure_redirects = 1" /etc/sysctl.conf
+sed -i "/net.ipv4.conf.all.accept_source_route =/c\net.ipv4.conf.all.accept_source_route = 1" /etc/sysctl.conf
+sed -i "/net.ipv4.conf.default.accept_source_route =/c\net.ipv4.conf.default.accept_source_route = 1" /etc/sysctl.conf
+sysctl -p >/dev/null && sysctl -w net.ipv4.route.flush=1 >/dev/null 2>&1
+
+sed -i '/meta l4proto { tcp, udp } th dport 53 drop/d' /opt/de_GWD/nftables/default.nft
+systemctl restart nftables
+
+[[ $1 = "r" ]] && /opt/de_GWD/ui-DHCPoff
diff --git a/resource/client/ui-script/ui-block53on b/resource/client/ui-script/ui-block53on
new file mode 100755
index 000000000..d02624aaf
--- /dev/null
+++ b/resource/client/ui-script/ui-block53on
@@ -0,0 +1,15 @@
+#!/bin/bash
+sed -i "/net.ipv4.ip_forward =/c\net.ipv4.ip_forward = 0" /etc/sysctl.conf
+sed -i "/net.ipv4.conf.all.accept_redirects =/c\net.ipv4.conf.all.accept_redirects = 0" /etc/sysctl.conf
+sed -i "/net.ipv4.conf.default.accept_redirects =/c\net.ipv4.conf.default.accept_redirects = 0" /etc/sysctl.conf
+sed -i "/net.ipv4.conf.all.secure_redirects =/c\net.ipv4.conf.all.secure_redirects = 0" /etc/sysctl.conf
+sed -i "/net.ipv4.conf.default.secure_redirects =/c\net.ipv4.conf.default.secure_redirects = 0" /etc/sysctl.conf
+sed -i "/net.ipv4.conf.all.accept_source_route =/c\net.ipv4.conf.all.accept_source_route = 0" /etc/sysctl.conf
+sed -i "/net.ipv4.conf.default.accept_source_route =/c\net.ipv4.conf.default.accept_source_route = 0" /etc/sysctl.conf
+sysctl -p >/dev/null && sysctl -w net.ipv4.route.flush=1 >/dev/null 2>&1
+
+sed -i '/meta l4proto { tcp, udp } th dport 53 drop/d' /opt/de_GWD/nftables/default.nft
+sed -i "/# Drop 53 in$/a\meta l4proto { tcp, udp } th dport 53 drop" /opt/de_GWD/nftables/default.nft
+systemctl restart nftables
+
+[[ $1 = "r" ]] && /opt/de_GWD/ui-DHCPoff
diff --git a/resource/client/ui-script/ui-changeNodeSS b/resource/client/ui-script/ui-changeNodeSS
new file mode 100755
index 000000000..02a3aa339
--- /dev/null
+++ b/resource/client/ui-script/ui-changeNodeSS
@@ -0,0 +1,33 @@
+#!/bin/bash
+ssAddress=$(jq -r '.v2nodeDIV.ss.ssAddress' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+ssPort=$(jq -r '.v2nodeDIV.ss.ssPort' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+ssMethod=$(jq -r '.v2nodeDIV.ss.ssMethod' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+ssSecure=$(jq -r '.v2nodeDIV.ss.ssSecure' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+OBss=`cat << EOF
+{
+ "tag": "ss",
+ "protocol": "shadowsocks",
+ "settings": {
+ "servers": [
+ {
+ "address": "$ssAddress",
+ "port": $ssPort,
+ "method": "$ssMethod",
+ "password": "$ssSecure",
+ "level": 1
+ }
+ ]
+ },
+ "streamSettings": {
+ "sockopt": {
+ "mark": 255
+ }
+ }
+}
+EOF
+`
+
+jq --argjson OBss "$OBss" '.outbounds[0]=$OBss' /opt/de_GWD/vtrui/config.json | sponge /opt/de_GWD/vtrui/config.json
+
+[[ $1 = "r" ]] && systemctl restart vtrui >/dev/null
diff --git a/resource/client/ui-script/ui-changeNodeSS0 b/resource/client/ui-script/ui-changeNodeSS0
new file mode 100755
index 000000000..0d796c26c
--- /dev/null
+++ b/resource/client/ui-script/ui-changeNodeSS0
@@ -0,0 +1,85 @@
+#!/bin/bash
+domain=$(jq -r '.update.v2node.domain' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+tls=$(jq -r '.update.v2node.tls' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+port=$(jq -r '.update.v2node.port' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+uuid=$(jq -r '.update.v2node.uuid' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+path=$(jq -r '.update.v2node.path' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+[[ -z $tls ]] && tls=$domain
+
+if [[ -z $path ]]; then
+OBdefault=`cat << EOF
+ {
+ "tag": "default",
+ "protocol": "vmess",
+ "settings": {
+ "vnext": [
+ {
+ "address": "$domain",
+ "port": $port,
+ "users": [
+ {
+ "id": "$uuid",
+ "alterId": 0,
+ "security": "auto"
+ }
+ ]
+ }
+ ]
+ },
+ "streamSettings": {
+ "network": "tcp",
+ "sockopt": {
+ "mark": 255,
+ "tcpFastOpen": true
+ }
+ }
+ }
+EOF
+`
+else
+OBdefault=`cat << EOF
+{
+ "tag": "default",
+ "protocol": "vmess",
+ "settings": {
+ "vnext": [
+ {
+ "address": "$domain",
+ "port": $port,
+ "users": [
+ {
+ "id": "$uuid",
+ "alterId": 0,
+ "security": "auto"
+ }
+ ]
+ }
+ ]
+ },
+ "streamSettings": {
+ "network": "ws",
+ "wsSettings": {
+ "path": "$path",
+ "headers": {
+ "Host": "$tls"
+ }
+ },
+ "security": "tls",
+ "tlsSettings": {
+ "serverName": "$tls",
+ "allowInsecure": false
+ },
+ "sockopt": {
+ "mark": 255,
+ "tcpFastOpen": true
+ }
+ }
+}
+EOF
+`
+fi
+
+jq --argjson OBdefault "$OBdefault" '.outbounds[0]=$OBdefault' /opt/de_GWD/vtrui/config.json | sponge /opt/de_GWD/vtrui/config.json
+
+systemctl restart vtrui
diff --git a/resource/client/ui-script/ui-checkDDNS3322 b/resource/client/ui-script/ui-checkDDNS3322
new file mode 100755
index 000000000..f755983ee
--- /dev/null
+++ b/resource/client/ui-script/ui-checkDDNS3322
@@ -0,0 +1,6 @@
+#!/bin/bash
+if [[ $(crontab -l 2>/dev/null) =~ "ddns3322updateIP" ]]; then
+ echo "success"
+else
+ echo "outline-secondary"
+fi
diff --git a/resource/client/ui-script/ui-checkDDNScf b/resource/client/ui-script/ui-checkDDNScf
new file mode 100755
index 000000000..e5629361a
--- /dev/null
+++ b/resource/client/ui-script/ui-checkDDNScf
@@ -0,0 +1,6 @@
+#!/bin/bash
+if [[ $(crontab -l 2>/dev/null) =~ "ddnsCFupdateIP" ]]; then
+ echo "success"
+else
+ echo "outline-secondary"
+fi
diff --git a/resource/client/ui-script/ui-checkDhcp b/resource/client/ui-script/ui-checkDhcp
new file mode 100755
index 000000000..e860051cb
--- /dev/null
+++ b/resource/client/ui-script/ui-checkDhcp
@@ -0,0 +1,6 @@
+#!/bin/bash
+if [[ $(ls /etc/dnsmasq.d) =~ "dhcp" ]]; then
+ echo "success"
+else
+ echo "outline-secondary"
+fi
diff --git a/resource/client/ui-script/ui-checkEditionARM b/resource/client/ui-script/ui-checkEditionARM
new file mode 100755
index 000000000..bcfd0f4af
--- /dev/null
+++ b/resource/client/ui-script/ui-checkEditionARM
@@ -0,0 +1,2 @@
+#!/bin/bash
+[[ $(dpkg --print-architecture) = "arm64" ]] && echo "ARM"
diff --git a/resource/client/ui-script/ui-checkFWD1 b/resource/client/ui-script/ui-checkFWD1
new file mode 100755
index 000000000..b2d374bf1
--- /dev/null
+++ b/resource/client/ui-script/ui-checkFWD1
@@ -0,0 +1,16 @@
+#!/bin/bash
+if [[ -f "/opt/de_GWD/vtrui1/config.json" ]]; then
+domain=$(jq -r '.outbounds[0].settings.vnext[0].address' /opt/de_GWD/vtrui1/config.json 2>/dev/null | grep -v '^null$')
+port=$(jq -r '.outbounds[0].settings.vnext[0].port' /opt/de_GWD/vtrui1/config.json 2>/dev/null | grep -v '^null$')
+
+if [[ $port = "443" ]]; then
+nodecheck=$domain
+else
+nodecheck=$domain:$port
+fi
+
+jq -r --arg nodecheck $nodecheck '.v2node[] | select(.domain == $nodecheck) | .name' /opt/de_GWD/0conf
+
+echo $nodecheck | grep -v '^:'
+rm -rf /tmp/vtruiDomains
+fi
diff --git a/resource/client/ui-script/ui-checkNode b/resource/client/ui-script/ui-checkNode
new file mode 100755
index 000000000..a372902ad
--- /dev/null
+++ b/resource/client/ui-script/ui-checkNode
@@ -0,0 +1,11 @@
+#!/bin/bash
+domain=$(jq -r '.outbounds[0].settings.vnext[0].address' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+port=$(jq -r '.outbounds[0].settings.vnext[0].port' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+
+if [[ $port = "443" ]]; then
+nodecheck=$domain
+else
+nodecheck=$domain:$port
+fi
+
+jq -r --arg nodecheck $nodecheck '.v2node | to_entries[] | select(.value.domain == $nodecheck) | .key' /opt/de_GWD/0conf
diff --git a/resource/client/ui-script/ui-checkNodeSS b/resource/client/ui-script/ui-checkNodeSS
new file mode 100755
index 000000000..234516532
--- /dev/null
+++ b/resource/client/ui-script/ui-checkNodeSS
@@ -0,0 +1,8 @@
+#!/bin/bash
+checkSS=$(jq -r '.outbounds[0].tag' /opt/de_GWD/vtrui/config.json 2>/dev/null | grep -v '^null$')
+
+if [[ $checkSS = "ss" ]]; then
+echo "btn-success"
+else
+echo "btn-outline-secondary"
+fi
diff --git a/resource/client/ui-script/ui-checkWG b/resource/client/ui-script/ui-checkWG
new file mode 100755
index 000000000..8c60269ac
--- /dev/null
+++ b/resource/client/ui-script/ui-checkWG
@@ -0,0 +1,2 @@
+#!/bin/bash
+[[ $(ip --oneline link show up | grep -v "lo" | awk '{print $2}' | cut -d':' -f1 | cut -d'@' -f1) =~ "wg0" ]] && echo "success"
diff --git a/resource/client/ui-script/ui-check_ssl b/resource/client/ui-script/ui-check_ssl
new file mode 100755
index 000000000..56361716e
--- /dev/null
+++ b/resource/client/ui-script/ui-check_ssl
@@ -0,0 +1,2 @@
+#!/bin/bash
+openssl x509 -enddate -noout -in /var/www/ssl/de_GWD.cer | sed 's/notAfter=//'
diff --git a/resource/client/ui-script/ui-ddns3322off b/resource/client/ui-script/ui-ddns3322off
new file mode 100755
index 000000000..a62f1579c
--- /dev/null
+++ b/resource/client/ui-script/ui-ddns3322off
@@ -0,0 +1,5 @@
+#!/bin/bash
+crontab -l 2>/dev/null >/tmp/now.cron
+sed -i '/ui-ddns3322/d' /tmp/now.cron
+crontab /tmp/now.cron
+rm -rf /tmp/now.cron
diff --git a/resource/client/ui-script/ui-ddns3322on b/resource/client/ui-script/ui-ddns3322on
new file mode 100755
index 000000000..cf8828283
--- /dev/null
+++ b/resource/client/ui-script/ui-ddns3322on
@@ -0,0 +1,8 @@
+#!/bin/bash
+/opt/de_GWD/ui-ddns3322updateIP
+
+crontab -l 2>/dev/null >/tmp/now.cron
+sed -i '/ui-ddns3322/d' /tmp/now.cron
+echo '*/1 * * * * /opt/de_GWD/ui-ddns3322updateIP >/dev/null 2>&1' >>/tmp/now.cron
+crontab /tmp/now.cron
+rm -rf /tmp/now.cron
diff --git a/resource/client/ui-script/ui-ddns3322updateIP b/resource/client/ui-script/ui-ddns3322updateIP
new file mode 100755
index 000000000..bd59551b0
--- /dev/null
+++ b/resource/client/ui-script/ui-ddns3322updateIP
@@ -0,0 +1,10 @@
+#!/bin/bash
+wanIP=$(/opt/de_GWD/ui-wanIP)
+
+domain=$(jq -r '.ddns.ddns3322.domain' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+user=$(jq -r '.ddns.ddns3322.user' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+pwd=$(jq -r '.ddns.ddns3322.pwd' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+domainip=$(dig $domain +short | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' | grep -v "127.0.0.1" | xargs -n 1 | awk NR==1)
+
+[[ $wanIP != $domainip ]] && curl -u $user:$pwd "http://www.3322.org/dyndns/update?hostname=$domain&myip=$wanIP"
diff --git a/resource/client/ui-script/ui-ddnsCFoff b/resource/client/ui-script/ui-ddnsCFoff
new file mode 100755
index 000000000..b76a5e8f5
--- /dev/null
+++ b/resource/client/ui-script/ui-ddnsCFoff
@@ -0,0 +1,5 @@
+#!/bin/bash
+crontab -l 2>/dev/null >/tmp/now.cron
+sed -i '/ui-ddnsCF/d' /tmp/now.cron
+crontab /tmp/now.cron
+rm -rf /tmp/now.cron
diff --git a/resource/client/ui-script/ui-ddnsCFon b/resource/client/ui-script/ui-ddnsCFon
new file mode 100755
index 000000000..041207a9b
--- /dev/null
+++ b/resource/client/ui-script/ui-ddnsCFon
@@ -0,0 +1,8 @@
+#!/bin/bash
+/opt/de_GWD/ui-ddnsCFupdateIP
+
+crontab -l 2>/dev/null >/tmp/now.cron
+sed -i '/ui-ddnsCF/d' /tmp/now.cron
+echo '*/1 * * * * /opt/de_GWD/ui-ddnsCFupdateIP >/dev/null 2>&1' >>/tmp/now.cron
+crontab /tmp/now.cron
+rm -rf /tmp/now.cron
diff --git a/resource/client/ui-script/ui-ddnsCFupdateIP b/resource/client/ui-script/ui-ddnsCFupdateIP
new file mode 100755
index 000000000..6109f9082
--- /dev/null
+++ b/resource/client/ui-script/ui-ddnsCFupdateIP
@@ -0,0 +1,23 @@
+#!/bin/bash
+CFdomain=$(jq -r '.ddns.ddnsCF.cfDomain' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+CFzoneID=$(jq -r '.ddns.ddnsCF.CfZoneID' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+CFapikey=$(jq -r '.ddns.ddnsCF.cfAPIkey' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+CFemail=$(jq -r '.ddns.ddnsCF.cfEmail' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+wanIP=$(/opt/de_GWD/ui-wanIP)
+
+CFdomainip=$(dig @127.0.0.1 $CFdomain -4p 5332 +short | grep -Po '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
+
+if [[ $wanIP != $CFdomainip ]]; then
+CFtopDomain=$(echo $CFdomain | rev | awk -F. '{print $1"."$2}' | rev)
+
+CFzoneID=$(curl -sX GET "https://api.cloudflare.com/client/v4/zones?name=$CFtopDomain" -H "X-Auth-Email: $CFemail" -H "X-Auth-Key: $CFapikey" -H "Content-Type: application/json" | jq -r '.result[].id')
+
+CFrecordID=$(curl -sX GET "https://api.cloudflare.com/client/v4/zones/$CFzoneID/dns_records" -H "X-Auth-Email: $CFemail" -H "X-Auth-Key: $CFapikey" -H "Content-Type: application/json" | jq --arg CFdomain "$CFdomain" -r '.result[] | select(.name == $CFdomain).id')
+
+curl -sX PUT "https://api.cloudflare.com/client/v4/zones/$CFzoneID/dns_records/$CFrecordID" \
+ -H "X-Auth-Email: $CFemail" \
+ -H "X-Auth-Key: $CFapikey" \
+ -H "Content-Type: application/json" \
+ --data '{"type":"A","name":"'$CFdomain'","content":"'$wanIP'","ttl":1,"proxied":false}'
+fi
diff --git a/resource/client/ui-script/ui-hostsCustomize b/resource/client/ui-script/ui-hostsCustomize
new file mode 100755
index 000000000..ae338e2e2
--- /dev/null
+++ b/resource/client/ui-script/ui-hostsCustomize
@@ -0,0 +1,2 @@
+#!/bin/bash
+jq -r '.dns.hosts | to_entries[] | [.value, .key] | @tsv' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$'
diff --git a/resource/client/ui-script/ui-installBitwarden b/resource/client/ui-script/ui-installBitwarden
new file mode 100755
index 000000000..41a04c4c6
--- /dev/null
+++ b/resource/client/ui-script/ui-installBitwarden
@@ -0,0 +1,215 @@
+#!/bin/bash
+clear
+RED='\E[1;31m'
+GREEN='\E[1;32m'
+YELLOW='\E[1;33m'
+BLUE='\E[1;34m'
+PURPLE='\E[1;35m'
+CYAN='\E[1;36m'
+WHITE='\E[1;37m'
+cRES='\E[0m'
+
+
+
+bitwardenNginxConf (){
+cat << EOF >/etc/nginx/conf.d/bitwarden.conf
+server {
+ listen 8099 ssl http2 fastopen=256 reuseport;
+ error_page 497 https://\$host:8099\$request_uri;
+
+ include /etc/nginx/conf.d/ssl_certificate;
+
+ add_header X-Cache \$upstream_cache_status;
+
+ add_header Referrer-Policy "origin" always;
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header X-Download-Options "noopen" always;
+ add_header X-Frame-Options "SAMEORIGIN" always;
+ add_header X-Permitted-Cross-Domain-Policies "none" always;
+ add_header X-Robots-Tag "none" always;
+ add_header X-XSS-Protection "1; mode=block" always;
+ add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
+
+location / {
+ proxy_pass http://127.0.0.1:8098;
+ proxy_set_header Host \$host;
+ proxy_set_header REMOTE-HOST \$remote_addr;
+ proxy_set_header X-Real-IP \$remote_addr;
+ proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto \$scheme;
+ keepalive_requests 100000;
+ keepalive_timeout 600;
+ proxy_connect_timeout 600;
+ proxy_read_timeout 600;
+ proxy_send_timeout 600;
+ proxy_redirect off;
+ proxy_buffering off;
+ proxy_buffer_size 8k;
+ }
+
+location /notifications/hub {
+ proxy_pass http://127.0.0.1:3012;
+ proxy_set_header Upgrade \$http_upgrade;
+ proxy_set_header Connection "upgrade";
+ keepalive_requests 100000;
+ keepalive_timeout 600;
+ proxy_connect_timeout 600;
+ proxy_read_timeout 600;
+ proxy_send_timeout 600;
+ proxy_redirect off;
+ proxy_buffering off;
+ proxy_buffer_size 8k;
+}
+
+location /notifications/hub/negotiate {
+ proxy_pass http://127.0.0.1:8098;
+ keepalive_requests 100000;
+ keepalive_timeout 600;
+ proxy_connect_timeout 600;
+ proxy_read_timeout 600;
+ proxy_send_timeout 600;
+ proxy_redirect off;
+ proxy_buffering off;
+ proxy_buffer_size 8k;
+}
+}
+EOF
+systemctl force-reload nginx
+}
+
+
+
+bitwardenDockerRun(){
+docker run -d \
+ --name bitwarden \
+ -e PUID=1000 \
+ -e PGID=1000 \
+ -e TZ=Asia/Shanghai \
+ -p 8098:80 \
+ -v /opt/bitwarden/:/data/ \
+ --dns 1.1.1.1 \
+ --restart always \
+ --privileged=true \
+ vaultwarden/server:latest
+}
+
+
+
+installBitwarden(){
+mkdir -p /opt/bitwarden
+
+docker pull vaultwarden/server:latest
+
+bitwardenDockerRun
+
+bitwardenNginxConf
+
+cat << EOF >/etc/logrotate.d/bitwarden
+/var/log/bitwarden/*.log {
+ # 以 bitwarden 用户和群组的身份执行轮换
+ su bitwarden bitwarden
+ # 每天轮换
+ daily
+ # 当尺寸大于 5M 时轮换
+ size 5M
+ # 压缩旧的日志文件
+ compress
+ # 在删除或邮寄到 mail 指令中指定的地址之前,保留 4 个轮换的日志文件
+ rotate 4
+ # 把当前日志备份并截断
+ copytruncate
+ # 如果日志文件不存在,继续下一个操作
+ missingok
+ # 如果日志文件为空则不进行轮换
+ notifempty
+ # 在轮换的日志文件中添加数字格式的日期
+ dateext
+ # dateext 的日期格式
+ dateformat -%Y-%m-%d-%s
+}
+EOF
+jq '.app.bitwarden="installed"' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+chmod 666 /opt/de_GWD/0conf
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Install Bitwarden${cRES}"
+}
+
+
+
+uninstallBitwarden(){
+docker stop bitwardenrs >/dev/null 2>&1
+docker rm bitwardenrs >/dev/null 2>&1
+docker image ls 2>/dev/null | awk '/bitwardenrs/{print$3}' | while read line; do
+docker rmi $line >/dev/null 2>&1
+done
+
+docker stop bitwarden >/dev/null 2>&1
+docker rm bitwarden >/dev/null 2>&1
+docker image ls 2>/dev/null | awk '/bitwarden/{print$3}' | while read line; do
+docker rmi $line >/dev/null 2>&1
+done
+
+rm -rf /opt/bitwardenrs
+rm -rf /opt/bitwarden
+rm -rf /etc/nginx/conf.d/bitwardenrs.conf
+rm -rf /etc/nginx/conf.d/bitwarden.conf
+systemctl force-reload nginx
+rm -rf /etc/logrotate.d/bitwarden
+jq 'del(.app.bitwardenrs)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+jq 'del(.app.bitwarden)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+chmod 666 /opt/de_GWD/0conf
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Uninstall Bitwarden${cRES}"
+}
+
+
+
+updateBitwarden(){
+docker pull vaultwarden/server:latest
+
+docker stop bitwarden
+docker rm bitwarden
+
+bitwardenDockerRun
+
+bitwardenNginxConf
+
+docker system prune -f
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Update Bitwarden${cRES}"
+}
+
+
+
+start_menu(){
+ echo -e "${GREEN}=============================== ${cRES}"
+ echo -e "${GREEN} Bitwarden${cRES}"
+ echo -e "${GREEN}=============================== ${cRES}"
+ echo -e "${GREEN}1. Install Bitwarden${cRES}"
+ echo -e "${YELLOW}2. Uninstall Bitwarden${cRES}"
+ echo -e "${GREEN}0. Update Bitwarden${cRES}"
+ echo ""
+ read -p "Select:" num
+ case "$num" in
+ 1)
+ installBitwarden
+ start_menu
+ ;;
+ 2)
+ uninstallBitwarden
+ start_menu
+ ;;
+ 0)
+ updateBitwarden
+ start_menu
+ ;;
+ *)
+ clear
+ echo -e "${RED}Wrong number${cRES}"
+ sleep 1s
+ start_menu
+ ;;
+ esac
+}
+
+start_menu
\ No newline at end of file
diff --git a/resource/client/ui-script/ui-installCER b/resource/client/ui-script/ui-installCER
new file mode 100755
index 000000000..0ae6244f3
--- /dev/null
+++ b/resource/client/ui-script/ui-installCER
@@ -0,0 +1,228 @@
+#!/bin/bash
+clear
+RED='\E[1;31m'
+GREEN='\E[1;32m'
+YELLOW='\E[1;33m'
+BLUE='\E[1;34m'
+PURPLE='\E[1;35m'
+CYAN='\E[1;36m'
+WHITE='\E[1;37m'
+cRES='\E[0m'
+
+
+
+installCER(){
+CFapikey=$(jq -r '.FORWARD.APIkey' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+CFemail=$(jq -r '.FORWARD.Email' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+domain=$(jq -r '.FORWARD.domain' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+topDomain=$(echo $domain | rev | awk -F. '{print $1"."$2}' | rev)
+
+[[ -f "/etc/nginx/conf.d/80.conf" ]] && sed -i "/server_name/c\server_name $domain;" /etc/nginx/conf.d/80.conf
+sed -i "/server_name/c\server_name $domain;" /etc/nginx/conf.d/default.conf
+jq --arg serverName "$domain" '.address.serverName = $serverName' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+chmod 666 /opt/de_GWD/0conf
+
+cat << EOF >/var/www/ssl/update_ocsp_cache
+#!/bin/bash
+[[ ! -f "/var/www/ssl/intermediate.pem" ]] && wget --show-progress -cqO /var/www/ssl/intermediate.pem https://letsencrypt.org/certs/lets-encrypt-r3-cross-signed.pem
+[[ ! -f "/var/www/ssl/root.pem" ]] && wget --show-progress -cqO /var/www/ssl/root.pem https://letsencrypt.org/certs/isrgrootx1.pem
+
+cat /var/www/ssl/intermediate.pem >/var/www/ssl/bundle.pem
+cat /var/www/ssl/root.pem >>/var/www/ssl/bundle.pem
+
+openssl ocsp -no_nonce \
+ -issuer /var/www/ssl/intermediate.pem \
+ -cert /var/www/ssl/*.cer \
+ -CAfile /var/www/ssl/bundle.pem \
+ -VAfile /var/www/ssl/bundle.pem \
+ -url http://r3.o.lencr.org \
+ -respout /var/www/ssl/ocsp.resp
+
+systemctl force-reload nginx >/dev/null
+EOF
+chmod +x /var/www/ssl/update_ocsp_cache
+
+if [[ $(/var/www/ssl/update_ocsp_cache | awk 'NR==1{print$2}') != "good" ]]; then
+rm -rf /var/www/ssl/*.cer
+rm -rf /var/www/ssl/*.key
+rm -rf /var/www/ssl/*.pem
+cat << EOF >/var/www/ssl/ocsp.resp
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 00
+EOF
+
+crontab -l 2>/dev/null >/tmp/now.cron
+sed -i '/acme.sh/d' /tmp/now.cron
+crontab /tmp/now.cron
+rm -rf /tmp/now.cron
+rm -rf "/root/.acme.sh"
+
+sed -i '/ssl_trusted_certificate/d' /etc/nginx/conf.d/ssl_certificate
+sed -i '/ssl_stapling/d' /etc/nginx/conf.d/ssl_certificate
+sed -i '/ssl_stapling_verify/d' /etc/nginx/conf.d/ssl_certificate
+sed -i '/ssl_stapling_file/d' /etc/nginx/conf.d/ssl_certificate
+sed -i '/ssl_early_data/d' /etc/nginx/conf.d/ssl_certificate
+sed -i '/proxy_set_header/d' /etc/nginx/conf.d/ssl_certificate
+cat << EOF >>/etc/nginx/conf.d/ssl_certificate
+ssl_trusted_certificate /var/www/ssl/bundle.pem;
+
+ssl_stapling on;
+ssl_stapling_verify on;
+ssl_stapling_file /var/www/ssl/ocsp.resp;
+
+ssl_early_data on;
+proxy_set_header Early-Data \$ssl_early_data;
+EOF
+
+export CF_Key="$CFapikey"
+export CF_Email="$CFemail"
+
+curl https://get.acme.sh | sh
+"/root/.acme.sh"/acme.sh --force --upgrade --auto-upgrade
+"/root/.acme.sh"/acme.sh --force --set-default-ca --server letsencrypt
+"/root/.acme.sh"/acme.sh --force --issue --dns dns_cf -d $topDomain -d *.$topDomain -k ec-256 --dnssleep 180
+"/root/.acme.sh"/acme.sh --force --installcert -d $topDomain \
+ --key-file /var/www/ssl/de_GWD.key \
+ --fullchain-file /var/www/ssl/de_GWD.cer \
+ --reloadcmd "chmod 644 /var/www/ssl/*.key && systemctl force-reload nginx" \
+ --ecc
+fi
+
+/var/www/ssl/update_ocsp_cache
+
+[[ -d "/opt/de_GWD/vtrui" ]] && systemctl restart vtrui
+[[ -d "/opt/de_GWD/vtrui1" ]] && systemctl restart vtrui1
+[[ -d "/opt/de_GWD/coredns" ]] && systemctl restart coredns
+[[ -d "/opt/de_GWD/RproxyS" ]] && systemctl restart RproxyS
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Generate & Deploy TLS Certificate${cRES}"
+}
+
+
+
+resetCER(){
+mkdir -p /var/www/ssl && cd /var/www/ssl
+
+openssl req -x509 -nodes -days 3650 \
+ -subj "/C=CA/ST=QC/O=Company, Inc./CN=localhost.com" \
+ -config <(cat /etc/ssl/openssl.cnf \
+ <(printf '[SAN]\nsubjectAltName=DNS:localhost')) \
+ -newkey rsa:2048 \
+ -keyout de_GWD.key \
+ -out de_GWD.cer
+
+rm -rf /var/www/ssl/*.cer
+rm -rf /var/www/ssl/*.key
+rm -rf /var/www/ssl/*.pem
+rm -rf /var/www/ssl/ocsp.resp
+cat << EOF >/var/www/ssl/ocsp.resp
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 0000 0000 0000 0000 0000
+0000 0000 0000 00
+EOF
+
+crontab -l 2>/dev/null >/tmp/now.cron
+sed -i '/acme.sh/d' /tmp/now.cron
+crontab /tmp/now.cron
+rm -rf /tmp/now.cron
+rm -rf "/root/.acme.sh"
+
+sed -i '/ssl_trusted_certificate/d' /etc/nginx/conf.d/ssl_certificate
+sed -i '/ssl_stapling/d' /etc/nginx/conf.d/ssl_certificate
+sed -i '/ssl_stapling_verify/d' /etc/nginx/conf.d/ssl_certificate
+sed -i '/ssl_stapling_file/d' /etc/nginx/conf.d/ssl_certificate
+sed -i '/ssl_early_data/d' /etc/nginx/conf.d/ssl_certificate
+sed -i '/proxy_set_header/d' /etc/nginx/conf.d/ssl_certificate
+
+systemctl force-reload nginx
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Remove TLS Certificate${cRES}"
+}
+
+
+
+start_menu(){
+ echo -e "${GREEN}=============================== ${cRES}"
+ echo -e "${GREEN} Domain & Certificate${cRES}"
+ echo -e "${GREEN}=============================== ${cRES}"
+ echo -e "${GREEN}1. Generate TLS Certificate${cRES}"
+ echo -e "${YELLOW}2. Reset TLS Certificate${cRES}"
+ echo ""
+ read -p "Select:" num
+ case "$num" in
+ 1)
+ installCER
+ start_menu
+ ;;
+ 2)
+ resetCER
+ start_menu
+ ;;
+ *)
+ clear
+ echo -e "${RED}Wrong number${cRES}"
+ sleep 1s
+ start_menu
+ ;;
+ esac
+}
+
+start_menu
\ No newline at end of file
diff --git a/resource/client/ui-script/ui-installDocker b/resource/client/ui-script/ui-installDocker
new file mode 100755
index 000000000..2dbd7126b
--- /dev/null
+++ b/resource/client/ui-script/ui-installDocker
@@ -0,0 +1,83 @@
+#!/bin/bash
+clear
+RED='\E[1;31m'
+GREEN='\E[1;32m'
+YELLOW='\E[1;33m'
+BLUE='\E[1;34m'
+PURPLE='\E[1;35m'
+CYAN='\E[1;36m'
+WHITE='\E[1;37m'
+cRES='\E[0m'
+dockerComposeVer_reserved="1.29.2"
+
+
+
+installDocker(){
+curl -sSLo- https://download.docker.com/linux/debian/gpg | gpg --dearmor >/usr/share/keyrings/docker-ce-archive-keyring.gpg
+echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-ce-archive-keyring.gpg] https://download.docker.com/linux/debian $(cat /etc/os-release | grep VERSION= | cut -d'(' -f2 | cut -d')' -f1) stable" >/etc/apt/sources.list.d/docker.list
+
+unset aptPKG
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^docker-ce$') ]] && aptPKG+=(docker-ce)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^docker-ce-cli$') ]] && aptPKG+=(docker-ce-cli)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^containerd.io$') ]] && aptPKG+=(containerd.io)
+[[ -n $aptPKG ]] && apt update && apt install $(echo ${aptPKG[@]})
+
+if [[ -n $(dpkg -l | awk '{print$2}' | grep '^docker-ce$') ]] && [[ -n $(dpkg -l | awk '{print$2}' | grep '^containerd.io$') ]]; then
+mkdir -p /etc/docker/
+systemctl stop docker containerd
+cat << EOF >/etc/docker/daemon.json
+{
+ "iptables": false
+}
+EOF
+systemctl restart docker
+fi
+
+dockerComposeVer=$(curl -sSL "https://api.github.com/repos/docker/compose/releases/latest" | jq -r .tag_name | grep -v '^null$')
+[[ -z $dockerComposeVer_reserved ]] && dockerComposeVer=$dockerComposeVer_reserved
+
+curl -L https://github.com/docker/compose/releases/download/$dockerComposeVer/docker-compose-$(uname -s)-$(uname -m) >/usr/local/bin/docker-compose
+chmod +x /usr/local/bin/docker-compose
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Install Docker${cRES}"
+}
+
+
+
+uninstallDocker(){
+rm -rf /etc/apt/sources.list.d/docker.list
+apt remove --purge docker-ce docker-ce-cli containerd.io
+rm -rf /usr/local/bin/docker-compose
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Uninstall Docker${cRES}"
+}
+
+
+
+start_menu(){
+ echo -e "${GREEN}=============================== ${cRES}"
+ echo -e "${GREEN} Docker${cRES}"
+ echo -e "${GREEN}=============================== ${cRES}"
+ echo -e "${GREEN}1. Install Docker${cRES}"
+ echo -e "${YELLOW}2. Uninstall Docker${cRES}"
+ echo ""
+ read -p "Select:" num
+ case "$num" in
+ 1)
+ installDocker
+ start_menu
+ ;;
+ 2)
+ uninstallDocker
+ start_menu
+ ;;
+ *)
+ clear
+ echo -e "${RED}Wrong number${cRES}"
+ sleep 1s
+ start_menu
+ ;;
+ esac
+}
+
+start_menu
\ No newline at end of file
diff --git a/resource/client/ui-script/ui-installFileRun b/resource/client/ui-script/ui-installFileRun
new file mode 100755
index 000000000..c92b0ce4b
--- /dev/null
+++ b/resource/client/ui-script/ui-installFileRun
@@ -0,0 +1,200 @@
+#!/bin/bash
+clear
+RED='\E[1;31m'
+GREEN='\E[1;32m'
+YELLOW='\E[1;33m'
+BLUE='\E[1;34m'
+PURPLE='\E[1;35m'
+CYAN='\E[1;36m'
+WHITE='\E[1;37m'
+cRES='\E[0m'
+architecture=$(dpkg --print-architecture)
+
+
+
+installFileRun(){
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^mariadb-server$') ]] && echo -e "${WHITE}[ ${YELLOW}! ${WHITE}]\c" && echo -e "\t${YELLOW}Install MariaDB first${cRES}" && exit
+
+filerunDep
+
+filerunNginx
+
+rm -rf /var/www/html/filerun
+mkdir -p /var/www/html/filerun
+wget --show-progress -cqO /var/www/html/filerun/FileRun.zip https://filerun.com/download-latest
+if [[ -n $(unzip -tq /var/www/html/filerun/FileRun.zip | grep "No errors detected in compressed data") ]]; then
+unzip /var/www/html/filerun/FileRun.zip -d /var/www/html/filerun >/dev/null
+rm -f /var/www/html/filerun/FileRun.zip
+chown -R www-data:www-data /var/www/html/filerun
+
+echo -e "${BLUE}-------------------------------------------------- ${cRES}"
+echo -e "${GREEN}FileRun thumbs and previews support${cRES}"
+echo
+echo -e "${BLUE}FFmpeg: ${YELLOW}/usr/bin/ffmpeg${cRES}"
+echo -e "${BLUE}LibreOffice: ${YELLOW}soffice${cRES}"
+echo -e "${BLUE}stl-thumb: ${YELLOW}/usr/bin/stl-thumb${cRES}"
+echo -e "${BLUE}pngquant: ${YELLOW}/usr/bin/pngquant${cRES}"
+echo
+echo -e "${BLUE}-------------------------------------------------- ${cRES}"
+
+else
+echo -e "${WHITE}[ ${RED}✕ ${WHITE}]\c" && echo -e "\t${WHITE}FileRun${RED} Download Failed${cRES}"
+break
+fi
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Install FileRun${cRES}"
+}
+
+
+
+filerunDep(){
+unset aptPKG
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-mysql$') ]] && aptPKG+=(php7.4-mysql)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-mbstring$') ]] && aptPKG+=(php7.4-mbstring)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-curl$') ]] && aptPKG+=(php7.4-curl)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-zip$') ]] && aptPKG+=(php7.4-zip)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-gd$') ]] && aptPKG+=(php7.4-gd)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-ldap$') ]] && aptPKG+=(php7.4-ldap)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-xml$') ]] && aptPKG+=(php7.4-xml)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-json$') ]] && aptPKG+=(php7.4-json)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-opcache$') ]] && aptPKG+=(php7.4-opcache)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-imagick$') ]] && aptPKG+=(php7.4-imagick)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^php7.4-memcached$') ]] && aptPKG+=(php7.4-memcached)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^imagemagick$') ]] && aptPKG+=(imagemagick)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^memcached$') ]] && aptPKG+=(memcached)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^libmemcached-tools$') ]] && aptPKG+=(libmemcached-tools)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^libvips-tools$') ]] && aptPKG+=(libvips-tools)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^pngquant$') ]] && aptPKG+=(pngquant)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^ffmpeg$') ]] && aptPKG+=(ffmpeg)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^libreoffice-common$') ]] && aptPKG+=(libreoffice-common)
+[[ -n $aptPKG ]] && apt update && apt install $(echo ${aptPKG[@]})
+[[ $? -ne 0 ]] && rm -rf /var/lib/apt/lists/lock
+
+ghREPO="unlimitedbacon/stl-thumb"
+ghPackage="_$architecture.deb"
+curl -sSL https://api.github.com/repos/${ghREPO}/releases/latest | grep -E 'browser_download_url' | grep 'stl-thumb_' | grep $ghPackage | cut -d '"' -f 4 | wget --show-progress -qi - -O /tmp/stl-thumb.deb
+[[ $? -ne 0 ]] && echo -e "${WHITE}[ ${RED}✕ ${WHITE}]\c" && echo -e "\t${WHITE}stl-thumb${RED} Download Failed${cRES}" && exit
+dpkg -i /tmp/stl-thumb.deb
+
+case "$architecture" in
+ amd64)
+ ioncube_loaders="ioncube_loaders_lin_x86-64.zip"
+ ;;
+ arm64)
+ ioncube_loaders="ioncube_loaders_lin_aarch64.zip"
+ ;;
+esac
+
+wget --show-progress -cqO /tmp/ioncube_loaders_lin.zip https://downloads.ioncube.com/loader_downloads/$ioncube_loaders
+if [[ -n $(unzip -tq /tmp/ioncube_loaders_lin.zip | grep "No errors detected in compressed data") ]]; then
+rm -rf /usr/local/ioncube
+unzip /tmp/ioncube_loaders_lin.zip -d /usr/local >/dev/null 2>&1
+
+echo "zend_extension = /usr/local/ioncube/ioncube_loader_lin_7.4.so" >/etc/php/7.4/mods-available/ioncube.ini
+ln -sf /etc/php/7.4/mods-available/ioncube.ini /etc/php/7.4/fpm/conf.d/00-ioncube.ini
+ln -sf /etc/php/7.4/mods-available/ioncube.ini /etc/php/7.4/cli/conf.d/00-ioncube.ini
+systemctl restart php7.4-fpm
+else
+echo -e "${WHITE}[ ${RED}✕ ${WHITE}]\c" && echo -e "\t${WHITE}ioncube_loader${RED} Download Failed${cRES}" && exit
+fi
+}
+
+
+
+filerunNginx(){
+cat << EOF >/etc/nginx/conf.d/filerun.conf
+server {
+ listen 10501 ssl http2 fastopen=256 reuseport;
+ root /var/www/html/filerun;
+ index index.php index.html index.htm;
+ error_page 497 https://\$host:10501\$request_uri;
+
+ include /etc/nginx/conf.d/ssl_certificate;
+
+ add_header X-Cache \$upstream_cache_status;
+
+ add_header Referrer-Policy "no-referrer" always;
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header X-Download-Options "noopen" always;
+ add_header X-Frame-Options "SAMEORIGIN" always;
+ add_header X-Permitted-Cross-Domain-Policies "none" always;
+ add_header X-Robots-Tag "none" always;
+ add_header X-XSS-Protection "1; mode=block" always;
+ add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
+
+location ~ [^/]\.php(/|$) {
+ fastcgi_split_path_info ^(.+?\.php)(/.*)$;
+ if (!-f \$document_root\$fastcgi_script_name) {
+ return 404;
+ }
+
+ fastcgi_pass unix:/run/php/php7.4-fpm.sock;
+ fastcgi_index index.php;
+ include fastcgi_params;
+ fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
+}
+}
+EOF
+
+systemctl force-reload nginx
+}
+
+
+
+uninstallFileRun(){
+rm -rf /var/www/html/filerun
+
+rm -rf /etc/nginx/conf.d/filerun.conf
+
+sed -i "/zend_extension/d" /etc/php/7.4/fpm/php.ini
+sed -i "/zend_extension/d" /etc/php/7.4/cli/php.ini
+rm -rf /usr/local/ioncube
+
+dpkg -r stl-thumb
+
+rm -rf /usr/share/fonts/truetype/libreoffice
+
+apt remove --purge libdrm-dev libosmesa6 libosmesa6-dev libpthread-stubs0-dev libx11-dev libxau-dev libxcb1-dev libxdmcp-dev x11proto-core-dev x11proto-dev xorg-sgml-doctools xtrans-dev mesa-common-dev libreoffice
+
+apt remove --purge && apt clean && apt autoclean
+
+cat << "EOF" >/tmp/filerunRestart
+#!/bin/bash
+systemctl restart php7.4-fpm
+systemctl force-reload nginx
+rm -rf /tmp/filerunRestart
+EOF
+chmod +x /tmp/filerunRestart
+tmux new -ds filerunRestart '/tmp/filerunRestart'
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Uninstall FileRun${cRES}"
+}
+
+
+
+start_menu(){
+ echo -e "${GREEN}=============================== ${cRES}"
+ echo -e "${GREEN} FileRun${cRES}"
+ echo -e "${GREEN}=============================== ${cRES}"
+ echo -e "${GREEN}1. Install FileRun${cRES}"
+ echo -e "${YELLOW}2. Uninstall FileRun${cRES}"
+ echo ""
+ read -p "Select:" num
+ case "$num" in
+ 1)
+ installFileRun
+ start_menu
+ ;;
+ 2)
+ uninstallFileRun
+ start_menu
+ ;;
+ *)
+ clear
+ echo -e "${RED}Wrong number${cRES}"
+ sleep 1s
+ start_menu
+ ;;
+ esac
+}
+
+start_menu
\ No newline at end of file
diff --git a/resource/client/ui-script/ui-installJellyfin b/resource/client/ui-script/ui-installJellyfin
new file mode 100755
index 000000000..abaf12948
--- /dev/null
+++ b/resource/client/ui-script/ui-installJellyfin
@@ -0,0 +1,223 @@
+#!/bin/bash
+clear
+RED='\E[1;31m'
+GREEN='\E[1;32m'
+YELLOW='\E[1;33m'
+BLUE='\E[1;34m'
+PURPLE='\E[1;35m'
+CYAN='\E[1;36m'
+WHITE='\E[1;37m'
+cRES='\E[0m'
+
+
+
+jellyfinNginxConf(){
+cat << EOF >/etc/nginx/conf.d/jellyfin.conf
+server {
+ listen 8097 ssl http2 fastopen=256 reuseport;
+ root /var/www/html;
+ error_page 497 https://\$host:8097\$request_uri;
+
+ include /etc/nginx/conf.d/ssl_certificate;
+
+ add_header X-Cache \$upstream_cache_status;
+
+ add_header Referrer-Policy "no-referrer" always;
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header X-Download-Options "noopen" always;
+ add_header X-Frame-Options "SAMEORIGIN" always;
+ add_header X-Permitted-Cross-Domain-Policies "none" always;
+ add_header X-Robots-Tag "none" always;
+ add_header X-XSS-Protection "1; mode=block" always;
+ add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
+
+location = / {
+ return 302 https://\$host:8097/web/;
+}
+
+location / {
+ proxy_pass http://127.0.0.1:8096;
+ proxy_set_header Host \$host;
+ proxy_set_header REMOTE-HOST \$remote_addr;
+ proxy_set_header X-Real-IP \$remote_addr;
+ proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto \$scheme;
+ proxy_set_header X-Forwarded-Protocol \$scheme;
+ proxy_set_header X-Forwarded-Host \$http_host;
+ keepalive_requests 100000;
+ keepalive_timeout 600;
+ proxy_connect_timeout 600;
+ proxy_read_timeout 600;
+ proxy_send_timeout 600;
+ proxy_redirect off;
+ proxy_buffering off;
+ proxy_buffer_size 8k;
+}
+
+location = /web/ {
+ proxy_pass http://127.0.0.1:8096/web/index.html;
+ proxy_set_header Host \$host;
+ proxy_set_header REMOTE-HOST \$remote_addr;
+ proxy_set_header X-Real-IP \$remote_addr;
+ proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto \$scheme;
+ proxy_set_header X-Forwarded-Protocol \$scheme;
+ proxy_set_header X-Forwarded-Host \$http_host;
+ keepalive_requests 100000;
+ keepalive_timeout 600;
+ proxy_connect_timeout 600;
+ proxy_read_timeout 600;
+ proxy_send_timeout 600;
+ proxy_redirect off;
+ proxy_buffering off;
+ proxy_buffer_size 8k;
+}
+
+location /socket {
+ proxy_pass http://127.0.0.1:8096/socket;
+ proxy_http_version 1.1;
+ proxy_set_header Host \$host;
+ proxy_set_header Upgrade \$http_upgrade;
+ proxy_set_header Connection "upgrade";
+ proxy_set_header REMOTE-HOST \$remote_addr;
+ proxy_set_header X-Real-IP \$remote_addr;
+ proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto \$scheme;
+ proxy_set_header X-Forwarded-Protocol \$scheme;
+ proxy_set_header X-Forwarded-Host \$http_host;
+ keepalive_requests 100000;
+ keepalive_timeout 600;
+ proxy_connect_timeout 600;
+ proxy_read_timeout 600;
+ proxy_send_timeout 600;
+ proxy_redirect off;
+ proxy_buffering off;
+ proxy_buffer_size 8k;
+}
+
+}
+EOF
+systemctl force-reload nginx >/dev/null
+}
+
+
+
+jellyfinDockerRun(){
+docker run -d \
+ --name jellyfin \
+ -e PUID=1000 \
+ -e PGID=1000 \
+ -e TZ=Asia/Shanghai \
+ -p 8096:8096 \
+ -p 8920:8920 \
+ -p 7359:7359/udp \
+ -p 1900:1900/udp \
+ -v /opt/jellyfin/config:/config \
+ -v /opt/jellyfin/cache:/cache \
+ --mount type=bind,src=/mnt,dst=/media,bind-propagation=rshared \
+ --dns 1.1.1.1 \
+ --restart always \
+ nyanmisaka/jellyfin:latest
+}
+
+
+
+installJellyfin(){
+mkdir -p /opt/jellyfin/config
+mkdir -p /opt/jellyfin/cache
+
+docker pull nyanmisaka/jellyfin:latest
+
+jellyfinDockerRun
+
+jellyfinNginxConf
+
+jq '.app.jellyfin="installed"' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+chmod 666 /opt/de_GWD/0conf
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Install Jellyfin${cRES}"
+}
+
+
+
+uninstallJellyfin(){
+docker stop jellyfin >/dev/null 2>&1
+docker rm jellyfin >/dev/null 2>&1
+docker image ls 2>/dev/null | awk '/jellyfin/{print$3}' | while read line; do
+docker rmi $line >/dev/null 2>&1
+done
+
+rm -rf /etc/nginx/conf.d/jellyfin.conf
+systemctl force-reload nginx >/dev/null
+
+rm -rf /opt/jellyfin
+jq 'del(.app.jellyfin)' /opt/de_GWD/0conf | sponge /opt/de_GWD/0conf
+chmod 666 /opt/de_GWD/0conf
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Uninstall Jellyfin${cRES}"
+}
+
+
+
+updateJellyfin(){
+mkdir -p /opt/jellyfin/config
+mkdir -p /opt/jellyfin/cache
+
+docker pull nyanmisaka/jellyfin:latest
+
+docker stop jellyfin
+docker rm jellyfin
+
+jellyfinDockerRun
+
+jellyfinNginxConf
+
+docker system prune -f
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Update Jellyfin${cRES}"
+}
+
+
+
+start_menu(){
+[[ -f "/usr/share/keyrings/jellyfin-archive-keyring.gpg" ]] && rm -rf /usr/share/keyrings/jellyfin-archive-keyring.gpg
+[[ -f "/etc/apt/sources.list.d/jellyfin.list" ]] && rm -rf /etc/apt/sources.list.d/jellyfin.list
+
+unset aptPKG
+[[ -n $(dpkg -l | awk '{print$2}' | grep '^jellyfin$') ]] && aptPKG+=(jellyfin)
+[[ -n $(dpkg -l | awk '{print$2}' | grep '^jellyfin-ffmpeg$') ]] && aptPKG+=(jellyfin-ffmpeg)
+[[ -n $(dpkg -l | awk '{print$2}' | grep '^jellyfin-server$') ]] && aptPKG+=(jellyfin-server)
+[[ -n $(dpkg -l | awk '{print$2}' | grep '^jellyfin-web$') ]] && aptPKG+=(jellyfin-web)
+[[ -n $aptPKG ]] && apt update && apt autoremove --purge $(echo ${aptPKG[@]})
+
+ echo -e "${GREEN}=============================== ${cRES}"
+ echo -e "${GREEN} Jellyfin${cRES}"
+ echo -e "${GREEN}=============================== ${cRES}"
+ echo -e "${GREEN}1. Install Jellyfin${cRES}"
+ echo -e "${YELLOW}2. Uninstall Jellyfin${cRES}"
+ echo -e "${GREEN}0. Update Jellyfin${cRES}"
+ echo ""
+ read -p "Select:" num
+ case "$num" in
+ 1)
+ installJellyfin
+ start_menu
+ ;;
+ 2)
+ uninstallJellyfin
+ start_menu
+ ;;
+ 0)
+ updateJellyfin
+ start_menu
+ ;;
+ *)
+ clear
+ echo -e "${RED}Wrong number${cRES}"
+ sleep 1s
+ start_menu
+ ;;
+ esac
+}
+
+start_menu
\ No newline at end of file
diff --git a/resource/client/ui-script/ui-installMariaDB b/resource/client/ui-script/ui-installMariaDB
new file mode 100755
index 000000000..d8a234d3b
--- /dev/null
+++ b/resource/client/ui-script/ui-installMariaDB
@@ -0,0 +1,184 @@
+#!/bin/bash
+clear
+RED='\E[1;31m'
+GREEN='\E[1;32m'
+YELLOW='\E[1;33m'
+BLUE='\E[1;34m'
+PURPLE='\E[1;35m'
+CYAN='\E[1;36m'
+WHITE='\E[1;37m'
+cRES='\E[0m'
+
+
+installMariaDB(){
+ echo -e "${GREEN}================== ${cRES}"
+ echo -e "${GREEN} Datadase user${cRES}"
+ echo -e "${GREEN}================== ${cRES}"
+ read sqluser
+
+ echo -e "${GREEN}================== ${cRES}"
+ echo -e "${GREEN} Datadase password${cRES}"
+ echo -e "${GREEN}================== ${cRES}"
+ read sqlpw
+
+ echo -e "${GREEN}================== ${cRES}"
+ echo -e "${GREEN} Datadase name${cRES}"
+ echo -e "${GREEN}================== ${cRES}"
+ read sqlnm
+
+apt update && apt install mariadb-server
+[[ $? -ne 0 ]] && rm -rf /var/lib/apt/lists/lock
+
+mysql_secure_installation
+
+echo -e "${WHITE}Enter current password for root again${cRES}"
+read sqlrootpw
+
+cat << EOF > ~/.my.cnf
+[client]
+user=root
+password=$sqlrootpw
+EOF
+
+mysql -e "create database $sqlnm default charset utf8 collate utf8_general_ci;"
+mysql -e "CREATE USER '$sqluser'@'localhost' IDENTIFIED BY '$sqlpw';"
+mysql -e "grant all privileges on $sqlnm.* TO '$sqluser'@'localhost';"
+rm -rf ~/.my.cnf
+
+cat << EOF > /etc/mysql/my.cnf
+[client]
+default-character-set = utf8mb4
+port = 3306
+socket = /run/mysqld/mysqld.sock
+
+[mysqld]
+user = mysql
+pid-file = /run/mysqld/mysqld.pid
+socket = /run/mysqld/mysqld.sock
+port = 3306
+bind-address =127.0.0.1
+basedir = /usr
+datadir = /var/lib/mysql
+tmpdir = /tmp
+lc_messages_dir = /usr/share/mysql
+lc_messages = en_US
+open_files_limit = 65535
+skip-external-locking
+
+max_allowed_packet = 32M
+max_connections = 300
+table_open_cache = 100
+sort_buffer_size = 4M
+
+thread_cache_size = 200
+key_buffer_size = 64M
+myisam_recover_options = BACKUP
+myisam_sort_buffer_size = 64M
+bulk_insert_buffer_size = 16M
+read_buffer_size = 2M
+read_rnd_buffer_size = 1M
+
+skip-name-resolve
+default_storage_engine = InnoDB
+innodb_buffer_pool_instances = 1
+innodb_buffer_pool_size = 256M
+innodb_open_files = 300
+innodb_io_capacity = 1000
+innodb_read_io_threads = 64
+innodb_write_io_threads = 64
+innodb_log_buffer_size = 32M
+innodb_log_file_size = 256M
+innodb_file_per_table = 1
+innodb_flush_log_at_trx_commit = 2
+innodb_flush_method = O_DIRECT
+innodb_max_dirty_pages_pct = 90
+innodb_large_prefix = on
+innodb_file_format = barracuda
+
+query_cache_type = 1
+query_cache_limit = 512K
+query_cache_min_res_unit = 2k
+query_cache_size = 64M
+tmp_table_size = 32M
+max_heap_table_size = 32M
+
+log_warnings = 2
+slow_query_log = 1
+slow_query_log_file = /var/log/mysql/mariadb.log
+long_query_time = 1
+log_slow_verbosity = query_plan
+log_bin = /var/log/mysql/mariadb-bin
+log_bin_index = /var/log/mysql/mariadb-bin.index
+expire_logs_days = 10
+max_binlog_size = 100M
+
+concurrent_insert = 2
+connect_timeout = 5
+wait_timeout = 600
+character-set-server = utf8mb4
+collation-server = utf8mb4_general_ci
+transaction_isolation = READ-COMMITTED
+binlog_format = ROW
+
+[mysqldump]
+quick
+quote-names
+max_allowed_packet = 16M
+
+[mysql]
+no-auto-rehash
+
+[isamchk]
+key_buffer = 16M
+EOF
+systemctl restart mariadb
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}MariaDB ${GREEN}Installed${cRES}"
+}
+
+
+
+uninstallMariaDB(){
+systemctl stop mariadb
+systemctl disable mariadb
+rm -rf /etc/mysql
+rm -rf /var/lib/mysql
+
+apt remove --purge mariadb*
+rm -f /var/lib/apt/lists/lock
+rm -f /var/cache/apt/archives/lock
+rm -f /var/lib/dpkg/lock
+dpkg --configure -a
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}MariaDB ${GREEN}Uninstalled${cRES}"
+}
+
+
+
+start_menu(){
+ echo -e "${GREEN}=============================== ${cRES}"
+ echo -e "${GREEN} MariaDB${cRES}"
+ echo -e "${GREEN}=============================== ${cRES}"
+ echo -e "${GREEN}1. Install MariaDB${cRES}"
+ echo -e "${YELLOW}2. Uninstall MariaDB${cRES}"
+ echo ""
+ read -p "Select:" num
+ case "$num" in
+ 1)
+ installMariaDB
+ start_menu
+ ;;
+ 2)
+ uninstallMariaDB
+ start_menu
+ ;;
+ *)
+ clear
+ echo -e "${RED}Wrong number${cRES}"
+ sleep 1s
+ start_menu
+ ;;
+ esac
+}
+
+start_menu
\ No newline at end of file
diff --git a/resource/client/ui-script/ui-installNFS b/resource/client/ui-script/ui-installNFS
new file mode 100755
index 000000000..65e364e17
--- /dev/null
+++ b/resource/client/ui-script/ui-installNFS
@@ -0,0 +1,71 @@
+#!/bin/bash
+clear
+RED='\E[1;31m'
+GREEN='\E[1;32m'
+YELLOW='\E[1;33m'
+BLUE='\E[1;34m'
+PURPLE='\E[1;35m'
+CYAN='\E[1;36m'
+WHITE='\E[1;37m'
+cRES='\E[0m'
+
+
+installNFSsupport(){
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Install NFS${cRES}\r\c"
+unset aptPKG
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^autofs$') ]] && aptPKG+=(autofs)
+[[ -z $(dpkg -l | awk '{print$2}' | grep '^nfs-common$') ]] && aptPKG+=(nfs-common)
+[[ -n $aptPKG ]] && apt update && apt install $(echo ${aptPKG[@]})
+
+rm -rf '/etc/auto.master.d'
+sed -i '/+auto.master/,$d' /etc/auto.master
+cat << EOF >>/etc/auto.master
++auto.master
+/net -hosts --timeout=60
+/media/misc /etc/autofs/auto.misc --timeout=5
+/media/net /etc/autofs/auto.net --timeout=60
+/- /etc/auto.nfs
+EOF
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Install NFS${cRES}"
+}
+
+
+
+uninstallNFSsupport(){
+apt remove --purge autofs nfs-common
+
+rm -rf /etc/auto.master.d/nfs.autofs
+
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}NFS ${GREEN}Uninstalled${cRES}"
+}
+
+
+
+start_menu(){
+ echo -e "${GREEN}=============================== ${cRES}"
+ echo -e "${GREEN} NFS support${cRES}"
+ echo -e "${GREEN}=============================== ${cRES}"
+ echo -e "${GREEN}1. Install NFS support${cRES}"
+ echo -e "${YELLOW}2. Uninstall NFS support${cRES}"
+ echo ""
+ read -p "Select:" num
+ case "$num" in
+ 1)
+ installNFSsupport
+ start_menu
+ ;;
+ 2)
+ uninstallNFSsupport
+ start_menu
+ ;;
+ *)
+ clear
+ echo -e "${RED}Wrong number${cRES}"
+ sleep 1s
+ start_menu
+ ;;
+ esac
+}
+
+start_menu
+
diff --git a/resource/client/ui-script/ui-installWG b/resource/client/ui-script/ui-installWG
new file mode 100755
index 000000000..4c549255a
--- /dev/null
+++ b/resource/client/ui-script/ui-installWG
@@ -0,0 +1,57 @@
+#!/bin/bash
+clear
+RED='\E[1;31m'
+GREEN='\E[1;32m'
+YELLOW='\E[1;33m'
+BLUE='\E[1;34m'
+PURPLE='\E[1;35m'
+CYAN='\E[1;36m'
+WHITE='\E[1;37m'
+cRES='\E[0m'
+
+
+
+installWGcore(){
+echo -e "${WHITE}[...]\c" && echo -e "\t${WHITE}Install Wireguard${cRES}\r\c"
+uname -r 2>&1 | grep -o '[0-9.]*' | head -n 1 >/tmp/kernelVer
+echo "5.6" >>/tmp/kernelVer
+
+if [[ $(cat /tmp/kernelVer | sort -rV | head -n 1) = "5.6" ]]; then
+ echo -e "${WHITE}[ ${YELLOW}! ${WHITE}]\c" && echo -e "\t${YELLOW}Update kernel first ! ${cRES}"
+else
+ unset aptPKG
+ [[ -z $(dpkg -l | awk '{print$2}' | grep '^wireguard-tools$') ]] && aptPKG+=(wireguard-tools)
+ [[ -n $aptPKG ]] && apt update && apt install $(echo ${aptPKG[@]})
+
+ if [[ -z $(jq -r '.wireguard.server.sprivatekey' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$') ]]; then
+ /opt/de_GWD/ui-WGgenSkey
+ fi
+fi
+
+rm -rf /tmp/kernelVer
+echo -e "${WHITE}[ ${GREEN}✓ ${WHITE}]\c" && echo -e "\t${WHITE}Install Wireguard${cRES}"
+}
+
+
+start_menu(){
+ echo -e "${GREEN}=============================== ${cRES}"
+ echo -e "${GREEN} Wireguard${cRES}"
+ echo -e "${GREEN}=============================== ${cRES}"
+ echo -e "${GREEN}1. Install Wireguard${cRES}"
+ echo ""
+ read -p "Select:" num
+ case "$num" in
+ 1)
+ installWGcore
+ start_menu
+ ;;
+ *)
+ clear
+ echo -e "${RED}Wrong number${cRES}"
+ sleep 1s
+ start_menu
+ ;;
+ esac
+}
+
+start_menu
\ No newline at end of file
diff --git a/resource/client/ui-script/ui-installZ b/resource/client/ui-script/ui-installZ
new file mode 100755
index 000000000..bf1ed0909
--- /dev/null
+++ b/resource/client/ui-script/ui-installZ
@@ -0,0 +1,10 @@
+#!/bin/bash
+rm -rf /opt/de_GWD/update
+
+kill $(ps -e | grep 'ttyd' | awk '{print$1}') >/dev/null 2>&1
+
+[[ -n $(cat /etc/resolv.conf | grep -v '127.0.0.1') ]] && resolvconf -u
+
+ps -aux | grep 'ui-install' | sed '/grep/d' | awk '{print$2}' | while read line; do
+kill $line >/dev/null 2>&1
+done
diff --git a/resource/client/ui-script/ui-markThis b/resource/client/ui-script/ui-markThis
new file mode 100755
index 000000000..dee973efe
--- /dev/null
+++ b/resource/client/ui-script/ui-markThis
@@ -0,0 +1,10 @@
+#!/bin/bash
+markName=$(jq -r '.address.alias' /opt/de_GWD/0conf 2>/dev/null | grep -v '^null$')
+
+sed -i "/