From ce242e3ab95315095ebca4fbe8fed76949f04897 Mon Sep 17 00:00:00 2001 From: mack-a Date: Thu, 10 Nov 2022 17:53:26 +0800 Subject: [PATCH] feat(script): update English version --- shell/install_en.sh | 4161 ++++++++++++++++++++++++++++--------------- 1 file changed, 2709 insertions(+), 1452 deletions(-) diff --git a/shell/install_en.sh b/shell/install_en.sh index 0e800735..81ccc290 100644 --- a/shell/install_en.sh +++ b/shell/install_en.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash -# Detection area -# ------------------------------------------------------------- -# Inspection system +# detection area +#---------------------------------------------------- +# check system export LANG=en_US.UTF-8 echoContent() { case $1 in - # Red + # red "red") # shellcheck disable=SC2154 ${echoType} "\033[31m${printN}$2 \033[0m" @@ -36,7 +36,7 @@ checkSystem() { if [[ -n $(find /etc -name "redhat-release") ]] || grep " - exit 1 - ;; - esac + echo "This CPU architecture is not supported--->" + exit 1 + ;; + esac fi else - echoContent red " Unable to recognize this CPU architecture, default AMD64, X86_64--->" + echoContent red "This CPU architecture cannot be recognized, default amd64, x86_64--->" xrayCoreCPUVendor="Xray-linux-64" v2rayCoreCPUVendor="v2ray-linux-64" - trojanGoCPUVendor="trojan-go-linux-amd64" fi } -# Initialization global variable +# initialize global variables initVar() { installType='yum -y install' removeType='yum -y remove' upgrade="yum -y update" echoType='echo -e' - # Core supported CPU version + # Core supported cpu version xrayCoreCPUVendor="" v2rayCoreCPUVendor="" - trojanGoCPUVendor="" + hysteriaCoreCPUVendor="" + # domain name domain= - # Cdn node Address + # address of the CDN node add= - # Total installation + # The total progress of the installation totalProgress=1 - # 1.xray-core Install - # 2.v2ray-core Install - # 3.v2ray-core[xtls] Install + # 1.xray-core installation + # 2.v2ray-core installation + # 3.v2ray-core[xtls] installation coreInstallType= - # Core installation PATH + # core installation path # coreInstallPath= # v2ctl Path ctlPath= - # 1.All installation - # 2.Personalization installation + # 1.Install all + # 2.Personalized installation # v2rayAgentInstallType= - # Current personalization installation method 01234 + # Current personalized installation method 01234 currentInstallProtocolType= - # Pre-type + # The order of the current alpn + currentAlpn= + + # prepended type frontingType= - # Selected personalized installation method + # Personalized installation method selected selectCustomInstallType= - # v2ray-core、xray-core Path of the configuration file + # Path to v2ray-core, xray-core configuration files configPath= - # Profile path + # Path to hysteria configuration file + hysteriaConfigPath= + + # The path to the configuration file currentPath= - # Profile host + # config file host currentHost= - # Selected when installing core Types of + # The core type selected during installation selectCoreType= - # Default Core version + # Default core version v2rayCoreVersion= - # Random path + # random path customPath= # centos version @@ -172,39 +177,101 @@ initVar() { # UUID currentUUID= - # pingIPv6 pingIPv4 - # pingIPv4= - pingIP= - pingIPv6= + # previousClients + previousClients= + localIP= - # Integrated Update Certificate Logic No longer use separate scripts--RenewTLS + # Integrated update certificate logic no longer uses a separate script --RenewTLS renewTLS=$1 - # Number of attempts after a failed tls installation + # The number of attempts after tls install failed installTLSCount= + + # BTPanel state + # BTPanelStatus= + + # nginx configuration file path + nginxConfigPath=/etc/nginx/conf.d/ + + # Is it a preview version + prereleaseStatus=false + + # ssl type + sslType= + + # ssl mailbox + sslEmail= + + # check the number of days + sslRenewalDays=90 + + # dns ssl status + dnsSSLStatus= + + # dns tls domain + dnsTLSDomain= + + # Whether the domain name installs a wildcard certificate through dns + installDNSACMEStatus= + + # custom port + customPort= + + # hysteria port + hysteriaPort= + + # hysteria protocol + hysteriaProtocol= + + # hysteria delay + hysteriaLag= + + # hysteria downlink speed + hysteriaClientDownloadSpeed= + + # hysteria uplink speed + hysteriaClientUploadSpeed= + } -# Detection installation method +# read tls certificate details +readAcmeTLS() { + if [[ -n "${currentHost}" ]]; then + dnsTLSDomain=$(echo "${currentHost}" | awk -F "[.]" '{print $(NF-1)"."$NF}') + fi + if [[ -d "$HOME/.acme.sh/*.${dnsTLSDomain}_ecc" && -f "$HOME/.acme.sh/*.${dnsTLSDomain}_ecc/*.${dnsTLSDomain}.key" && -f "$HOME/.acme.sh/*.${dnsTLSDomain}_ecc/*.${dnsTLSDomain}.cer" ]]; then + installDNSACMEStatus=true + fi +} +# Read the default custom port +readCustomPort() { + if [[ -n "${configPath}" ]]; then + local port= + port=$(jq -r .inbounds[0].port "${configPath}${frontingType}.json") + if [[ "${port}" != "443" ]]; then + customPort=${port} + fi + fi +} +# Check the installation method readInstallType() { coreInstallType= configPath= + hysteriaConfigPath= - # 1.Detection installation directory + # 1.Detect the installation directory if [[ -d "/etc/v2ray-agent" ]]; then - # Detection installation method v2ray-core + # Detect installation method v2ray-core if [[ -d "/etc/v2ray-agent/v2ray" && -f "/etc/v2ray-agent/v2ray/v2ray" && -f "/etc/v2ray-agent/v2ray/v2ctl" ]]; then if [[ -d "/etc/v2ray-agent/v2ray/conf" && -f "/etc/v2ray-agent/v2ray/conf/02_VLESS_TCP_inbounds.json" ]]; then configPath=/etc/v2ray-agent/v2ray/conf/ - - if ! grep /dev/null | grep -q "active (exited)"; then + local updateFirewalldStatus= + if ! iptables -L | grep -q "$1(mack-a)"; then + updateFirewalldStatus=true + iptables -I INPUT -p tcp --dport "$1" -m comment --comment "allow $1(mack-a)" -j ACCEPT + fi + + if echo "${updateFirewalldStatus}" | grep -q "true"; then + netfilter-persistent save + fi + elif systemctl status ufw 2>/dev/null | grep -q "active (exited)"; then + if ufw status | grep -q "Status: active"; then + if ! ufw status | grep -q "$1"; then + sudo ufw allow "$1" + checkUFWAllowPort "$1" + fi + fi + + elif + systemctl status firewalld 2>/dev/null | grep -q "active (running)" + then + local updateFirewalldStatus= + if ! firewall-cmd --list-ports --permanent | grep -qw "$1/tcp"; then + updateFirewalldStatus=true + firewall-cmd --zone=public --add-port="$1/tcp" --permanent + checkFirewalldAllowPort "$1" + fi + + if echo "${updateFirewalldStatus}" | grep -q "true"; then + firewall-cmd --reload + fi + fi +} + +# Check the occupancy of ports 80 and 443 +checkPortUsedStatus() { + if lsof -i tcp:80 | grep -q LISTEN; then + echoContent red "\n ---> Port 80 is occupied, please close it manually and install\n" + lsof -i tcp:80 | grep LISTEN + exit 0 + fi + + if lsof -i tcp:443 | grep -q LISTEN; then + echoContent red "\n ---> Port 443 is occupied, please close it manually and install\n" + lsof -i tcp:80 | grep LISTEN + exit 0 + fi +} + +# output ufw port open status +checkUFWAllowPort() { + if ufw status | grep -q "$1"; then + echoContent green "---> $1 port opened successfully" + else + echoContent red "---> $1 port opening failed" + exit 0 + fi +} - done < <(ls ${configPath} | grep inbounds.json | awk -F "[.]" '{print $1}') +# Output firewall-cmd port open status +checkFirewalldAllowPort() { + if firewall-cmd --list-ports --permanent | grep -q "$1"; then + echoContent green "---> $1 port opened successfully" + else + echoContent red "---> $1 port opening failed" + exit 0 + fi } -# Check file directory and path path +# Read the hysteria network environment +readHysteriaConfig() { + if [[ -n "${hysteriaConfigPath}" ]]; then + hysteriaLag=$(jq -r .hysteriaLag <"${hysteriaConfigPath}client_network.json") + hysteriaClientDownloadSpeed=$(jq -r .hysteriaClientDownloadSpeed <"${hysteriaConfigPath}client_network.json") + hysteriaClientUploadSpeed=$(jq -r .hysteriaClientUploadSpeed <"${hysteriaConfigPath}client_network.json") + hysteriaPort=$(jq -r .listen <"${hysteriaConfigPath}config.json" | awk -F "[:]" '{print $2}') + hysteriaProtocol=$(jq -r .protocol <"${hysteriaConfigPath}config.json") + fi +} +# Check the file directory and path path readConfigHostPathUUID() { currentPath= + currentDefaultPort= currentUUID= currentHost= currentPort= currentAdd= - # 读取path + # read path if [[ -n "${configPath}" ]]; then - local fallback=$(jq -r -c '.inbounds[0].settings.fallbacks[]|select(.path)' ${configPath}${frontingType}.json|head -1) + local fallback + fallback=$(jq -r -c '.inbounds[0].settings.fallbacks[]|select(.path)' ${configPath}${frontingType}.json | head -1) - local path=$(echo "${fallback}"|jq -r .path|awk -F "[/]" '{print $2}') + local path + path=$(echo "${fallback}" | jq -r .path | awk -F "[/]" '{print $2}') - if [[ $(echo "${fallback}"|jq -r .dest) == 31297 ]]; then + if [[ $(echo "${fallback}" | jq -r .dest) == 31297 ]]; then currentPath=$(echo "${path}" | awk -F "[w][s]" '{print $1}') - elif [[ $(echo "${fallback}"|jq -r .dest) == 31298 ]]; then + elif [[ $(echo "${fallback}" | jq -r .dest) == 31298 ]]; then currentPath=$(echo "${path}" | awk -F "[t][c][p]" '{print $1}') - elif [[ $(echo "${fallback}"|jq -r .dest) == 31299 ]]; then + elif [[ $(echo "${fallback}" | jq -r .dest) == 31299 ]]; then currentPath=$(echo "${path}" | awk -F "[v][w][s]" '{print $1}') fi - fi + # try to read alpn h2 Path + + if [[ -z "${currentPath}" ]]; then + dest=$(jq -r -c '.inbounds[0].settings.fallbacks[]|select(.alpn)|.dest' ${configPath}${frontingType}.json | head -1) + if [[ "${dest}" == "31302" || "${dest}" == "31304" ]]; then + + if grep -q "trojangrpc {" <${nginxConfigPath}alone.conf; then + currentPath=$(grep "trojangrpc {" <${nginxConfigPath}alone.conf | awk -F "[/]" '{print $2}' | awk -F "[t][r][o][j][a][n]" '{print $1}') + elif grep -q "grpc {" <${nginxConfigPath}alone.conf; then + currentPath=$(grep "grpc {" <${nginxConfigPath}alone.conf | head -1 | awk -F "[/]" '{print $2}' | awk -F "[g][r][p][c]" '{print $1}') + fi + fi + fi + + local defaultPortFile= + defaultPortFile=$(find ${configPath}* | grep "default") + if [[ -n "${defaultPortFile}" ]]; then + currentDefaultPort=$(echo "${defaultPortFile}" | awk -F [_] '{print $4}') + else + currentDefaultPort=$(jq -r .inbounds[0].port ${configPath}${frontingType}.json) + fi + + fi if [[ "${coreInstallType}" == "1" ]]; then currentHost=$(jq -r .inbounds[0].streamSettings.xtlsSettings.certificates[0].certificateFile ${configPath}${frontingType}.json | awk -F '[t][l][s][/]' '{print $2}' | awk -F '[.][c][r][t]' '{print $1}') currentUUID=$(jq -r .inbounds[0].settings.clients[0].id ${configPath}${frontingType}.json) currentAdd=$(jq -r .inbounds[0].settings.clients[0].add ${configPath}${frontingType}.json) - if [[ "${currentAdd}" == "null" ]];then + if [[ "${currentAdd}" == "null" ]]; then currentAdd=${currentHost} fi currentPort=$(jq .inbounds[0].port ${configPath}${frontingType}.json) elif [[ "${coreInstallType}" == "2" || "${coreInstallType}" == "3" ]]; then if [[ "${coreInstallType}" == "3" ]]; then + currentHost=$(jq -r .inbounds[0].streamSettings.xtlsSettings.certificates[0].certificateFile ${configPath}${frontingType}.json | awk -F '[t][l][s][/]' '{print $2}' | awk -F '[.][c][r][t]' '{print $1}') else currentHost=$(jq -r .inbounds[0].streamSettings.tlsSettings.certificates[0].certificateFile ${configPath}${frontingType}.json | awk -F '[t][l][s][/]' '{print $2}' | awk -F '[.][c][r][t]' '{print $1}') fi currentAdd=$(jq -r .inbounds[0].settings.clients[0].add ${configPath}${frontingType}.json) - if [[ "${currentAdd}" == "null" ]];then + if [[ "${currentAdd}" == "null" ]]; then currentAdd=${currentHost} fi currentUUID=$(jq -r .inbounds[0].settings.clients[0].id ${configPath}${frontingType}.json) @@ -303,28 +506,28 @@ readConfigHostPathUUID() { fi } -# Status display +# status display showInstallStatus() { if [[ -n "${coreInstallType}" ]]; then if [[ "${coreInstallType}" == 1 ]]; then if [[ -n $(pgrep -f xray/xray) ]]; then - echoContent yellow "\n core: xray-core[Run in operation]" + echoContent yellow "\nCore: Xray-core [running]" else - echoContent yellow "\n core: xray-core[Not running]" + echoContent yellow "\nCore: Xray-core[not running]" fi elif [[ "${coreInstallType}" == 2 || "${coreInstallType}" == 3 ]]; then if [[ -n $(pgrep -f v2ray/v2ray) ]]; then - echoContent yellow "\n core: v2ray-core[Run in operation]" + echoContent yellow "\nCore: v2ray-core[running]" else - echoContent yellow "\n core: v2ray-core[Not running]" + echoContent yellow "\nCore: v2ray-core[not running]" fi fi - # Read protocol type + # read protocol type readInstallProtocolType if [[ -n ${currentInstallProtocolType} ]]; then - echoContent yellow "Installed protocol:\c" + echoContent yellow "Protocol installed: \c" fi if echo ${currentInstallProtocolType} | grep -q 0; then if [[ "${coreInstallType}" == 2 ]]; then @@ -362,7 +565,7 @@ showInstallStatus() { fi } -# Clean up old residue +# clean up old residue cleanUp() { if [[ "$1" == "v2rayClean" ]]; then rm -rf "$(find /etc/v2ray-agent/v2ray/* | grep -E '(config_full.json|conf)')" @@ -381,32 +584,36 @@ cleanUp() { fi } -initVar $1 +initVar "$1" checkSystem checkCPUVendor readInstallType readInstallProtocolType readConfigHostPathUUID +readInstallAlpn +readCustomPort +checkBTPanel +#---------------------------------------------------- -# ------------------------------------------------------------- - -# Initialization installation directory +# Initialize the installation directory mkdirTools() { mkdir -p /etc/v2ray-agent/tls mkdir -p /etc/v2ray-agent/subscribe mkdir -p /etc/v2ray-agent/subscribe_tmp mkdir -p /etc/v2ray-agent/v2ray/conf + mkdir -p /etc/v2ray-agent/v2ray/tmp mkdir -p /etc/v2ray-agent/xray/conf + mkdir -p /etc/v2ray-agent/xray/tmp mkdir -p /etc/v2ray-agent/trojan + mkdir -p /etc/v2ray-agent/hysteria/conf mkdir -p /etc/systemd/system/ mkdir -p /tmp/v2ray-agent-tls/ } -# Installation kit +# install toolkit installTools() { - echo 'Installation tool' - echoContent skyBlue "\n progress $1/${totalProgress} : Installation tool" - # Repair Ubuntu Individual System Issues + echoContent skyBlue "\nProgress $1/${totalProgress} : Install Tool" + # Fix ubuntu individual system issues if [[ "${release}" == "ubuntu" ]]; then dpkg --configure -a fi @@ -415,9 +622,13 @@ installTools() { pgrep -f apt | xargs kill -9 fi - echoContent green " ---> Check, installation update [new machine will be very slow, if there is no response for a long time, please re-execute it manually]" + echoContent green " ---> Check and install updates [The new machine will be very slow, if there is no response for a long time, please stop it manually and execute it again]" + + ${upgrade} >/etc/v2ray-agent/install.log 2>&1 + if grep <"/etc/v2ray-agent/install.log" -q "changed"; then + ${updateReleaseInfoChange} >/dev/null 2>&1 + fi - ${upgrade} >/dev/null 2>&1 if [[ "${release}" == "centos" ]]; then rm -rf /var/run/yum.pid ${installType} epel-release >/dev/null 2>&1 @@ -426,32 +637,32 @@ installTools() { # [[ -z `find /usr/bin /usr/sbin |grep -v grep|grep -w curl` ]] if ! find /usr/bin /usr/sbin | grep -q -w wget; then - echoContent green " ---> Install wget" + echoContent green " ---> install wget" ${installType} wget >/dev/null 2>&1 fi if ! find /usr/bin /usr/sbin | grep -q -w curl; then - echoContent green " ---> Install CURL" + echoContent green " ---> install curl" ${installType} curl >/dev/null 2>&1 fi if ! find /usr/bin /usr/sbin | grep -q -w unzip; then - echoContent green " ---> Install unzip" + echoContent green " ---> install unzip" ${installType} unzip >/dev/null 2>&1 fi if ! find /usr/bin /usr/sbin | grep -q -w socat; then - echoContent green " ---> Install SOCAT" + echoContent green " ---> install socat" ${installType} socat >/dev/null 2>&1 fi if ! find /usr/bin /usr/sbin | grep -q -w tar; then - echoContent green " ---> Install tar" + echoContent green " ---> install tar" ${installType} tar >/dev/null 2>&1 fi if ! find /usr/bin /usr/sbin | grep -q -w cron; then - echoContent green " ---> Install crontabs" + echoContent green " ---> install crontabs" if [[ "${release}" == "ubuntu" ]] || [[ "${release}" == "debian" ]]; then ${installType} cron >/dev/null 2>&1 else @@ -459,49 +670,63 @@ installTools() { fi fi if ! find /usr/bin /usr/sbin | grep -q -w jq; then - echoContent green " ---> Install JQ" + echoContent green " ---> install jq" ${installType} jq >/dev/null 2>&1 fi if ! find /usr/bin /usr/sbin | grep -q -w binutils; then - echoContent green " ---> Install binutils" + echoContent green " ---> install binutils" ${installType} binutils >/dev/null 2>&1 fi if ! find /usr/bin /usr/sbin | grep -q -w ping6; then - echoContent green " ---> Install PING6" + echoContent green " ---> install ping6" ${installType} inetutils-ping >/dev/null 2>&1 fi if ! find /usr/bin /usr/sbin | grep -q -w qrencode; then - echoContent green " ---> Install QRencode" + echoContent green " ---> install qrencode" ${installType} qrencode >/dev/null 2>&1 fi - if ! find /usr/bin /usr/sbin | grep -q -w sudo; then - echoContent green " ---> Cheap Sudo" + if ! find /usr/bin /usr/sbin | grep -q -w sudo; then + echoContent green " ---> install sudo" ${installType} sudo >/dev/null 2>&1 fi if ! find /usr/bin /usr/sbin | grep -q -w lsb-release; then - echoContent green " ---> Install LSB-RELEASE" + echoContent green " ---> install lsb-release" ${installType} lsb-release >/dev/null 2>&1 fi - # Detect the NGINX version and provide options to be uninstalled + if ! find /usr/bin /usr/sbin | grep -q -w lsof; then + echoContent green " ---> install lsof" + ${installType} lsof >/dev/null 2>&1 + fi + + if ! find /usr/bin /usr/sbin | grep -q -w dig; then + echoContent green " ---> install dig" + if echo "${installType}" | grep -q -w "apt"; then + ${installType} dnsutils >/dev/null 2>&1 + elif echo "${installType}" | grep -q -w "yum"; then + ${installType} bind-utils >/dev/null 2>&1 + fi + fi + + # Detect the nginx version and provide the option to uninstall if ! find /usr/bin /usr/sbin | grep -q -w nginx; then - echoContent green " ---> Install nginx" + echoContent green " ---> install nginx" installNginxTools else nginxVersion=$(nginx -v 2>&1) nginxVersion=$(echo "${nginxVersion}" | awk -F "[n][g][i][n][x][/]" '{print $2}' | awk -F "[.]" '{print $2}') if [[ ${nginxVersion} -lt 14 ]]; then - read -r -p "Reading to the current NGINX version does not support GRPC, resulting in failure, whether to uninstall NGINX, reinstall ?[y/n]:" unInstallNginxStatus + read -r -p "Read that the current Nginx version does not support gRPC, which will cause the installation to fail.Do you want to uninstall Nginx and then reinstall it? [y/n]:" unInstallNginxStatus if [[ "${unInstallNginxStatus}" == "y" ]]; then ${removeType} nginx >/dev/null 2>&1 - echoContent yellow " ---> Nginx uninstalled completion" - echoContent green " ---> Install nginx" + echoContent yellow " ---> nginx uninstallation completed" + echoContent green " ---> install nginx" installNginxTools >/dev/null 2>&1 else exit 0 @@ -509,7 +734,7 @@ installTools() { fi fi if ! find /usr/bin /usr/sbin | grep -q -w semanage; then - echoContent green " ---> Install semanage" + echoContent green " ---> install semanage" ${installType} bash-completion >/dev/null 2>&1 if [[ "${centosVersion}" == "7" ]]; then @@ -528,20 +753,23 @@ installTools() { fi if [[ ! -d "$HOME/.acme.sh" ]] || [[ -d "$HOME/.acme.sh" && -z $(find "$HOME/.acme.sh/acme.sh") ]]; then - echoContent green " ---> Install acme.sh" - curl -s https://get.acme.sh | sh -s >/etc/v2ray-agent/tls/acme.log 2>&1 + echoContent green " ---> install acme.sh" + curl -s https://get.acme.sh | sh >/etc/v2ray-agent/tls/acme.log 2>&1 + if [[ ! -d "$HOME/.acme.sh" ]] || [[ -z $(find "$HOME/.acme.sh/acme.sh") ]]; then - echoContent red " acme installation failed--->" + echoContent red "acme installation failed--->" tail -n 100 /etc/v2ray-agent/tls/acme.log - echoContent yellow "Error investigation:" - echoContent red " 1.Get the github file failed, please wait for Gitub to restore, try, recover progress to view [https://www.githubstatus.com/]" - echoContent red " 2.acme.the sh script has bugs, you can view[https://github.com/acmesh-official/acme.sh] issues" + echoContent yellow "Error troubleshooting:" + echoContent red " 1.Failed to obtain Github files, please wait for Github to recover and try, the recovery progress can be viewed at [https://www.githubstatus.com/]" + echoContent red "There is a bug in the 2.acme.sh script, see [https://github.com/acmesh-official/acme.sh] issues" + echoContent red " 3.For pure IPv6 machines, please set up NAT64 and execute the following commands" + echoContent skyBlue " echo -e \"nameserver 2001:67c:2b0::4\\\nnameserver 2001:67c:2b0::6\" >> /etc/resolv.conf" exit 0 fi fi } -# Install nginx +# Install Nginx installNginxTools() { if [[ "${release}" == "debian" ]]; then @@ -588,9 +816,9 @@ EOF systemctl enable nginx } -# Install WARP -installWarp(){ - ${installType} gnupg2 -y >/dev/null 2>&1 +# install warp +installWarp() { + ${installType} gnupg2 -y >/dev/null 2>&1 if [[ "${release}" == "debian" ]]; then curl -s https://pkg.cloudflareclient.com/pubkey.gpg | sudo apt-key add - >/dev/null 2>&1 echo "deb http://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list >/dev/null 2>&1 @@ -603,57 +831,66 @@ installWarp(){ elif [[ "${release}" == "centos" ]]; then ${installType} yum-utils >/dev/null 2>&1 - sudo rpm -ivh http://pkg.cloudflareclient.com/cloudflare-release-el${centosVersion}.rpm >/dev/null 2>&1 + sudo rpm -ivh "http://pkg.cloudflareclient.com/cloudflare-release-el${centosVersion}.rpm" >/dev/null 2>&1 fi - echoContent green " ---> Install WARP" + echoContent green " ---> install WARP" ${installType} cloudflare-warp >/dev/null 2>&1 - if [[ -z $(which warp-cli) ]];then - echoContent red " ---> Install WARP failed" - exit 0; + if [[ -z $(which warp-cli) ]]; then + echoContent red "---> Failed to install WARP" + exit 0 fi systemctl enable warp-svc warp-cli --accept-tos register warp-cli --accept-tos set-mode proxy warp-cli --accept-tos set-proxy-port 31303 warp-cli --accept-tos connect -# if [[]];then -# fi - # todo curl --socks5 127.0.0.1:31303 https://www.cloudflare.com/cdn-cgi/trace + warp-cli --accept-tos enable-always-on + + # if [[]];then + # fi + # todo curl --socks5 127.0.0.1:31303 https://www.cloudflare.com/cdn-cgi/trace # systemctl daemon-reload # systemctl enable cloudflare-warp } -# Initialization Nginx application certificate configuration +# Initialize Nginx application certificate configuration initTLSNginxConfig() { handleNginx stop - echoContent skyBlue "\n progress $1/${totalProgress} : Initialization Nginx application certificate configuration" + echoContent skyBlue "\nProgress $1/${totalProgress} : Initialize Nginx application certificate configuration" if [[ -n "${currentHost}" ]]; then echo - read -r -p "Read it to the last installation record, whether the domain name when the last installation is used ?[y/n]:" historyDomainStatus + read -r -p "Read the last installation record, do you use the domain name of the last installation? [y/n]:" historyDomainStatus if [[ "${historyDomainStatus}" == "y" ]]; then domain=${currentHost} - echoContent yellow "\n ---> domain name:${domain}" + echoContent yellow "\n ---> Domain name: ${domain}" else echo - echoContent yellow "Please enter the domain name to configure:www.v2ray-agent.com --->" + echoContent yellow "Please enter the domain name to be configured Example: www.v2ray-agent.com --->" read -r -p "domain name:" domain fi else echo - echoContent yellow "Please enter the domain name you want to configure example:www.v2ray-agent.com --->" + echoContent yellow "Please enter the domain name to be configured Example: www.v2ray-agent.com --->" read -r -p "domain name:" domain fi if [[ -z ${domain} ]]; then - echoContent red " Domain name--->" - initTLSNginxConfig + echoContent red "The domain name cannot be empty--->" + initTLSNginxConfig 3 else - # update config - touch /etc/nginx/conf.d/alone.conf - cat </etc/nginx/conf.d/alone.conf + dnsTLSDomain=$(echo "${domain}" | awk -F "[.]" '{print $(NF-1)"."$NF}') + customPortFunction + local port=80 + if [[ -n "${customPort}" ]]; then + port=${customPort} + fi + + # Change setting + touch ${nginxConfigPath}alone.conf + cat <${nginxConfigPath}alone.conf server { - listen 80; - listen [::]:80; + listen ${port}; + listen [::]:${port}; server_name ${domain}; root /usr/share/nginx/html; location ~ /.well-known { @@ -672,22 +909,42 @@ server { } } EOF - # start nginx - handleNginx start - checkIP fi + + readAcmeTLS } -# Modify NGINX redirection configuration +# Modify nginx redirect configuration updateRedirectNginxConf() { - cat </etc/nginx/conf.d/alone.conf + # if [[ ${BTPanelStatus} == "true" ]]; then + # + # cat <${nginxConfigPath}alone.conf + # server { + # listen 127.0.0.1:31300; + # server_name _; + # return 403; + # } + #EOF + # + # elif [[ -n "${customPort}" ]]; then + # cat <${nginxConfigPath}alone.conf + # server { + # listen 127.0.0.1:31300; + # server_name _; + # return 403; + # } + #EOF + # fi + local redirectDomain=${domain} + if [[ -n "${customPort}" ]]; then + redirectDomain=${domain}:${customPort} + fi + cat <${nginxConfigPath}alone.conf server { listen 80; - listen [::]:80; server_name ${domain}; - # shellcheck disable=SC2154 - return 301 https://${domain}$request_uri; + return 302 https://${redirectDomain}; } server { listen 127.0.0.1:31300; @@ -695,45 +952,51 @@ server { return 403; } EOF -if [[ -n $(echo "${selectCustomInstallType}" |grep 2) && -n $(echo "${selectCustomInstallType}" |grep 5) ]] || [[ -z "${selectCustomInstallType}" ]];then - cat <>/etc/nginx/conf.d/alone.conf + if echo "${selectCustomInstallType}" | grep -q 2 && echo "${selectCustomInstallType}" | grep -q 5 || [[ -z "${selectCustomInstallType}" ]]; then + + cat <>${nginxConfigPath}alone.conf server { - listen 127.0.0.1:31302 http2; + listen 127.0.0.1:31302 http2 so_keepalive=on; server_name ${domain}; root /usr/share/nginx/html; + + client_header_timeout 1071906480m; + keepalive_timeout 1071906480m; + location /s/ { - add_header Content-Type text/plain; - alias /etc/v2ray-agent/subscribe/; + add_header Content-Type text/plain; + alias /etc/v2ray-agent/subscribe/; } location /${currentPath}grpc { - client_max_body_size 0; -# keepalive_time 1071906480m; - keepalive_requests 4294967296; + if (\$content_type !~ "application/grpc") { + return 404; + } + client_max_body_size 0; + grpc_set_header X-Real-IP \$proxy_add_x_forwarded_for; client_body_timeout 1071906480m; - send_timeout 1071906480m; - lingering_close always; - grpc_read_timeout 1071906480m; - grpc_send_timeout 1071906480m; + grpc_read_timeout 1071906480m; grpc_pass grpc://127.0.0.1:31301; } location /${currentPath}trojangrpc { - client_max_body_size 0; - # keepalive_time 1071906480m; - keepalive_requests 4294967296; + if (\$content_type !~ "application/grpc") { + return 404; + } + client_max_body_size 0; + grpc_set_header X-Real-IP \$proxy_add_x_forwarded_for; client_body_timeout 1071906480m; - send_timeout 1071906480m; - lingering_close always; - grpc_read_timeout 1071906480m; - grpc_send_timeout 1071906480m; + grpc_read_timeout 1071906480m; grpc_pass grpc://127.0.0.1:31304; } + location / { + add_header Strict-Transport-Security "max-age=15552000; preload" always; + } } EOF - elif echo "${selectCustomInstallType}" |grep -q 5 || [[ -z "${selectCustomInstallType}" ]]; then - cat <>/etc/nginx/conf.d/alone.conf + elif echo "${selectCustomInstallType}" | grep -q 5 || [[ -z "${selectCustomInstallType}" ]]; then + cat <>${nginxConfigPath}alone.conf server { listen 127.0.0.1:31302 http2; server_name ${domain}; @@ -756,9 +1019,9 @@ server { } EOF - elif echo "${selectCustomInstallType}" |grep -q 2 || [[ -z "${selectCustomInstallType}" ]];then + elif echo "${selectCustomInstallType}" | grep -q 2 || [[ -z "${selectCustomInstallType}" ]]; then - cat <>/etc/nginx/conf.d/alone.conf + cat <>${nginxConfigPath}alone.conf server { listen 127.0.0.1:31302 http2; server_name ${domain}; @@ -782,7 +1045,7 @@ server { EOF else - cat <>/etc/nginx/conf.d/alone.conf + cat <>${nginxConfigPath}alone.conf server { listen 127.0.0.1:31302 http2; server_name ${domain}; @@ -797,7 +1060,7 @@ server { EOF fi - cat <>/etc/nginx/conf.d/alone.conf + cat <>${nginxConfigPath}alone.conf server { listen 127.0.0.1:31300; server_name ${domain}; @@ -814,100 +1077,300 @@ EOF } -# Check IP +# check ip checkIP() { - echoContent skyBlue "\n ---> Check the domain name IP address" - localIP=$(curl -s -m 2 "${domain}/ip") + echoContent skyBlue "\n ---> Check the domain name ip" + local checkDomain=${domain} + if [[ -n "${customPort}" ]]; then + checkDomain="http://${domain}:${customPort}" + fi + localIP=$(curl -s -m 2 "${checkDomain}/ip") + handleNginx stop - if [[ -z ${localIP} ]] || ! echo "${localIP}"|sed '1{s/[^(]*(//;s/).*//;q}'|grep -q '\.' && ! echo "${localIP}"|sed '1{s/[^(]*(//;s/).*//;q}'|grep -q ':';then - echoContent red "\n ---> The ip of the current domain name is not detected" - echoContent yellow " ---> Please check if the domain name is written correctly" - echoContent yellow " ---> Please check whether the domain name dns resolution is correct" - echoContent yellow " ---> If the resolution is correct, please wait for the dns to take effect, it is expected to take effect within three minutes" - echoContent yellow " ---> If the above settings are correct, please try again after reinstalling the pure system" - if [[ -n ${localIP} ]];then - echoContent yellow " ---> Detecting return value exceptions" + if [[ -z ${localIP} ]] || ! echo "${localIP}" | sed '1{s/[^(]*(//;s/).*//;q}' | grep -q '\.' && ! echo "${localIP}" | sed '1{s/[^(]*(//;s/).*//;q}' | grep -q ':'; then + echoContent red "\n ---> The ip of the current domain name was not detected" + echoContent skyBlue " ---> Please perform the following checks in order" + echoContent yellow " ---> 1.Check whether the domain name is written correctly" + echoContent yellow " ---> 2.Check whether the domain name dns resolution is correct" + echoContent yellow " ---> 3.If the parsing is correct, please wait for dns to take effect, it is expected to take effect within three minutes" + echoContent yellow " ---> 4.If a problem with Nginx startup is reported, please manually start nginx to check the error.If you can't handle it yourself, please file issues" + echoContent yellow " ---> 5.Error log: ${localIP}" + echo + echoContent skyBlue " ---> If the above settings are correct, please reinstall the pure system and try again" + + if [[ -n ${localIP} ]]; then + echoContent yellow " ---> The detection return value is abnormal, it is recommended to manually uninstall nginx and re-execute the script" + fi + local portFirewallPortStatus="443、80" + + if [[ -n "${customPort}" ]]; then + portFirewallPortStatus="${customPort}" + fi + echoContent red " ---> Please check if firewall rules are open ${portFirewallPortStatus}\n" + read -r -p "Do you want to modify the firewall rules by script to open the port ${portFirewallPortStatus}? [y/n]:" allPortFirewallStatus + + if [[ ${allPortFirewallStatus} == "y" ]]; then + if [[ -n "${customPort}" ]]; then + allowPort "${customPort}" + else + allowPort 80 + allowPort 443 + fi + + handleNginx start + checkIP + else + exit 0 + fi + else + if echo "${localIP}" | awk -F "[,]" '{print $2}' | grep -q "." || echo "${localIP}" | awk -F "[,]" '{print $2}' | grep -q ":"; then + echoContent red "\n ---> Multiple IPs detected, please confirm whether to close cloudflare's cloud" + echoContent yellow " ---> After closing the cloud, wait three minutes and try again" + echoContent yellow " ---> The detected ip is as follows: [${localIP}]" + exit 0 + fi + echoContent green " ---> The current domain name ip is: [${localIP}]" + fi + +} +# custom email +customSSLEmail() { + if echo "$1" | grep -q "validate email"; then + read -r -p "Whether to re-enter the email address [y/n]:" sslEmailStatus + if [[ "${sslEmailStatus}" == "y" ]]; then + sed '/ACCOUNT_EMAIL/d' /root/.acme.sh/account.conf >/root/.acme.sh/account.conf_tmp && mv /root/.acme.sh/account.conf_tmp /root/.acme.sh/account.conf + else + exit 0 + fi + fi + + if [[ -d "/root/.acme.sh" && -f "/root/.acme.sh/account.conf" ]]; then + if ! grep -q "ACCOUNT_EMAIL" <"/root/.acme.sh/account.conf" && ! echo "${sslType}" | grep -q "letsencrypt"; then + read -r -p "Please enter email address:" sslEmail + if echo "${sslEmail}" | grep -q "@"; then + echo "ACCOUNT_EMAIL='${sslEmail}'" >>/root/.acme.sh/account.conf + echoContent green " ---> Add successfully" + else + echoContent yellow "Please re-enter the correct email format [example: username@example.com]" + customSSLEmail + fi + fi + fi + +} +# select ssl installation type +switchSSLType() { + if [[ -z "${sslType}" ]]; then + echoContent red "\n==============================================================" + echoContent yellow "1.letsencrypt[default]" + echoContent yellow "2.zerossl" + echoContent yellow "3.buypass[DNS request not supported]" + echoContent red "==============================================================" + read -r -p "Please select [Enter] to use default:" selectSSLType + case ${selectSSLType} in + 1) + sslType="letsencrypt" + ;; + 2) + sslType="zerossl" + ;; + 3) + sslType="buypass" + ;; + *) + sslType="letsencrypt" + ;; + esac + touch /etc/v2ray-agent/tls + echo "${sslType}" >/etc/v2ray-agent/tls/ssl_type + + fi +} + +# Select the acme installation certificate method +selectAcmeInstallSSL() { + local installSSLIPv6= + if echo "${localIP}" | grep -q ":"; then + installSSLIPv6="--listen-v6" + fi + echo + if [[ -n "${customPort}" ]]; then + if [[ "${selectSSLType}" == "3" ]]; then + echoContent red " ---> buypass does not support free wildcard certificates" + echo + exit fi - echoContent red " ---> Please check if the firewall is closed\n" - read -r -p "Whether to turn off the firewall via script?[y/n]:" disableFirewallStatus - if [[ ${disableFirewallStatus} == "y" ]];then - handleFirewall stop + dnsSSLStatus=true + else + read -r -p "Whether to use DNS to apply for certificate [y/n]:" installSSLDNSStatus + if [[ ${installSSLDNStatus} == 'y' ]]; then + dnsSSLStatus=true fi + fi + acmeInstallSSL + + readAcmeTLS +} + +# Install SSL certificate +acmeInstallSSL() { + if [[ "${dnsSSLStatus}" == "true" ]]; then - exit 0; + sudo "$HOME/.acme.sh/acme.sh" --issue -d "*.${dnsTLSDomain}" --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please --standalone -k ec-256 --server "${sslType}" ${installSSLIPv6} 2>&1 | tee -a /etc/v2ray-agent/tls/acme.log >/dev/null + + local txtValue= + txtValue=$(tail -n 10 /etc/v2ray-agent/tls/acme.log | grep "TXT value" | awk -F "'" '{print $2}') + if [[ -n "${txtValue}" ]]; then + echoContent green " ---> Please manually add DNS TXT record" + echoContent yellow " ---> Please refer to this tutorial for adding methods, https://github.com/mack-a/v2ray-agent/blob/master/documents/dns_txt.md" + echoContent green " ---> name:_acme-challenge" + echoContent green " ---> value:${txtValue}" + echoContent yellow " ---> Please wait for 1-2 minutes after the addition is complete" + echo + read -r -p "Whether the addition is complete [y/n]:" addDNSTXTRecordStatus + if [[ "${addDNSTXTRecordStatus}" == "y" ]]; then + local txtAnswer= + txtAnswer=$(dig +nocmd "_acme-challenge.${dnsTLSDomain}" txt +noall +answer | awk -F "[\"]" '{print $2}') + if [[ "${txtAnswer}" == "${txtValue}" ]]; then + echoContent green " ---> TXT record verification passed" + echoContent green "---> Generating certificate" + sudo "$HOME/.acme.sh/acme.sh" --renew -d "*.${dnsTLSDomain}" --yes-I-know-dns-manual-mode-enough-go-ahead-please --ecc --server "${sslType}" ${installSSLIPv6} 2>&1 | tee -a /etc/v2ray-agent/tls/acme.log >/dev/null + else + echoContent red " ---> Authentication failed, please try again after 1-2 minutes" + acmeInstallSSL + fi + else + echoContent red " ---> give up" + exit 0 + fi + fi + else + echoContent green "---> Generating certificate" + sudo "$HOME/.acme.sh/acme.sh" --issue -d "${tlsDomain}" --standalone -k ec-256 --server "${sslType}" ${installSSLIPv6} 2>&1 | tee -a /etc/v2ray-agent/tls/acme.log >/dev/null + fi +} +# custom port +customPortFunction() { + local historyCustomPortStatus= + local showPort= + if [[ -n "${customPort}" || -n "${currentPort}" ]]; then + echo + read -r -p "Read the port of the last installation, do you use the port of the last installation? [y/n]:" historyCustomPortStatus + if [[ "${historyCustomPortStatus}" == "y" ]]; then + showPort="${currentPort}" + if [[ -n "${customPort}" ]]; then + showPort="${customPort}" + fi + echoContent yellow "\n ---> Port: ${showPort}" + fi fi - if echo "${localIP}"|awk -F "[,]" '{print $2}'|grep -q "." || echo "${localIP}"|awk -F "[,]" '{print $2}'|grep -q ":";then - echoContent red "\n ---> Multiple ip detected, please confirm whether to turn off the cloudflare proxy" - echoContent yellow " ---> Close the cloudflare proxy and wait three minutes before retrying" - echoContent yellow " ---> The detected ip is as follows:[${localIP}]" - exit 0; + if [[ "${historyCustomPortStatus}" == "n" ]] && [[ -z "${customPort}" && -z "${currentPort}" ]]; then + echo + echoContent yellow "Please enter the port [default: 443], such as a custom port, only allow the use of DNS to apply for a certificate [enter to use the default]" + read -r -p "port:" customPort + if [[ -n "${customPort}" ]]; then + if ((customPort >= 1 && customPort <= 65535)); then + checkCustomPort + allowPort "${customPort}" + else + echoContent red " ---> Port input error" + exit + fi + else + echoContent yellow "\n ---> Port: 443" + fi fi +} - echoContent green " ---> Current domain ip is:[${localIP}]" +# Check if the port is occupied +checkCustomPort() { + if lsof -i "tcp:${customPort}" | grep -q LISTEN; then + echoContent red "\n ---> ${customPort} port is occupied, please close it manually and install it\n" + lsof -i tcp:80 | grep LISTEN + exit 0 + fi } -# Install TLS + +# install TLS installTLS() { - echoContent skyBlue "\n progress $1/${totalProgress} : Apply for a TLS certificate\n" + echoContent skyBlue "\nProgress $1/${totalProgress} : Apply for TLS certificate\n" local tlsDomain=${domain} - # Install TLS + + # install tls if [[ -f "/etc/v2ray-agent/tls/${tlsDomain}.crt" && -f "/etc/v2ray-agent/tls/${tlsDomain}.key" && -n $(cat "/etc/v2ray-agent/tls/${tlsDomain}.crt") ]] || [[ -d "$HOME/.acme.sh/${tlsDomain}_ecc" && -f "$HOME/.acme.sh/${tlsDomain}_ecc/${tlsDomain}.key" && -f "$HOME/.acme.sh/${tlsDomain}_ecc/${tlsDomain}.cer" ]]; then - # Have a certificate - echoContent green " ---> Certificate" - checkTLStatus "${tlsDomain}" - if [[ "${tlsStatus}" == "expired" ]]; then - rm -rf $HOME/.acme.sh/${tlsDomain}_ecc/* - rm -rf /etc/v2ray-agent/tls/${tlsDomain}* - installTLS "$1" - else - echoContent green " ---> Certificate is valid" + echoContent green " ---> Certificate detected" + # checkTLStatus + renewalTLS - if ! ls /etc/v2ray-agent/tls/ | grep -q "${tlsDomain}.crt" || ! ls /etc/v2ray-agent/tls/ | grep -q "${tlsDomain}.key" || [[ -z $(cat "/etc/v2ray-agent/tls/${tlsDomain}.crt") ]]; then - sudo "$HOME/.acme.sh/acme.sh" --installcert -d "${tlsDomain}" --fullchainpath "/etc/v2ray-agent/tls/${tlsDomain}.crt" --keypath "/etc/v2ray-agent/tls/${tlsDomain}.key" --ecc >/dev/null - else - echoContent yellow " ---> If you have not expired, please choose[n]\n" - read -r -p "Do you reinstall?[y/n]:" reInstallStatus - if [[ "${reInstallStatus}" == "y" ]]; then - rm -rf /etc/v2ray-agent/tls/* - installTLS "$1" - fi + if [[ -z $(find /etc/v2ray-agent/tls/ -name "${tlsDomain}.crt") ]] || [[ -z $(find /etc/v2ray-agent/tls/ -name "${tlsDomain}.key") ]] || [[ -z $(cat "/etc/v2ray-agent/tls/${tlsDomain}.crt") ]]; then + sudo "$HOME/.acme.sh/acme.sh" --installcert -d "${tlsDomain}" --fullchainpath "/etc/v2ray-agent/tls/${tlsDomain}.crt" --keypath "/etc/v2ray-agent/tls/${tlsDomain}.key" --ecc >/dev/null + else + echoContent yellow " ---> If not expired or custom certificate, please select [n]\n" + read -r -p "Reinstall? [y/n]:" reInstallStatus + if [[ "${reInstallStatus}" == "y" ]]; then + rm -rf /etc/v2ray-agent/tls/* + installTLS "$1" fi fi + elif [[ -d "$HOME/.acme.sh" ]] && [[ ! -f "$HOME/.acme.sh/${tlsDomain}_ecc/${tlsDomain}.cer" || ! -f "$HOME/.acme.sh/${tlsDomain}_ecc/${tlsDomain}.key" ]]; then echoContent green " ---> Install TLS certificate" - if [[ -n "${pingIPv6}" ]]; then - sudo "$HOME/.acme.sh/acme.sh" --issue -d "${tlsDomain}" --standalone -k ec-256 --server letsencrypt --listen-v6 >> /etc/v2ray-agent/tls/acme.log + + if [[ "${installDNSACMEStatus}" != "true" ]]; then + switchSSLType + customSSLEmail + selectAcmeInstallSSL else - sudo "$HOME/.acme.sh/acme.sh" --issue -d "${tlsDomain}" --standalone -k ec-256 --server letsencrypt >> /etc/v2ray-agent/tls/acme.log + echoContent green " ---> Detected that a wildcard certificate has been installed, automatically generating" fi - if [[ -d "$HOME/.acme.sh/${tlsDomain}_ecc" && -f "$HOME/.acme.sh/${tlsDomain}_ecc/${tlsDomain}.key" && -f "$HOME/.acme.sh/${tlsDomain}_ecc/${tlsDomain}.cer" ]]; then + if [[ "${installDNSACMEStatus}" == "true" ]]; then + echo + if [[ -d "$HOME/.acme.sh/*.${dnsTLSDomain}_ecc" && -f "$HOME/.acme.sh/*.${dnsTLSDomain}_ecc/*.${dnsTLSDomain}.key" && -f "$HOME/.acme.sh/*.${dnsTLSDomain}_ecc/*.${dnsTLSDomain}.cer" ]]; then + sudo "$HOME/.acme.sh/acme.sh" --installcert -d "${dnsTLSDomain}" -d "*.${dnsTLSDomain}" --fullchainpath "/etc/v2ray-agent/tls/${tlsDomain}.crt" --keypath "/etc/v2ray-agent/tls/${tlsDomain}.key" --ecc >/dev/null + fi + + elif [[ -d "$HOME/.acme.sh/${tlsDomain}_ecc" && -f "$HOME/.acme.sh/${tlsDomain}_ecc/${tlsDomain}.key" && -f "$HOME/.acme.sh/${tlsDomain}_ecc/${tlsDomain}.cer" ]]; then sudo "$HOME/.acme.sh/acme.sh" --installcert -d "${tlsDomain}" --fullchainpath "/etc/v2ray-agent/tls/${tlsDomain}.crt" --keypath "/etc/v2ray-agent/tls/${tlsDomain}.key" --ecc >/dev/null fi - if [[ ! -f "/etc/v2ray-agent/tls/${tlsDomain}.crt" || ! -f "/etc/v2ray-agent/tls/${tlsDomain}.key" ]] || [[ -z $(cat "/etc/v2ray-agent/tls/${tlsDomain}.key") || -z $(cat "/etc/v2ray-agent/tls/${tlsDomain}.crt") ]]; then + if [[ ! -f "/etc/v2ray-agent/tls/${tlsDomain}.crt" || ! -f "/etc/v2ray-agent/tls/${tlsDomain}.key" ]] || [[ -z $(cat "/etc/v2ray-agent/tls/${tlsDomain}.key") || -z $(cat "/etc/v2ray-agent/tls/${tlsDomain}.crt") ]]; then tail -n 10 /etc/v2ray-agent/tls/acme.log - if [[ ${installTLSCount} == "1" ]];then - echoContent red " ---> TLS installation failed, please check acme logs" + if [[ ${installTLSCount} == "1" ]]; then + echoContent red " ---> TLS installation failed, please check the acme log" exit 0 fi - echoContent red " ---> TLS installation failed, check the firewall in" - handleFirewall stop - echoContent yellow " ---> Retry to install the TLS certificate" + installTLSCount=1 - installTLS "$1" + echo + echoContent red "---> TLS installation failed, checking whether ports 80 and 443 are open" + allowPort 80 + allowPort 443 + echoContent yellow " ---> Retry to install TLS certificate" + + if tail -n 10 /etc/v2ray-agent/tls/acme.log | grep -q "Could not validate email address as valid"; then + echoContent red " ---> The mailbox cannot be verified by the SSL manufacturer, please re-enter" + echo + customSSLEmail "validate email" + installTLS "$1" + else + installTLS "$1" + fi + fi - echoContent green " ---> TLS generation success" + + echoContent green "---> TLS generated successfully" else - echoContent yellow " ---> No acme is installed" + echoContent yellow " ---> acme.sh is not installed" exit 0 fi } -# Configure a camouflage blog +# Configure fake blog initNginxConfig() { - echoContent skyBlue "\n progress $1/${totalProgress} : Configuring nginx" + echoContent skyBlue "\nProgress $1/${totalProgress} : configure Nginx" - cat </etc/nginx/conf.d/alone.conf + cat <${nginxConfigPath}alone.conf server { listen 80; listen [::]:80; @@ -919,25 +1382,25 @@ server { EOF } -# customize/Random path +# custom/random path randomPathFunction() { - echoContent skyBlue "\n progress $1/${totalProgress} : Generate a random path" + echoContent skyBlue "\nProgress $1/${totalProgress} : generate random path" if [[ -n "${currentPath}" ]]; then echo - read -r -p "Read to the last installation record, use the PATH path when the last installation is installed ?[y/n]:" historyPathStatus + read -r -p "Read the last installation record, do you use the path of the last installation? [y/n]:" historyPathStatus echo fi if [[ "${historyPathStatus}" == "y" ]]; then customPath=${currentPath} - echoContent green " ---> Successful use\n" + echoContent green " ---> Use successfully\n" else - echoContent yellow "Please enter a custom path[example: alone] path should be without slash. empty means random" + echoContent yellow "Please enter a custom path [example: alone], no slashes required, [enter] random path" read -r -p 'path:' customPath if [[ -z "${customPath}" ]]; then - customPath=$(head -n 50 /dev/urandom | sed 's/[^a-z]//g' | strings -n 4 | tr 'A-Z' 'a-z' | head -1) + customPath=$(head -n 50 /dev/urandom | sed 's/[^a-z]//g' | strings -n 4 | tr '[:upper:]' '[:lower:]' | head -1) currentPath=${customPath:0:4} customPath=${currentPath} else @@ -945,154 +1408,211 @@ randomPathFunction() { fi fi - echoContent yellow "\n path:${currentPath}" + echoContent yellow "\n path:${currentPath}" echoContent skyBlue "\n----------------------------" } -# Nginx camouflage blog +# Nginx Camouflage Blog nginxBlog() { - echoContent skyBlue "\n progress $1/${totalProgress} : Add a camouflage site" + echoContent skyBlue "\nProgress $1/${totalProgress} : Add fake site" if [[ -d "/usr/share/nginx/html" && -f "/usr/share/nginx/html/check" ]]; then echo - read -r -p "Detecting the installation camouflage site, do you need to reinstall?[y/n]:" nginxBlogInstallStatus + read -r -p "Detected installation of fake sites, do you need to reinstall [y/n]:" nginxBlogInstallStatus if [[ "${nginxBlogInstallStatus}" == "y" ]]; then rm -rf /usr/share/nginx/html - randomNum=$((RANDOM%6+1)) + randomNum=$((RANDOM % 6 + 1)) wget -q -P /usr/share/nginx https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${randomNum}.zip >/dev/null unzip -o /usr/share/nginx/html${randomNum}.zip -d /usr/share/nginx/html >/dev/null rm -f /usr/share/nginx/html${randomNum}.zip* - echoContent green " ---> Add a camouflage site successfully" + echoContent green " ---> Add fake site successfully" fi else - randomNum=$((RANDOM%6+1)) + randomNum=$((RANDOM % 6 + 1)) rm -rf /usr/share/nginx/html wget -q -P /usr/share/nginx https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${randomNum}.zip >/dev/null unzip -o /usr/share/nginx/html${randomNum}.zip -d /usr/share/nginx/html >/dev/null rm -f /usr/share/nginx/html${randomNum}.zip* - echoContent green " ---> Add a camouflage site successfully" + echoContent green " ---> Add fake site successfully" fi } -# Operation Nginx + +# Modify http_port_t port +updateSELinuxHTTPPortT() { + + $(find /usr/bin /usr/sbin | grep -w journalctl) -xe >/etc/v2ray-agent/nginx_error.log 2>&1 + + if find /usr/bin /usr/sbin | grep -q -w semanage && find /usr/bin /usr/sbin | grep -q -w getenforce && grep -E "31300|31302" Check if SELinux port is open" + if ! $(find /usr/bin /usr/sbin | grep -w semanage) port -l | grep http_port | grep -q 31300; then + $(find /usr/bin /usr/sbin | grep -w semanage) port -a -t http_port_t -p tcp 31300 + echoContent green " ---> http_port_t 31300 port opened successfully" + fi + + if ! $(find /usr/bin /usr/sbin | grep -w semanage) port -l | grep http_port | grep -q 31302; then + $(find /usr/bin /usr/sbin | grep -w semanage) port -a -t http_port_t -p tcp 31302 + echoContent green " ---> http_port_t 31302 port opened successfully" + fi + handleNginx start + + else + exit 0 + fi +} + +# Operate Nginx handleNginx() { if [[ -z $(pgrep -f "nginx") ]] && [[ "$1" == "start" ]]; then - nginx + systemctl start nginx 2>/etc/v2ray-agent/nginx_error.log + sleep 0.5 - if ! ps -ef | grep -v grep | grep -q nginx; then - echoContent red " ---> Nginx start failed" - echoContent red " ---> Please manually try NGINX, execute the script again" - exit 0 + + if [[ -z $(pgrep -f nginx) ]]; then + echoContent red "---> Nginx failed to start" + echoContent red " ---> Please try to install nginx manually and execute the script again" + + if grep -q "journalctl -xe" Nginx started successfully" fi - elif [[ "$1" == "stop" ]] && [[ -n $(pgrep -f "nginx") ]]; then - nginx -s stop >/dev/null 2>&1 + + elif [[ -n $(pgrep -f "nginx") ]] && [[ "$1" == "stop" ]]; then + systemctl stop nginx sleep 0.5 if [[ -n $(pgrep -f "nginx") ]]; then pgrep -f "nginx" | xargs kill -9 fi + echoContent green "---> Nginx closed successfully" fi } -# Timed task update TLS certificate +# Scheduled task to update tls certificate installCronTLS() { - echoContent skyBlue "\n progress $1/${totalProgress} : Add tls certificate" + echoContent skyBlue "\nProgress $1/${totalProgress} : Add scheduled maintenance certificate" crontab -l >/etc/v2ray-agent/backup_crontab.cron - local historyCrontab=$(sed '/v2ray-agent/d;/acme.sh/d' /etc/v2ray-agent/backup_crontab.cron) + local historyCrontab + historyCrontab=$(sed '/v2ray-agent/d;/acme.sh/d' /etc/v2ray-agent/backup_crontab.cron) echo "${historyCrontab}" >/etc/v2ray-agent/backup_crontab.cron echo "30 1 * * * /bin/bash /etc/v2ray-agent/install.sh RenewTLS >> /etc/v2ray-agent/crontab_tls.log 2>&1" >>/etc/v2ray-agent/backup_crontab.cron crontab /etc/v2ray-agent/backup_crontab.cron - echoContent green "\n ---> Adding tls success" + echoContent green "\n ---> Adding the timing maintenance certificate successfully" } -# Update certificate +# update certificate renewalTLS() { - echoContent skyBlue "\n progress 1/1 : Update certificate" - if [[ -d "$HOME/.acme.sh/${currentHost}_ecc" ]] && [[ -f "$HOME/.acme.sh/${currentHost}_ecc/${currentHost}.key" ]] && [[ -f "$HOME/.acme.sh/${currentHost}_ecc/${currentHost}.cer" ]]; then - modifyTime=$(stat $HOME/.acme.sh/${currentHost}_ecc/${currentHost}.cer | sed -n '7,6p' | awk '{print $2" "$3" "$4" "$5}') + if [[ -n $1 ]]; then + echoContent skyBlue "\nProgress $1/1 : Renew certificate" + fi + readAcmeTLS + local domain=${currentHost} + if [[ -z "${currentHost}" && -n "${tlsDomain}" ]]; then + domain=${tlsDomain} + fi + + if [[ -f "/etc/v2ray-agent/tls/ssl_type" ]]; then + if grep -q "buypass" <"/etc/v2ray-agent/tls/ssl_type"; then + sslRenewalDays=180 + fi + fi + if [[ -d "$HOME/.acme.sh/${domain}_ecc" && -f "$HOME/.acme.sh/${domain}_ecc/${domain}.key" && -f "$HOME/.acme.sh/${domain}_ecc/${domain}.cer" ]] || [[ "${installDNSACMEStatus}" == "true" ]]; then + modifyTime= + + if [[ "${installDNSACMEStatus}" == "true" ]]; then + modifyTime=$(stat "$HOME/.acme.sh/*.${dnsTLSDomain}_ecc/*.${dnsTLSDomain}.cer" | sed -n '7,6p' | awk '{print $2" "$3" "$4" "$5}') + else + modifyTime=$(stat "$HOME/.acme.sh/${domain}_ecc/${domain}.cer" | sed -n '7,6p' | awk '{print $2" "$3" "$4" "$5}') + fi modifyTime=$(date +%s -d "${modifyTime}") currentTime=$(date +%s) - stampDiff=$(expr ${currentTime} - ${modifyTime}) - days=$(expr ${stampDiff} / 86400) - remainingDays=$(expr 90 - ${days}) + ((stampDiff = currentTime - modifyTime)) + ((days = stampDiff / 86400)) + ((remainingDays = sslRenewalDays - days)) + tlsStatus=${remainingDays} if [[ ${remainingDays} -le 0 ]]; then - tlsStatus="expired" + tlsStatus="Expired" fi - echoContent skyBlue " ---> Certificate check dates:$(date "+%F %H:%M:%S")" - echoContent skyBlue " ---> Certificate generation date:$(date -d @"${modifyTime}" +"%F %H:%M:%S")" - echoContent skyBlue " ---> Certificate generation days:${days}" + echoContent skyBlue " ---> Certificate check date: $(date "+%F %H:%M:%S")" + echoContent skyBlue " ---> Certificate generation date: $(date -d @"${modifyTime}" +"%F %H:%M:%S")" + echoContent skyBlue " ---> Certificate generation days: ${days}" echoContent skyBlue " ---> Certificate remaining days:"${tlsStatus} - echoContent skyBlue " ---> Automatic update before the certificate expires, such as update failure, please update manually" + echoContent skyBlue " ---> The certificate will be automatically updated on the last day before the certificate expires.If the update fails, please update it manually" if [[ ${remainingDays} -le 1 ]]; then - echoContent yellow " ---> Regeneration certificate" + echoContent yellow " ---> regenerate certificate" handleNginx stop sudo "$HOME/.acme.sh/acme.sh" --cron --home "$HOME/.acme.sh" - sudo "$HOME/.acme.sh/acme.sh" --installcert -d "${currentHost}" --fullchainpath /etc/v2ray-agent/tls/"${currentHost}.crt" --keypath /etc/v2ray-agent/tls/"${currentHost}.key" --ecc + sudo "$HOME/.acme.sh/acme.sh" --installcert -d "${domain}" --fullchainpath /etc/v2ray-agent/tls/"${domain}.crt" --keypath /etc/v2ray-agent/tls/"${domain}.key" --ecc reloadCore + handleNginx start else - echoContent green " ---> Certificate is valid" + echoContent green " ---> Certificate valid" fi else - echoContent red " ---> Not Installed" + echoContent red "---> not installed" fi } # View the status of the TLS certificate checkTLStatus() { - if [[ -n "$1" ]]; then - if [[ -d "$HOME/.acme.sh/$1_ecc" ]] && [[ -f "$HOME/.acme.sh/$1_ecc/$1.key" ]] && [[ -f "$HOME/.acme.sh/$1_ecc/$1.cer" ]]; then - modifyTime=$(stat $HOME/.acme.sh/$1_ecc/$1.key | sed -n '7,6p' | awk '{print $2" "$3" "$4" "$5}') - - modifyTime=$(date +%s -d "${modifyTime}") - currentTime=$(date +%s) - stampDiff=$(expr ${currentTime} - ${modifyTime}) - days=$(expr ${stampDiff} / 86400) - remainingDays=$(expr 90 - ${days}) - tlsStatus=${remainingDays} - if [[ ${remainingDays} -le 0 ]]; then - tlsStatus="expired" - fi - echoContent skyBlue " ---> Certificate generation date:$(date -d "@${modifyTime}" +"%F %H:%M:%S")" - echoContent skyBlue " ---> Certificate generation days:${days}" - echoContent skyBlue " ---> Certificate remaining days:${tlsStatus}" - fi - fi -} + if [[ -d "$HOME/.acme.sh/${currentHost}_ecc" ]] && [[ -f "$HOME/.acme.sh/${currentHost}_ecc/${currentHost}.key" ]] && [[ -f "$HOME/.acme.sh/${currentHost}_ecc/${currentHost}.cer" ]]; then + modifyTime=$(stat "$HOME/.acme.sh/${currentHost}_ecc/${currentHost}.cer" | sed -n '7,6p' | awk '{print $2" "$3" "$4" "$5}') -# Install v2ray, specify version + modifyTime=$(date +%s -d "${modifyTime}") + currentTime=$(date +%s) + ((stampDiff = currentTime - modifyTime)) + ((days = stampDiff / 86400)) + ((remainingDays = sslRenewalDays - days)) + + tlsStatus=${remainingDays} + if [[ ${remainingDays} -le 0 ]]; then + tlsStatus="Expired" + fi + + echoContent skyBlue " ---> Certificate generation date: $(date -d "@${modifyTime}" +"%F %H:%M:%S")" + echoContent skyBlue " ---> Certificate generation days: ${days}" + echoContent skyBlue " ---> Certificate remaining days: ${tlsStatus}" + fi +} + +# Install V2Ray, specify the version installV2Ray() { readInstallType - echoContent skyBlue "\n progress $1/${totalProgress} : Install v2ray" + echoContent skyBlue "\nProgress $1/${totalProgress} : Install V2Ray" if [[ "${coreInstallType}" != "2" && "${coreInstallType}" != "3" ]]; then if [[ "${selectCoreType}" == "2" ]]; then - version=$(curl -s https://api.github.com/repos/v2fly/v2ray-core/releases | jq -r .[].tag_name|head -1) + version=$(curl -s https://api.github.com/repos/v2fly/v2ray-core/releases | jq -r '.[]|select (.prerelease==false)|.tag_name' | grep -v 'v5' | head -1) else version=${v2rayCoreVersion} fi - echoContent green " ---> v2ray-core version:${version}" + echoContent green " ---> v2ray-core version: ${version}" if wget --help | grep -q show-progress; then wget -c -q --show-progress -P /etc/v2ray-agent/v2ray/ "https://github.com/v2fly/v2ray-core/releases/download/${version}/${v2rayCoreCPUVendor}.zip" else wget -c -P /etc/v2ray-agent/v2ray/ "https://github.com/v2fly/v2ray-core/releases/download/${version}/${v2rayCoreCPUVendor}.zip" >/dev/null 2>&1 fi - unzip -o /etc/v2ray-agent/v2ray/${v2rayCoreCPUVendor}.zip -d /etc/v2ray-agent/v2ray >/dev/null - rm -rf /etc/v2ray-agent/v2ray/${v2rayCoreCPUVendor}.zip + unzip -o "/etc/v2ray-agent/v2ray/${v2rayCoreCPUVendor}.zip" -d /etc/v2ray-agent/v2ray >/dev/null + rm -rf "/etc/v2ray-agent/v2ray/${v2rayCoreCPUVendor}.zip" else if [[ "${selectCoreType}" == "3" ]]; then - echoContent green " ---> lock v2ray-core version is v4.32.1" + echoContent green " ---> lock v2ray-core version to v4.32.1" rm -f /etc/v2ray-agent/v2ray/v2ray rm -f /etc/v2ray-agent/v2ray/v2ctl installV2Ray "$1" else echoContent green " ---> v2ray-core version:$(/etc/v2ray-agent/v2ray/v2ray --version | awk '{print $2}' | head -1)" - read -r -p "Is it updated, upgrade?[y/n]:" reInstallV2RayStatus + read -r -p "Update, upgrade? [y/n]:" reInstallV2RayStatus if [[ "${reInstallV2RayStatus}" == "y" ]]; then rm -f /etc/v2ray-agent/v2ray/v2ray rm -f /etc/v2ray-agent/v2ray/v2ctl @@ -1102,147 +1622,154 @@ installV2Ray() { fi } -# Install XRay -installXray() { +# install hysteria +installHysteria() { readInstallType - echoContent skyBlue "\n progress $1/${totalProgress} : Install XRay" + echoContent skyBlue "\nProgress $1/${totalProgress} : Install Hysteria" - if [[ "${coreInstallType}" != "1" ]]; then + if [[ -z "${hysteriaConfigPath}" ]]; then - version=$(curl -s https://api.github.com/repos/XTLS/Xray-core/releases | jq -r .[].tag_name|head -1) + version=$(curl -s https://api.github.com/repos/HyNetwork/hysteria/releases | jq -r '.[]|select (.prerelease==false)|.tag_name' | head -1) - echoContent green " ---> Xray-core version:${version}" + echoContent green " ---> Hysteria version: ${version}" if wget --help | grep -q show-progress; then - wget -c -q --show-progress -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip" + wget -c -q --show-progress -P /etc/v2ray-agent/hysteria/ "https://github.com/HyNetwork/hysteria/releases/download/${version}/${hysteriaCoreCPUVendor}" else - wget -c -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip" >/dev/null 2>&1 + wget -c -P /etc/v2ray-agent/hysteria/ "https://github.com/HyNetwork/hysteria/releases/download/${version}/${hysteriaCoreCPUVendor}" >/dev/null 2>&1 fi - - unzip -o /etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip -d /etc/v2ray-agent/xray >/dev/null - rm -rf /etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip - chmod 655 /etc/v2ray-agent/xray/xray + mv "/etc/v2ray-agent/hysteria/${hysteriaCoreCPUVendor}" /etc/v2ray-agent/hysteria/hysteria + chmod 655 /etc/v2ray-agent/hysteria/hysteria else - echoContent green " ---> Xray-core version:$(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)" - read -r -p "Is it updated, upgrade?[y/n]:" reInstallXrayStatus - if [[ "${reInstallXrayStatus}" == "y" ]]; then - rm -f /etc/v2ray-agent/xray/xray - installXray "$1" + echoContent green " ---> Hysteria version:$(/etc/v2ray-agent/hysteria/hysteria --version | awk '{print $3}')" + read -r -p "Update, upgrade? [y/n]:" reInstallHysteriaStatus + if [[ "${reInstallHysteriaStatus}" == "y" ]]; then + rm -f /etc/v2ray-agent/hysteria/hysteria + installHysteria "$1" fi fi + } +# install xray +installXray() { + readInstallType + echoContent skyBlue "\nProgress $1/${totalProgress} : Install Xray" -# Install Trojan-go -installTrojanGo() { - echoContent skyBlue "\n progress $1/${totalProgress} : Install Trojan-Go" + if [[ "${coreInstallType}" != "1" ]]; then - if ! ls /etc/v2ray-agent/trojan/ | grep -q trojan-go; then + version=$(curl -s https://api.github.com/repos/XTLS/Xray-core/releases | jq -r '.[]|select (.prerelease==false)|.tag_name' | head -1) - version=$(curl -s https://api.github.com/repos/p4gefau1t/trojan-go/releases | jq -r .[0].tag_name) - echoContent green " ---> Trojan-Go version:${version}" + echoContent green " ---> Xray-core version: ${version}" if wget --help | grep -q show-progress; then - wget -c -q --show-progress -P /etc/v2ray-agent/trojan/ "https://github.com/p4gefau1t/trojan-go/releases/download/${version}/${trojanGoCPUVendor}.zip" + wget -c -q --show-progress -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip" else - wget -c -P /etc/v2ray-agent/trojan/ "https://github.com/p4gefau1t/trojan-go/releases/download/${version}/${trojanGoCPUVendor}.zip" >/dev/null 2>&1 + wget -c -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip" >/dev/null 2>&1 fi - unzip -o /etc/v2ray-agent/trojan/${trojanGoCPUVendor}.zip -d /etc/v2ray-agent/trojan >/dev/null - rm -rf /etc/v2ray-agent/trojan/${trojanGoCPUVendor}.zip - else - echoContent green " ---> Trojan-Go version:$(/etc/v2ray-agent/trojan/trojan-go --version | awk '{print $2}' | head -1)" - read -r -p "Do you reinstall?[y/n]:" reInstallTrojanStatus - if [[ "${reInstallTrojanStatus}" == "y" ]]; then - rm -rf /etc/v2ray-agent/trojan/trojan-go* - installTrojanGo "$1" + unzip -o "/etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip" -d /etc/v2ray-agent/xray >/dev/null + rm -rf "/etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip" + chmod 655 /etc/v2ray-agent/xray/xray + else + echoContent green " ---> Xray-core version:$(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)" + read -r -p "Update, upgrade? [y/n]:" reInstallXrayStatus + if [[ "${reInstallXrayStatus}" == "y" ]]; then + rm -f /etc/v2ray-agent/xray/xray + installXray "$1" fi fi } -# V2Ray version management +# v2ray version management v2rayVersionManageMenu() { - echoContent skyBlue "\n progress $1/${totalProgress} : V2Ray version management" + echoContent skyBlue "\nProgress $1/${totalProgress} : V2Ray version management" if [[ ! -d "/etc/v2ray-agent/v2ray/" ]]; then - echoContent red " ---> No installation directory is detected, please perform script installation content" + echoContent red " ---> No installation directory detected, please execute the script to install the content" menu exit 0 fi echoContent red "\n==============================================================" - echoContent yellow "1.upgrade" - echoContent yellow "2.go back" - echoContent yellow "3.Close V2ray-core" + echoContent yellow "1.Upgrade v2ray-core" + echoContent yellow "2.Fallback v2ray-core" + echoContent yellow "3.Close v2ray-core" echoContent yellow "4.Open v2ray-core" - echoContent yellow "5.Restart V2Ray-core" + echoContent yellow "5.Restart v2ray-core" echoContent red "==============================================================" - read -r -p "please choose:" selectV2RayType + read -r -p "Please select:" selectV2RayType if [[ "${selectV2RayType}" == "1" ]]; then updateV2Ray elif [[ "${selectV2RayType}" == "2" ]]; then - echoContent yellow "\n1.Can only fall back to the most recent version" - echoContent yellow "2.Do not guarantee that you must use it normally after the fallback" - echoContent yellow "3.If the version of the rollback does not support the current config, it will not be able to connect, careful" + echoContent yellow "\n1.Only the last five versions can be rolled back" + echoContent yellow "2.It is not guaranteed that it can be used normally after the rollback" + echoContent yellow "3.If the rolled back version does not support the current config, it will not be able to connect, operate with caution" echoContent skyBlue "------------------------Version-------------------------------" - curl -s https://api.github.com/repos/v2fly/v2ray-core/releases | jq -r .[].tag_name| head -5| awk '{print ""NR""":"$0}' + curl -s https://api.github.com/repos/v2fly/v2ray-core/releases | jq -r '.[]|select (.prerelease==false)|.tag_name' | grep -v 'v5' | head -5 | awk '{print ""NR""":"$0}' echoContent skyBlue "--------------------------------------------------------------" - read -r -p "Please enter the version you want to fall back:" selectV2rayVersionType - version=$(curl -s https://api.github.com/repos/v2fly/v2ray-core/releases | jq -r .[].tag_name| head -5| awk '{print ""NR""":"$0}' | grep "${selectV2rayVersionType}:" | awk -F "[:]" '{print $2}') + read -r -p "Please enter the version to be rolled back:" selectV2rayVersionType + version=$(curl -s https://api.github.com/repos/v2fly/v2ray-core/releases | jq -r '.[]|select (.prerelease==false)|.tag_name' | grep -v 'v5' | head -5 | awk '{print ""NR""":"$0}' | grep "${selectV2rayVersionType}:" | awk -F "[:]" '{print $2}') if [[ -n "${version}" ]]; then - updateV2Ray ${version} + updateV2Ray "${version}" else - echoContent red "\n ---> Enter is incorrect, please re-enter" + echoContent red "\n ---> Input error, please re-enter" v2rayVersionManageMenu 1 fi - elif [[ "${selectXrayType}" == "3" ]]; then + elif [[ "${selectV2RayType}" == "3" ]]; then handleV2Ray stop - elif [[ "${selectXrayType}" == "4" ]]; then + elif [[ "${selectV2RayType}" == "4" ]]; then handleV2Ray start - elif [[ "${selectXrayType}" == "5" ]]; then + elif [[ "${selectV2RayType}" == "5" ]]; then reloadCore fi } -# XRay version management +# xray version management xrayVersionManageMenu() { - echoContent skyBlue "\n progress $1/${totalProgress} : XRay version management" + echoContent skyBlue "\nProgress $1/${totalProgress} : Xray Version Management" if [[ ! -d "/etc/v2ray-agent/xray/" ]]; then - echoContent red " ---> No installation directory is detected, please perform script installation content" + echoContent red " ---> No installation directory detected, please execute the script to install the content" menu exit 0 fi echoContent red "\n==============================================================" - echoContent yellow "1.upgrade" - echoContent yellow "2.go back" - echoContent yellow "3.Close xray-core" - echoContent yellow "4.Open xray-core" - echoContent yellow "5.Restart XRAY-core" + echoContent yellow "1.Upgrade Xray-core" + echoContent yellow "2.Upgrade Xray-core preview version" + echoContent yellow "3.Fallback Xray-core" + echoContent yellow "4.Close Xray-core" + echoContent yellow "5.Open Xray-core" + echoContent yellow "6.Restart Xray-core" echoContent red "==============================================================" - read -r -p "please choose:" selectXrayType + read -r -p "Please select:" selectXrayType if [[ "${selectXrayType}" == "1" ]]; then updateXray elif [[ "${selectXrayType}" == "2" ]]; then - echoContent yellow "\n1.Due to XRay-Core frequently updated, only two recent versions" - echoContent yellow "2.Do not guarantee that you must use it normally after the fallback" - echoContent yellow "3.If the version of the rollback does not support the current config, it will not be able to connect, careful" + + prereleaseStatus=true + updateXray + + elif [[ "${selectXrayType}" == "3" ]]; then + echoContent yellow "\n1.Only the last five versions can be rolled back" + echoContent yellow "2.It is not guaranteed that it can be used normally after the rollback" + echoContent yellow "3.If the rolled back version does not support the current config, it will not be able to connect, operate with caution" echoContent skyBlue "------------------------Version-------------------------------" - curl -s https://api.github.com/repos/XTLS/Xray-core/releases | jq -r .[].tag_name| head -2 | awk '{print ""NR""":"$0}' + curl -s https://api.github.com/repos/XTLS/Xray-core/releases | jq -r '.[]|select (.prerelease==false)|.tag_name' | head -5 | awk '{print ""NR""":"$0}' echoContent skyBlue "--------------------------------------------------------------" - read -r -p "Please enter the version you want to fall back:" selectXrayVersionType - version=$(curl -s https://api.github.com/repos/XTLS/Xray-core/releases | jq -r .[].tag_name| head -2 | awk '{print ""NR""":"$0}' | grep "${selectXrayVersionType}:" | awk -F "[:]" '{print $2}') + read -r -p "Please enter the version to be rolled back:" selectXrayVersionType + version=$(curl -s https://api.github.com/repos/XTLS/Xray-core/releases | jq -r '.[]|select (.prerelease==false)|.tag_name' | head -5 | awk '{print ""NR""":"$0}' | grep "${selectXrayVersionType}:" | awk -F "[:]" '{print $2}') if [[ -n "${version}" ]]; then updateXray "${version}" else - echoContent red "\n ---> Enter is incorrect, please re-enter" + echoContent red "\n ---> Input error, please re-enter" xrayVersionManageMenu 1 fi - elif [[ "${selectXrayType}" == "3" ]]; then - handleXray stop elif [[ "${selectXrayType}" == "4" ]]; then - handleXray start + handleXray stop elif [[ "${selectXrayType}" == "5" ]]; then + handleXray start + elif [[ "${selectXrayType}" == "6" ]]; then reloadCore fi } -# Update V2ray +# Update V2Ray updateV2Ray() { readInstallType if [[ -z "${coreInstallType}" ]]; then @@ -1250,13 +1777,13 @@ updateV2Ray() { if [[ -n "$1" ]]; then version=$1 else - version=$(curl -s https://api.github.com/repos/v2fly/v2ray-core/releases | jq -r .[0].tag_name) + version=$(curl -s https://api.github.com/repos/v2fly/v2ray-core/releases | jq -r '.[]|select (.prerelease==false)|.tag_name' | grep -v 'v5' | head -1) fi - # Use the locked version + # use locked version if [[ -n "${v2rayCoreVersion}" ]]; then version=${v2rayCoreVersion} fi - echoContent green " ---> v2ray-Core version:${version}" + echoContent green " ---> v2ray-core version: ${version}" if wget --help | grep -q show-progress; then wget -c -q --show-progress -P /etc/v2ray-agent/v2ray/ "https://github.com/v2fly/v2ray-core/releases/download/${version}/${v2rayCoreCPUVendor}.zip" @@ -1264,29 +1791,29 @@ updateV2Ray() { wget -c -P "/etc/v2ray-agent/v2ray/ https://github.com/v2fly/v2ray-core/releases/download/${version}/${v2rayCoreCPUVendor}.zip" >/dev/null 2>&1 fi - unzip -o /etc/v2ray-agent/v2ray/${v2rayCoreCPUVendor}.zip -d /etc/v2ray-agent/v2ray >/dev/null - rm -rf /etc/v2ray-agent/v2ray/${v2rayCoreCPUVendor}.zip + unzip -o "/etc/v2ray-agent/v2ray/${v2rayCoreCPUVendor}.zip" -d /etc/v2ray-agent/v2ray >/dev/null + rm -rf "/etc/v2ray-agent/v2ray/${v2rayCoreCPUVendor}.zip" handleV2Ray stop handleV2Ray start else - echoContent green " ---> Current v2ray-Core version:$(/etc/v2ray-agent/v2ray/v2ray --version | awk '{print $2}' | head -1)" + echoContent green " ---> Current v2ray-core version: $(/etc/v2ray-agent/v2ray/v2ray --version | awk '{print $2}' | head -1)" if [[ -n "$1" ]]; then version=$1 else - version=$(curl -s https://api.github.com/repos/v2fly/v2ray-core/releases | jq -r .[0].tag_name) + version=$(curl -s https://api.github.com/repos/v2fly/v2ray-core/releases | jq -r '.[]|select (.prerelease==false)|.tag_name' | grep -v 'v5' | head -1) fi if [[ -n "${v2rayCoreVersion}" ]]; then version=${v2rayCoreVersion} fi if [[ -n "$1" ]]; then - read -r -p "Retreat${version},Whether to continue?[y/n]:" rollbackV2RayStatus + read -r -p "The rollback version is ${version}, do you want to continue? [y/n]:" rollbackV2RayStatus if [[ "${rollbackV2RayStatus}" == "y" ]]; then if [[ "${coreInstallType}" == "2" || "${coreInstallType}" == "3" ]]; then - echoContent green " ---> Current v2ray-Core version:$(/etc/v2ray-agent/v2ray/v2ray --version | awk '{print $2}' | head -1)" + echoContent green " ---> Current v2ray-core version: $(/etc/v2ray-agent/v2ray/v2ray --version | awk '{print $2}' | head -1)" elif [[ "${coreInstallType}" == "1" ]]; then - echoContent green " ---> Current Xray-Core version:$(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)" + echoContent green " ---> Current Xray-core version: $(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)" fi handleV2Ray stop @@ -1294,43 +1821,43 @@ updateV2Ray() { rm -f /etc/v2ray-agent/v2ray/v2ctl updateV2Ray "${version}" else - echoContent green " ---> Abandon the retreat version" + echoContent green " ---> Abort the fallback version" fi elif [[ "${version}" == "v$(/etc/v2ray-agent/v2ray/v2ray --version | awk '{print $2}' | head -1)" ]]; then - read -r -p "The current version is the same as the latest version, is it reinstalled?[y/n]:" reInstallV2RayStatus + read -r -p "The current version is the same as the latest version, do you want to reinstall? [y/n]:" reInstallV2RayStatus if [[ "${reInstallV2RayStatus}" == "y" ]]; then handleV2Ray stop rm -f /etc/v2ray-agent/v2ray/v2ray rm -f /etc/v2ray-agent/v2ray/v2ctl updateV2Ray else - echoContent green " ---> Abandon reinstall" + echoContent green " ---> Abort reinstallation" fi else - read -r -p "The latest version is:${version}Is it updated?[y/n]:" installV2RayStatus + read -r -p "The latest version is: ${version}, update? [y/n]:" installV2RayStatus if [[ "${installV2RayStatus}" == "y" ]]; then rm -f /etc/v2ray-agent/v2ray/v2ray rm -f /etc/v2ray-agent/v2ray/v2ctl updateV2Ray else - echoContent green " ---> Give up update" + echoContent green " ---> Abort update" fi fi fi } -# Update xray +# Update Xray updateXray() { readInstallType if [[ -z "${coreInstallType}" ]]; then if [[ -n "$1" ]]; then version=$1 else - version=$(curl -s https://api.github.com/repos/XTLS/Xray-core/releases | jq -r .[0].tag_name) + version=$(curl -s https://api.github.com/repos/XTLS/Xray-core/releases | jq -r ".[]|select (.prerelease==${prereleaseStatus})|.tag_name" | head -1) fi - echoContent green " ---> Xray-Core version:${version}" + echoContent green " ---> Xray-core version: ${version}" if wget --help | grep -q show-progress; then wget -c -q --show-progress -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip" @@ -1338,48 +1865,48 @@ updateXray() { wget -c -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip" >/dev/null 2>&1 fi - unzip -o /etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip -d /etc/v2ray-agent/xray >/dev/null - rm -rf /etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip + unzip -o "/etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip" -d /etc/v2ray-agent/xray >/dev/null + rm -rf "/etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip" chmod 655 /etc/v2ray-agent/xray/xray handleXray stop handleXray start else - echoContent green " ---> Current Xray-Core version:$(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)" + echoContent green " ---> Current Xray-core version: $(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)" if [[ -n "$1" ]]; then version=$1 else - version=$(curl -s https://api.github.com/repos/XTLS/Xray-core/releases | jq -r .[0].tag_name) + version=$(curl -s https://api.github.com/repos/XTLS/Xray-core/releases | jq -r ".[]|select (.prerelease==${prereleaseStatus})|.tag_name" | head -1) fi if [[ -n "$1" ]]; then - read -r -p "Retreat${version},Whether to continue?[y/n]:" rollbackXrayStatus + read -r -p "The rollback version is ${version}, do you want to continue? [y/n]:" rollbackXrayStatus if [[ "${rollbackXrayStatus}" == "y" ]]; then - echoContent green " ---> Current Xray-Core version:$(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)" + echoContent green " ---> Current Xray-core version: $(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)" handleXray stop rm -f /etc/v2ray-agent/xray/xray updateXray "${version}" else - echoContent green " ---> Abandon the retreat version" + echoContent green " ---> Abort the fallback version" fi elif [[ "${version}" == "v$(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)" ]]; then - read -r -p "The current version is the same as the latest version, is it reinstalled?[y/n]:" reInstallXrayStatus + read -r -p "The current version is the same as the latest version, do you want to reinstall? [y/n]:" reInstallXrayStatus if [[ "${reInstallXrayStatus}" == "y" ]]; then handleXray stop rm -f /etc/v2ray-agent/xray/xray rm -f /etc/v2ray-agent/xray/xray updateXray else - echoContent green " ---> Abandon reinstall" + echoContent green " ---> Abort reinstallation" fi else - read -r -p "The latest version is:${version}Is it updated?[y/n]:" installXrayStatus + read -r -p "The latest version is: ${version}, update? [y/n]:" installXrayStatus if [[ "${installXrayStatus}" == "y" ]]; then rm -f /etc/v2ray-agent/xray/xray updateXray else - echoContent green " ---> Give up update" + echoContent green " ---> Abort update" fi fi @@ -1389,21 +1916,21 @@ updateXray() { # Verify that the entire service is available checkGFWStatue() { readInstallType - echoContent skyBlue "\n progress $1/${totalProgress} : Verify service startup status" + echoContent skyBlue "\nProgress $1/${totalProgress} : Verify service startup status" if [[ "${coreInstallType}" == "1" ]] && [[ -n $(pgrep -f xray/xray) ]]; then - echoContent green " ---> Service starts success" + echoContent green " ---> Service started successfully" elif [[ "${coreInstallType}" == "2" || "${coreInstallType}" == "3" ]] && [[ -n $(pgrep -f v2ray/v2ray) ]]; then - echoContent green " ---> Service starts success" + echoContent green " ---> Service started successfully" else - echoContent red " ---> Service startup failed, please check if the terminal has a log printing" + echoContent red " ---> The service failed to start, please check whether the terminal has log printing" exit 0 fi } -# V2RAY boot +# V2Ray starts automatically installV2RayService() { - echoContent skyBlue "\n progress $1/${totalProgress} : Configuring V2RAY boot" + echoContent skyBlue "\nProgress $1/${totalProgress} : configure V2Ray to start automatically" if [[ -n $(find /bin /usr/bin -name "systemctl") ]]; then rm -rf /etc/systemd/system/v2ray.service touch /etc/systemd/system/v2ray.service @@ -1423,28 +1950,62 @@ NoNewPrivileges=yes ExecStart=${execStart} Restart=on-failure RestartPreventExitStatus=23 - +LimitNPROC=10000 +LimitNOFILE=1000000 [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable v2ray.service - echoContent green " ---> Configuring V2RAY boot self-start" + echoContent green " ---> Configure V2Ray to start automatically after booting successfully" fi } -# XRay boot +# Install hysteria to start automatically +installHysteriaService() { + echoContent skyBlue "\nProgress $1/${totalProgress} : configure Hysteria to start automatically" + if [[ -n $(find /bin /usr/bin -name "systemctl") ]]; then + rm -rf /etc/systemd/system/hysteria.service + touch /etc/systemd/system/hysteria.service + execStart='/etc/v2ray-agent/hysteria/hysteria --log-level info -c /etc/v2ray-agent/hysteria/conf/config.json server' + cat </etc/systemd/system/hysteria.service + [Unit] + Description=Hysteria Service + Documentation=https://github.com/HyNetwork/hysteria/wiki + After=network.target nss-lookup.target + Wants=network-online.target + + [Service] + Type=simple + User=root + CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_NET_RAW + NoNewPrivileges=yes + ExecStart=${execStart} + Restart=on-failure + RestartPreventExitStatus=23 + LimitNPROC=10000 + LimitNOFILE=1000000 + + [Install] + WantedBy=multi-user.target +EOF + systemctl daemon-reload + systemctl enable hysteria.service + echoContent green " ---> Configure Hysteria to boot successfully" + fi +} +# Xray starts automatically at boot installXrayService() { - echoContent skyBlue "\n progress $1/${totalProgress} : Configuring XRAY boot self-start" + echoContent skyBlue "\nProgress $1/${totalProgress} : configure Xray to start automatically" if [[ -n $(find /bin /usr/bin -name "systemctl") ]]; then rm -rf /etc/systemd/system/xray.service touch /etc/systemd/system/xray.service execStart='/etc/v2ray-agent/xray/xray run -confdir /etc/v2ray-agent/xray/conf' cat </etc/systemd/system/xray.service [Unit] -Description=Xray - A unified platform for anti-censorship -# Documentation=https://v2ray.com https://guide.v2fly.org +Description=Xray Service +Documentation=https://github.com/XTLS/Xray-core After=network.target nss-lookup.target Wants=network-online.target @@ -1456,49 +2017,19 @@ NoNewPrivileges=yes ExecStart=${execStart} Restart=on-failure RestartPreventExitStatus=23 - +LimitNPROC=10000 +LimitNOFILE=1000000 [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable xray.service - echoContent green " ---> Configuring XRAY boot self-start" + echoContent green " ---> Configure Xray to boot successfully" fi } -# Trojan boot self-start -installTrojanService() { - echoContent skyBlue "\n progress $1/${totalProgress} : Configuring Trojan boot self-start" - if [[ -n $(find /bin /usr/bin -name "systemctl") ]]; then - rm -rf /etc/systemd/system/trojan-go.service - touch /etc/systemd/system/trojan-go.service - - cat </etc/systemd/system/trojan-go.service -[Unit] -Description=Trojan-Go - A unified platform for anti-censorship -Documentation=Trojan-Go -After=network.target nss-lookup.target -Wants=network-online.target - -[Service] -Type=simple -User=root -CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_NET_RAW -NoNewPrivileges=yes -ExecStart=/etc/v2ray-agent/trojan/trojan-go -config /etc/v2ray-agent/trojan/config_full.json -Restart=on-failure -RestartPreventExitStatus=23 - -[Install] -WantedBy=multi-user.target -EOF - systemctl daemon-reload - systemctl enable trojan-go.service - echoContent green " ---> Configuring Trojan boot self-starting" - fi -} -# Operation v2ray +# Operate V2Ray handleV2Ray() { # shellcheck disable=SC2010 if find /bin /usr/bin | grep -q systemctl && ls /etc/systemd/system/ | grep -q v2ray.service; then @@ -1512,25 +2043,56 @@ handleV2Ray() { if [[ "$1" == "start" ]]; then if [[ -n $(pgrep -f "v2ray/v2ray") ]]; then - echoContent green " ---> V2Ray starts success" + echoContent green " ---> V2Ray started successfully" else - echoContent red "V2Ray starts failed" - echoContent red "Please manually【/etc/v2ray-agent/v2ray/v2ray -confdir /etc/v2ray-agent/v2ray/conf】,View the error log" + echoContent red "V2Ray failed to start" + echoContent red "Please manually execute [/etc/v2ray-agent/v2ray/v2ray -confdir /etc/v2ray-agent/v2ray/conf] to view the error log" exit 0 fi elif [[ "$1" == "stop" ]]; then if [[ -z $(pgrep -f "v2ray/v2ray") ]]; then - echoContent green " ---> V2RAY is successful" + echoContent green "---> V2Ray closed successfully" + else + echoContent red "Failed to close V2Ray" + echoContent red "Please manually execute [ps -ef|grep -v grep|grep v2ray|awk '{print \$2}'|xargs kill -9]" + exit 0 + fi + fi +} + +# Operate Hysteria +handleHysteria() { + # shellcheck disable=SC2010 + if find /bin /usr/bin | grep -q systemctl && ls /etc/systemd/system/ | grep -q hysteria.service; then + if [[ -z $(pgrep -f "hysteria/hysteria") ]] && [[ "$1" == "start" ]]; then + systemctl start hysteria.service + elif [[ -n $(pgrep -f "hysteria/hysteria") ]] && [[ "$1" == "stop" ]]; then + systemctl stop hysteria.service + fi + fi + sleep 0.8 + + if [[ "$1" == "start" ]]; then + if [[ -n $(pgrep -f "hysteria/hysteria") ]]; then + echoContent green " ---> Hysteria started successfully" + else + echoContent red "Hysteria failed to start" + echoContent red "Please manually execute [/etc/v2ray-agent/hysteria/hysteria --log-level debug -c /etc/v2ray-agent/hysteria/conf/config.json server] to view the error log" + exit 0 + fi + elif [[ "$1" == "stop" ]]; then + if [[ -z $(pgrep -f "hysteria/hysteria") ]]; then + echoContent green " ---> Hysteria closed successfully" else - echoContent red "V2Ray Close failed" - echoContent red "Please manually【ps -ef|grep -v grep|grep v2ray|awk '{print \$2}'|xargs kill -9】" + echoContent red "Hysteria shutdown failed" + echoContent red "Please manually execute [ps -ef|grep -v grep|grep hysteria|awk '{print \$2}'|xargs kill -9]" exit 0 fi fi } -# Operation XRAY +# Manipulate xray handleXray() { - if [[ -n $(find /bin /usr/bin -name "systemctl") ]] && ls /etc/systemd/system/ | grep -q xray.service; then + if [[ -n $(find /bin /usr/bin -name "systemctl") ]] && [[ -n $(find /etc/systemd/system/ -name "xray.service") ]]; then if [[ -z $(pgrep -f "xray/xray") ]] && [[ "$1" == "start" ]]; then systemctl start xray.service elif [[ -n $(pgrep -f "xray/xray") ]] && [[ "$1" == "stop" ]]; then @@ -1542,71 +2104,205 @@ handleXray() { if [[ "$1" == "start" ]]; then if [[ -n $(pgrep -f "xray/xray") ]]; then - echoContent green " ---> Xray started successfully" + echoContent green "---> Xray started successfully" else - echoContent red "XRay start failed" - echoContent red "Please manually【/etc/v2ray-agent/xray/xray -confdir /etc/v2ray-agent/xray/conf】,View the error log" + echoContent red "Xray failed to start" + echoContent red "Please manually execute [/etc/v2ray-agent/xray/xray -confdir /etc/v2ray-agent/xray/conf] to view the error log" exit 0 fi elif [[ "$1" == "stop" ]]; then if [[ -z $(pgrep -f "xray/xray") ]]; then - echoContent green " ---> XRay close success" + echoContent green "---> Xray closed successfully" else - echoContent red "XRay Close failed" - echoContent red "Please manually【ps -ef|grep -v grep|grep xray|awk '{print \$2}'|xargs kill -9】" + echoContent red "xray close failed" + echoContent red "Please manually execute [ps -ef|grep -v grep|grep xray|awk '{print \$2}'|xargs kill -9]" exit 0 fi fi } +# Get clients configuration +getClients() { + local path=$1 -# Operation Trojan-Go -handleTrojanGo() { - if [[ -n $(find /bin /usr/bin -name "systemctl") ]] && ls /etc/systemd/system/ | grep -q trojan-go.service; then - if [[ -z $(pgrep -f "trojan-go") ]] && [[ "$1" == "start" ]]; then - systemctl start trojan-go.service - elif [[ -n $(pgrep -f "trojan-go") ]] && [[ "$1" == "stop" ]]; then - systemctl stop trojan-go.service + local addClientsStatus=$2 + previousClients= + if [[ ${addClientsStatus} == "true" ]]; then + if [[ ! -f "${path}" ]]; then + echo + local protocol + protocol=$(echo "${path}" | awk -F "[_]" '{print $2 $3}') + echoContent yellow "The last installed configuration file of this protocol [${protocol}] was not read, the first uuid of the configuration file is used" + else + previousClients=$(jq -r ".inbounds[0].settings.clients" "${path}") fi + fi +} - sleep 0.5 - if [[ "$1" == "start" ]]; then - if [[ -n $(pgrep -f "trojan-go") ]]; then - echoContent green " ---> Trojan-GO starts success" - else - echoContent red "Trojan-Go failed to start" - echoContent red "Please manually【/etc/v2ray-agent/trojan/trojan-go -config /etc/v2ray-agent/trojan/config_full.json】,View the error log" - exit 0 +# Add client configuration +addClients() { + local path=$1 + local addClientsStatus=$2 + if [[ ${addClientsStatus} == "true" && -n "${previousClients}" ]]; then + config=$(jq -r ".inbounds[0].settings.clients = ${previousClients}" "${path}") + echo "${config}" | jq .>"${path}" + fi +} +# Add hysteria configuration +addClientsHysteria() { + local path=$1 + local addClientsStatus=$2 + + if [[ ${addClientsStatus} == "true" && -n "${previousClients}" ]]; then + local uuids= + uuids=$(echo "${previousClients}" | jq -r [.[].id]) + + + if [[ "${frontingType}" == "02_trojan_TCP_inbounds" ]]; then + uuids=$(echo "${previousClients}" | jq -r [.[].password]) fi - elif [[ "$1" == "stop" ]]; then - if [[ -z $(pgrep -f "trojan-go") ]]; then - echoContent green " ---> Trojan-GO close success" + config=$(jq -r ".auth.config = ${uuids}" "${path}") + echo "${config}" | jq .>"${path}" + fi +} + +# Initialize the hysteria port +initHysteriaPort() { + readHysteriaConfig + if [[ -n "${hysteriaPort}" ]]; then + read -r -p "Read the port of the last installation, do you use the port of the last installation? [y/n]:" historyHysteriaPortStatus + if [[ "${historyHysteriaPortStatus}" == "y" ]]; then + echoContent yellow "\n ---> Port: ${hysteriaPort}" else - echoContent red "Trojan-GO close failed" - echoContent red "Please manually【ps -ef|grep -v grep|grep trojan-go|awk '{print \$2}'|xargs kill -9】" - exit 0 + hysteriaPort= fi fi + + if [[ -z "${hysteriaPort}" ]]; then + echoContent yellow "Please enter the Hysteria port [Example: 10000], which cannot be repeated with other services" + read -r -p "Port:" hysteriaPort + fi + if [[ -z ${hysteriaPort} ]]; then + echoContent red " ---> Port cannot be empty" + initHysteriaPort "$2" + elif ((hysteriaPort < 1 || hysteriaPort > 65535)); then + echoContent red " ---> The port is invalid" + initHysteriaPort "$2" + fi + allowPort "${hysteriaPort}" +} + +# Initialize the protocol of hysteria +initHysteriaProtocol() { + echoContent skyBlue "\nPlease select a protocol type" + echoContent red "==============================================================" + echoContent yellow "1.udp(QUIC) (default)" + echoContent yellow "2.faketcp" + echoContent yellow "3.wechat-video" + echoContent red "==============================================================" + read -r -p "Please select:" selectHysteriaProtocol + case ${selectHysteriaProtocol} in + 1) + hysteriaProtocol="udp" + ;; + 2) + hysteriaProtocol="faketcp" + ;; + 3) + hysteriaProtocol="wechat-video" + ;; + *) + hysteriaProtocol="udp" + ;; + esac + echoContent yellow "\n ---> Protocol: ${hysteriaProtocol}\n" +} + +# Initialize hysteria network information +initHysteriaNetwork() { + + echoContent yellow "Please enter the average delay from local to server, please fill in according to the actual situation (default: 180, unit: ms)" + read -r -p "delay:" hysteriaLag + if [[ -z "${hysteriaLag}" ]]; then + hysteriaLag=180 + echoContent yellow "\n ---> Delay: ${hysteriaLag}\n" + fi + + echoContent yellow "Please enter the local bandwidth peak downlink speed (default: 100, unit: Mbps)" + read -r -p "Download speed:" hysteriaClientDownloadSpeed + if [[ -z "${hysteriaClientDownloadSpeed}" ]]; then + hysteriaClientDownloadSpeed=100 + echoContent yellow "\n ---> Downlink speed: ${hysteriaClientDownloadSpeed}\n" + fi + + echoContent yellow "Please enter the local bandwidth peak uplink speed (default: 50, unit: Mbps)" + read -r -p "Upload speed:" hysteriaClientUploadSpeed + if [[ -z "${hysteriaClientUploadSpeed}" ]]; then + hysteriaClientUploadSpeed=50 + echoContent yellow "\n ---> Uplink speed: ${hysteriaClientUploadSpeed}\n" + fi + + cat </etc/v2ray-agent/hysteria/conf/client_network.json +{ + "hysteriaLag":"${hysteriaLag}", + "hysteriaClientUploadSpeed":"${hysteriaClientUploadSpeed}", + "hysteriaClientDownloadSpeed":"${hysteriaClientDownloadSpeed}" +} +EOF + +} +# Initialize Hysteria configuration +initHysteriaConfig() { + echoContent skyBlue "\nProgress $1/${totalProgress} : Initialize Hysteria configuration" + + initHysteriaPort + initHysteriaProtocol + initHysteriaNetwork + + getClients "${configPath}${frontingType}.json" true + cat </etc/v2ray-agent/hysteria/conf/config.json +{ + "listen": ":${hysteriaPort}", + "protocol": "${hysteriaProtocol}", + "disable_udp": false, + "cert": "/etc/v2ray-agent/tls/${currentHost}.crt", + "key": "/etc/v2ray-agent/tls/${currentHost}.key", + "auth": { + "mode": "passwords", + "config": [] + }, + "alpn": "h3", + "recv_window_conn": 15728640, + "recv_window_client": 67108864, + "max_conn_client": 4096, + "disable_mtu_discovery": true, + "resolve_preference": "46", + "resolver": "https://8.8.8.8:443/dns-query" +} +EOF + + addClientsHysteria "/etc/v2ray-agent/hysteria/conf/config.json" true } -# Initialize V2RAY configuration file +# Initialize V2Ray configuration file initV2RayConfig() { - echoContent skyBlue "\n schedule $2/${totalProgress} : Initialize V2RAY configuration" + echoContent skyBlue "\nProgress $2/${totalProgress} : Initialize V2Ray configuration" echo - read -r -p "Whether it is customized UUID ?[y/n]:" customUUIDStatus + read -r -p "Custom UUID? [y/n]:" customUUIDStatus echo if [[ "${customUUIDStatus}" == "y" ]]; then - read -r -p "Please enter legal UUID:" currentCustomUUID + read -r -p "Please enter a valid UUID:" currentCustomUUID if [[ -n "${currentCustomUUID}" ]]; then uuid=${currentCustomUUID} fi fi - + local addClientsStatus= if [[ -n "${currentUUID}" && -z "${uuid}" ]]; then - read -r -p "Read to the last installation record,Whether to use the last installation UUID ?[y/n]:" historyUUIDStatus + read -r -p "Read the last installation record, do you use the UUID of the last installation? [y/n]:" historyUUIDStatus if [[ "${historyUUIDStatus}" == "y" ]]; then uuid=${currentUUID} + addClientsStatus=true else uuid=$(/etc/v2ray-agent/v2ray/v2ctl uuid) fi @@ -1615,13 +2311,13 @@ initV2RayConfig() { fi if [[ -z "${uuid}" ]]; then - echoContent red "\n ---> uuid Read error,regenerate" + addClientsStatus= + echoContent red "\n ---> uuid read error, regenerate" uuid=$(/etc/v2ray-agent/v2ray/v2ctl uuid) fi - rm -rf /etc/v2ray-agent/v2ray/conf/* - rm -rf /etc/v2ray-agent/v2ray/config_full.json - + movePreviousConfig + # log cat </etc/v2ray-agent/v2ray/conf/00_log.json { "log": { @@ -1643,8 +2339,8 @@ EOF ] } EOF - else + else cat </etc/v2ray-agent/v2ray/conf/10_ipv4_outbounds.json { "outbounds":[ @@ -1671,7 +2367,6 @@ EOF EOF fi - # dns cat </etc/v2ray-agent/v2ray/conf/11_dns.json { @@ -1682,13 +2377,18 @@ EOF } } EOF - # VLESS_TCP_TLS/XTLS - # Fall back nginx + + # VLESS_TCP_TLS + # fall back to nginx local fallbacksList='{"dest":31300,"xver":0},{"alpn":"h2","dest":31302,"xver":0}' -if [[ -n $(echo "${selectCustomInstallType}" | grep 4) || "$1" == "all" ]]; then + # trojan + if echo "${selectCustomInstallType}" | grep -q 4 || [[ "$1" == "all" ]]; then + fallbacksList='{"dest":31296,"xver":1},{"alpn":"h2","dest":31302,"xver":0}' -cat </etc/v2ray-agent/v2ray/conf/04_trojan_TCP_inbounds.json + + getClients "${configPath}../tmp/04_trojan_TCP_inbounds.json" "${addClientsStatus}" + cat </etc/v2ray-agent/v2ray/conf/04_trojan_TCP_inbounds.json { "inbounds":[ { @@ -1700,7 +2400,7 @@ cat </etc/v2ray-agent/v2ray/conf/04_trojan_TCP_inbounds.json "clients": [ { "password": "${uuid}", - "email": "${domain}_trojan_tcp" + "email": "${domain}_${uuid}" } ], "fallbacks":[ @@ -1718,46 +2418,91 @@ cat </etc/v2ray-agent/v2ray/conf/04_trojan_TCP_inbounds.json ] } EOF + addClients "/etc/v2ray-agent/v2ray/conf/04_trojan_TCP_inbounds.json" "${addClientsStatus}" fi # VLESS_WS_TLS if echo "${selectCustomInstallType}" | grep -q 1 || [[ "$1" == "all" ]]; then fallbacksList=${fallbacksList}',{"path":"/'${customPath}'ws","dest":31297,"xver":1}' + getClients "${configPath}../tmp/03_VLESS_WS_inbounds.json" "${addClientsStatus}" cat </etc/v2ray-agent/v2ray/conf/03_VLESS_WS_inbounds.json { "inbounds":[ { - "port": 31297, - "listen": "127.0.0.1", - "protocol": "vless", - "tag":"VLESSWS", - "settings": { - "clients": [ - { - "id": "${uuid}", - "email": "${domain}_VLESS_WS" - } - ], - "decryption": "none" - }, - "streamSettings": { - "network": "ws", - "security": "none", - "wsSettings": { - "acceptProxyProtocol": true, - "path": "/${customPath}ws" - } - } -} + "port": 31297, + "listen": "127.0.0.1", + "protocol": "vless", + "tag":"VLESSWS", + "settings": { + "clients": [ + { + "id": "${uuid}", + "email": "${domain}_${uuid}" + } + ], + "decryption": "none" + }, + "streamSettings": { + "network": "ws", + "security": "none", + "wsSettings": { + "acceptProxyProtocol": true, + "path": "/${customPath}ws" + } + } + } ] } EOF + addClients "/etc/v2ray-agent/v2ray/conf/03_VLESS_WS_inbounds.json" "${addClientsStatus}" fi + # trojan_grpc + if echo "${selectCustomInstallType}" | grep -q 2 || [[ "$1" == "all" ]]; then + if ! echo "${selectCustomInstallType}" | grep -q 5 && [[ -n ${selectCustomInstallType} ]]; then + fallbacksList=${fallbacksList//31302/31304} + fi + getClients "${configPath}../tmp/04_trojan_gRPC_inbounds.json" "${addClientsStatus}" + cat </etc/v2ray-agent/v2ray/conf/04_trojan_gRPC_inbounds.json +{ + "inbounds": [ + { + "port": 31304, + "listen": "127.0.0.1", + "protocol": "trojan", + "tag": "trojangRPCTCP", + "settings": { + "clients": [ + { + "password": "${uuid}", + "email": "${domain}_${uuid}" + } + ], + "fallbacks": [ + { + "dest": "31300" + } + ] + }, + "streamSettings": { + "network": "grpc", + "grpcSettings": { + "serviceName": "${customPath}trojangrpc" + } + } + } + ] +} +EOF + addClients "/etc/v2ray-agent/v2ray/conf/04_trojan_gRPC_inbounds.json" "${addClientsStatus}" + fi # VMess_WS if echo "${selectCustomInstallType}" | grep -q 3 || [[ "$1" == "all" ]]; then fallbacksList=${fallbacksList}',{"path":"/'${customPath}'vws","dest":31299,"xver":1}' + + getClients "${configPath}../tmp/05_VMess_WS_inbounds.json" "${addClientsStatus}" + cat </etc/v2ray-agent/v2ray/conf/05_VMess_WS_inbounds.json { "inbounds":[ @@ -1772,7 +2517,7 @@ EOF "id": "${uuid}", "alterId": 0, "add": "${add}", - "email": "${domain}_vmess_ws" + "email": "${domain}_${uuid}" } ] }, @@ -1788,9 +2533,11 @@ EOF ] } EOF + addClients "/etc/v2ray-agent/v2ray/conf/05_VMess_WS_inbounds.json" "${addClientsStatus}" fi - # VLESS gRPC + if echo "${selectCustomInstallType}" | grep -q 5 || [[ "$1" == "all" ]]; then + getClients "${configPath}../tmp/06_VLESS_gRPC_inbounds.json" "${addClientsStatus}" cat </etc/v2ray-agent/v2ray/conf/06_VLESS_gRPC_inbounds.json { "inbounds":[ @@ -1804,7 +2551,7 @@ EOF { "id": "${uuid}", "add": "${add}", - "email": "${domain}_VLESS_gRPC" + "email": "${domain}_${uuid}" } ], "decryption": "none" @@ -1819,56 +2566,21 @@ EOF ] } EOF + addClients "/etc/v2ray-agent/v2ray/conf/06_VLESS_gRPC_inbounds.json" "${addClientsStatus}" fi # VLESS_TCP - if [[ "${selectCoreType}" == "2" ]]; then - cat </etc/v2ray-agent/v2ray/conf/02_VLESS_TCP_inbounds.json -{ - "inbounds":[ - { - "port": 443, - "protocol": "vless", - "tag":"VLESSTCP", - "settings": { - "clients": [ - { - "id": "${uuid}", - "add": "${add}", - "email": "${domain}_VLESS_TLS_TCP" - } - ], - "decryption": "none", - "fallbacks": [ - ${fallbacksList} - ] - }, - "streamSettings": { - "network": "tcp", - "security": "tls", - "tlsSettings": { - "alpn": [ - "http/1.1", - "h2" - ], - "certificates": [ - { - "certificateFile": "/etc/v2ray-agent/tls/${domain}.crt", - "keyFile": "/etc/v2ray-agent/tls/${domain}.key" - } - ] - } - } - } - ] -} -EOF - elif [[ "${selectCoreType}" == "3" ]]; then - cat </etc/v2ray-agent/v2ray/conf/02_VLESS_TCP_inbounds.json + getClients "${configPath}../tmp/02_VLESS_TCP_inbounds.json" "${addClientsStatus}" + local defaultPort=443 + if [[ -n "${customPort}" ]]; then + defaultPort=${customPort} + fi + + cat </etc/v2ray-agent/v2ray/conf/02_VLESS_TCP_inbounds.json { "inbounds":[ { - "port": 443, + "port": ${defaultPort}, "protocol": "vless", "tag":"VLESSTCP", "settings": { @@ -1876,8 +2588,7 @@ EOF { "id": "${uuid}", "add":"${add}", - "flow":"xtls-rprx-direct", - "email": "${domain}_VLESS_XTLS/TLS-direct_TCP" + "email": "${domain}_VLESS_TLS-direct_TCP" } ], "decryption": "none", @@ -1887,15 +2598,19 @@ EOF }, "streamSettings": { "network": "tcp", - "security": "xtls", - "xtlsSettings": { + "security": "tls", + "tlsSettings": { + "minVersion": "1.2", "alpn": [ - "http/1.1" + "http/1.1", + "h2" ], "certificates": [ { "certificateFile": "/etc/v2ray-agent/tls/${domain}.crt", - "keyFile": "/etc/v2ray-agent/tls/${domain}.key" + "keyFile": "/etc/v2ray-agent/tls/${domain}.key", + "ocspStapling": 3600, + "usage":"encipherment" } ] } @@ -1904,18 +2619,19 @@ EOF ] } EOF - fi + addClients "/etc/v2ray-agent/v2ray/conf/02_VLESS_TCP_inbounds.json" "${addClientsStatus}" + } -# initializationXray Trojan XTLS config -initXrayFrontingConfig(){ +# Initialize Xray Trojan XTLS configuration file +initXrayFrontingConfig() { if [[ -z "${configPath}" ]]; then - echoContent red " ---> Not installed, please use the script installation" + echoContent red " ---> Not installed, please use script to install" menu exit 0 fi - if [[ "${coreInstallType}" != "1" ]];then - echoContent red " ---> No available types" + if [[ "${coreInstallType}" != "1" ]]; then + echoContent red " ---> Available types are not installed" fi local xtlsType= if echo ${currentInstallProtocolType} | grep -q trojan; then @@ -1925,67 +2641,78 @@ initXrayFrontingConfig(){ fi - echoContent skyBlue "\n function 1/${totalProgress} : Pre-switching${xtlsType}" + echoContent skyBlue "\nFunction 1/${totalProgress} : switch to ${xtlsType}" echoContent red "\n==============================================================" - echoContent yellow "# Precautions \n" - echoContent yellow "Alternative to${xtlsType}" - echoContent yellow "If the front is Trojan, two Trojan protocols have nodes, there is an unavailable XTLS" - echoContent yellow "Execute it again to switch to the previous front \n" + echoContent yellow "# Notes\n" + echoContent yellow "replaces the prefix with ${xtlsType}" + echoContent yellow "If the prefix is ​​Trojan, when viewing the account, there will be two nodes of the Trojan protocol, one of which is unavailable xtls" + echoContent yellow "Execute again to switch to the previous preamble\n" - echoContent yellow "1.Switch to${xtlsType}" + echoContent yellow "1.Switch to ${xtlsType}" echoContent red "==============================================================" - read -r -p "please choose:" selectType + read -r -p "Please select:" selectType if [[ "${selectType}" == "1" ]]; then - if [[ "${xtlsType}" == "Trojan" ]];then + if [[ "${xtlsType}" == "Trojan" ]]; then - local VLESSConfig=$(cat ${configPath}${frontingType}.json) + local VLESSConfig + VLESSConfig=$(cat ${configPath}${frontingType}.json) VLESSConfig=${VLESSConfig//"id"/"password"} VLESSConfig=${VLESSConfig//VLESSTCP/TrojanTCPXTLS} VLESSConfig=${VLESSConfig//VLESS/Trojan} VLESSConfig=${VLESSConfig//"vless"/"trojan"} VLESSConfig=${VLESSConfig//"id"/"password"} - echo "${VLESSConfig}" | jq . >${configPath}02_trojan_TCP_inbounds.json - rm ${configPath}${frontingType}.json + echo "${VLESSConfig}" | jq .>${configPath}02_trojan_TCP_inbounds.json + rm ${configPath}${frontingType}.json elif [[ "${xtlsType}" == "VLESS" ]]; then - local VLESSConfig=$(cat ${configPath}02_trojan_TCP_inbounds.json) + local VLESSConfig + VLESSConfig=$(cat ${configPath}02_trojan_TCP_inbounds.json) VLESSConfig=${VLESSConfig//"password"/"id"} VLESSConfig=${VLESSConfig//TrojanTCPXTLS/VLESSTCP} VLESSConfig=${VLESSConfig//Trojan/VLESS} VLESSConfig=${VLESSConfig//"trojan"/"vless"} VLESSConfig=${VLESSConfig//"password"/"id"} - echo "${VLESSConfig}" | jq . >${configPath}02_VLESS_TCP_inbounds.json + echo "${VLESSConfig}" | jq .>${configPath}02_VLESS_TCP_inbounds.json rm ${configPath}02_trojan_TCP_inbounds.json fi reloadCore fi - exit 0; + exit 0 +} + +# Move the last configuration file to a temporary file +movePreviousConfig() { + if [[ -n "${configPath}" ]] && [[ -f "${configPath}02_VLESS_TCP_inbounds.json" ]]; then + rm -rf ${configPath}../tmp/* + mv ${configPath}* ${configPath}../tmp/ + fi + } -# Initialize XRAY profile +# Initialize Xray configuration file initXrayConfig() { - echoContent skyBlue "\n progress $2/${totalProgress} : Initialize XRAY configuration" + echoContent skyBlue "\nProgress $2/${totalProgress} : Initialize Xray configuration" echo local uuid= + local addClientsStatus= if [[ -n "${currentUUID}" ]]; then - read -r -p "Read to the last installation record, is it used in the last installation? UUID ?[y/n]:" historyUUIDStatus + read -r -p "Read the last installation record, do you use the UUID of the last installation? [y/n]:" historyUUIDStatus if [[ "${historyUUIDStatus}" == "y" ]]; then + addClientsStatus=true uuid=${currentUUID} - echoContent green "\n ---> 使用成功" - else - uuid=$(/etc/v2ray-agent/xray/xray uuid) + echoContent green "\n ---> Successfully used" fi fi - if [[ -z "${uuid}" ]];then - echoContent yellow "Please enter custom UUID [need to legal], [Enter] Random UUID" + if [[ -z "${uuid}" ]]; then + echoContent yellow "Please enter a custom UUID [must be legal], [enter] random UUID" read -r -p 'UUID:' customUUID - if [[ -n ${customUUID} ]];then + if [[ -n ${customUUID} ]]; then uuid=${customUUID} else uuid=$(/etc/v2ray-agent/xray/xray uuid) @@ -1994,13 +2721,14 @@ initXrayConfig() { fi if [[ -z "${uuid}" ]]; then - echoContent red "\n ---> UUID read error, regenerate" + addClientsStatus= + echoContent red "\n ---> uuid read error, regenerate" uuid=$(/etc/v2ray-agent/xray/xray uuid) fi echoContent yellow "\n ${uuid}" - rm -rf /etc/v2ray-agent/xray/conf/* + movePreviousConfig # log cat </etc/v2ray-agent/xray/conf/00_log.json @@ -2053,7 +2781,6 @@ EOF EOF fi - # dns cat </etc/v2ray-agent/xray/conf/11_dns.json { @@ -2066,12 +2793,14 @@ EOF EOF # VLESS_TCP_TLS/XTLS - # 回落nginx + # fall back to nginx local fallbacksList='{"dest":31300,"xver":0},{"alpn":"h2","dest":31302,"xver":0}' # trojan - if [[ -n $(echo "${selectCustomInstallType}" | grep 4) || "$1" == "all" ]]; then + if echo "${selectCustomInstallType}" | grep -q 4 || [[ "$1" == "all" ]]; then fallbacksList='{"dest":31296,"xver":1},{"alpn":"h2","dest":31302,"xver":0}' + getClients "${configPath}../tmp/04_trojan_TCP_inbounds.json" "${addClientsStatus}" + cat </etc/v2ray-agent/xray/conf/04_trojan_TCP_inbounds.json { "inbounds":[ @@ -2084,7 +2813,7 @@ EOF "clients": [ { "password": "${uuid}", - "email": "${domain}_trojan_tcp" + "email": "${domain}_${uuid}" } ], "fallbacks":[ @@ -2102,49 +2831,51 @@ EOF ] } EOF + addClients "/etc/v2ray-agent/xray/conf/04_trojan_TCP_inbounds.json" "${addClientsStatus}" fi # VLESS_WS_TLS if echo "${selectCustomInstallType}" | grep -q 1 || [[ "$1" == "all" ]]; then fallbacksList=${fallbacksList}',{"path":"/'${customPath}'ws","dest":31297,"xver":1}' + getClients "${configPath}../tmp/03_VLESS_WS_inbounds.json" "${addClientsStatus}" cat </etc/v2ray-agent/xray/conf/03_VLESS_WS_inbounds.json { "inbounds":[ { - "port": 31297, - "listen": "127.0.0.1", - "protocol": "vless", - "tag":"VLESSWS", - "settings": { - "clients": [ - { - "id": "${uuid}", - "email": "${domain}_VLESS_WS" - } - ], - "decryption": "none" - }, - "streamSettings": { - "network": "ws", - "security": "none", - "wsSettings": { - "acceptProxyProtocol": true, - "path": "/${customPath}ws" - } - } -} + "port": 31297, + "listen": "127.0.0.1", + "protocol": "vless", + "tag":"VLESSWS", + "settings": { + "clients": [ + { + "id": "${uuid}", + "email": "${domain}_${uuid}" + } + ], + "decryption": "none" + }, + "streamSettings": { + "network": "ws", + "security": "none", + "wsSettings": { + "acceptProxyProtocol": true, + "path": "/${customPath}ws" + } + } + } ] } EOF + addClients "/etc/v2ray-agent/xray/conf/03_VLESS_WS_inbounds.json" "${addClientsStatus}" fi - # trojan_grpc - if echo ${selectCustomInstallType} | grep -q 2 || [[ "$1" == "all" ]]; then - if ! echo ${selectCustomInstallType} | grep -q 5 && [[ -n ${selectCustomInstallType} ]];then + if echo "${selectCustomInstallType}" | grep -q 2 || [[ "$1" == "all" ]]; then + if ! echo "${selectCustomInstallType}" | grep -q 5 && [[ -n ${selectCustomInstallType} ]]; then fallbacksList=${fallbacksList//31302/31304} fi - + getClients "${configPath}../tmp/04_trojan_gRPC_inbounds.json" "${addClientsStatus}" cat </etc/v2ray-agent/xray/conf/04_trojan_gRPC_inbounds.json { "inbounds": [ @@ -2157,7 +2888,7 @@ EOF "clients": [ { "password": "${uuid}", - "email": "${domain}_trojan_gRPC" + "email": "${domain}_${uuid}" } ], "fallbacks": [ @@ -2176,12 +2907,13 @@ EOF ] } EOF + addClients "/etc/v2ray-agent/xray/conf/04_trojan_gRPC_inbounds.json" "${addClientsStatus}" fi - # VMess_WS if echo "${selectCustomInstallType}" | grep -q 3 || [[ "$1" == "all" ]]; then fallbacksList=${fallbacksList}',{"path":"/'${customPath}'vws","dest":31299,"xver":1}' + getClients "${configPath}../tmp/05_VMess_WS_inbounds.json" "${addClientsStatus}" cat </etc/v2ray-agent/xray/conf/05_VMess_WS_inbounds.json { "inbounds":[ @@ -2196,7 +2928,7 @@ EOF "id": "${uuid}", "alterId": 0, "add": "${add}", - "email": "${domain}_vmess_ws" + "email": "${domain}_${uuid}" } ] }, @@ -2212,9 +2944,11 @@ EOF ] } EOF + addClients "/etc/v2ray-agent/xray/conf/05_VMess_WS_inbounds.json" "${addClientsStatus}" fi if echo "${selectCustomInstallType}" | grep -q 5 || [[ "$1" == "all" ]]; then + getClients "${configPath}../tmp/06_VLESS_gRPC_inbounds.json" "${addClientsStatus}" cat </etc/v2ray-agent/xray/conf/06_VLESS_gRPC_inbounds.json { "inbounds":[ @@ -2228,7 +2962,7 @@ EOF { "id": "${uuid}", "add": "${add}", - "email": "${domain}_VLESS_gRPC" + "email": "${domain}_${uuid}" } ], "decryption": "none" @@ -2243,14 +2977,21 @@ EOF ] } EOF + addClients "/etc/v2ray-agent/xray/conf/06_VLESS_gRPC_inbounds.json" "${addClientsStatus}" fi # VLESS_TCP + getClients "${configPath}../tmp/02_VLESS_TCP_inbounds.json" "${addClientsStatus}" + local defaultPort=443 + if [[ -n "${customPort}" ]]; then + defaultPort=${customPort} + fi + cat </etc/v2ray-agent/xray/conf/02_VLESS_TCP_inbounds.json { "inbounds":[ { - "port": 443, + "port": ${defaultPort}, "protocol": "vless", "tag":"VLESSTCP", "settings": { @@ -2259,7 +3000,7 @@ EOF "id": "${uuid}", "add":"${add}", "flow":"xtls-rprx-direct", - "email": "${domain}_VLESS_XTLS/TLS-direct_TCP" + "email": "${domain}_${uuid}" } ], "decryption": "none", @@ -2290,12 +3031,13 @@ EOF ] } EOF + addClients "/etc/v2ray-agent/xray/conf/02_VLESS_TCP_inbounds.json" "${addClientsStatus}" } -# initialization Trojan-Go Configure +# Initialize Trojan-Go configuration initTrojanGoConfig() { - echoContent skyBlue "\n schedule $1/${totalProgress} : Initialization Trojan configuration" + echoContent skyBlue "\nProgress $1/${totalProgress} : Initialize Trojan configuration" cat </etc/v2ray-agent/trojan/config_full.json { "run_type": "server", @@ -2329,130 +3071,118 @@ initTrojanGoConfig() { EOF } -# customizeCDN IP +# Custom CDN IP customCDNIP() { - echoContent skyBlue "\n progress $1/${totalProgress} : Add cloudflare self-selecting CNAME" + echoContent skyBlue "\nProgress $1/${totalProgress} : add cloudflare custom CNAME" echoContent red "\n==============================================================" - echoContent yellow "# Cautions" - echoContent yellow "\n Tutorial Address:" + echoContent yellow "# Notes" + echoContent yellow "\nTutorial address:" echoContent skyBlue "https://github.com/mack-a/v2ray-agent/blob/master/documents/optimize_V2Ray.md" - echoContent red "\n If you do not know about Cloudflare optimization, please do not use" - echoContent yellow "\n 1.china Mobile:104.16.123.96" - echoContent yellow " 2.china Unicom:www.cloudflare.com" - echoContent yellow " 3.china Telecom:www.digitalocean.com" + echoContent red "\nIf you don't know about Cloudflare optimization, please don't use" + echoContent yellow "\n 1.Mobile: 104.16.123.96" + echoContent yellow " 2.Unicom: www.cloudflare.com" + echoContent yellow " 3.Telecom: www.digitalocean.com" echoContent skyBlue "----------------------------" - read -r -p "Please choose[Carriage return not used]:" selectCloudflareType - case ${selectCloudflareType} in - 1) - add="104.16.123.96" - ;; - 2) - add="www.cloudflare.com" - ;; - 3) - add="www.digitalocean.com" - ;; - *) + read -r -p "Please select [Enter not used]:" selectCloudflareType + case ${selectCloudflareType} in + 1) + add="104.16.123.96" + ;; + 2) + add="www.cloudflare.com" + ;; + 3) + add="www.digitalocean.com" + ;; + *) add="${domain}" - echoContent yellow "\n ---> No use" + echoContent yellow "\n ---> not used" ;; - esac + esac } -# 通用 +# generic defaultBase64Code() { local type=$1 local email=$2 local id=$3 - local hostPort=$4 - local host= - local port= - if echo "${hostPort}" | grep -q ":"; then - host=$(echo "${hostPort}" | awk -F "[:]" '{print $1}') - port=$(echo "${hostPort}" | awk -F "[:]" '{print $2}') - else - host=${hostPort} - port=443 - fi - local path=$5 - local add=$6 + port=${currentDefaultPort} - local subAccount=${currentHost}_$(echo "${id}_currentHost" | md5sum | awk '{print $1}') + local subAccount + subAccount=$(echo "${email}" | awk -F "[_]" '{print $1}')_$(echo "${id}_currentHost" | md5sum | awk '{print $1}') if [[ "${type}" == "vlesstcp" ]]; then - if [[ "${coreInstallType}" == "1" ]] && echo ${currentInstallProtocolType} | grep -q 0; then - echoContent yellow " ---> General format(VLESS+TCP+TLS/xtls-rprx-direct)" - echoContent green " vless://${id}@${host}:${port}?encryption=none&security=xtls&type=tcp&host=${host}&headerType=none&sni=${host}&flow=xtls-rprx-direct#${email}\n" + if [[ "${coreInstallType}" == "1" ]] && echo "${currentInstallProtocolType}" | grep -q 0; then + echoContent yellow " ---> General format (VLESS+TCP+TLS/xtls-rprx-direct)" + echoContent green " vless://${id}@${currentHost}:${currentDefaultPort}?encryption=none&security=xtls&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx-direct#${email}\n" - echoContent yellow " ---> Format clear text(VLESS+TCP+TLS/xtls-rprx-direct)" - echoContent green "agreement type:VLESS,address:${host},port:${port},user ID:${id},Safety:xtls,transfer method:tcp,flow:xtls-rprx-direct,account name:${email}\n" + echoContent yellow " ---> formatted plaintext (VLESS+TCP+TLS/xtls-rprx-direct)" + echoContent green "Protocol type: VLESS, address: ${currentHost}, port: ${currentDefaultPort}, user ID: ${id}, security: xtls, transmission method: tcp, flow: xtls-rprx-direct, account name: ${email}\n" cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" -vless://${id}@${host}:${port}?encryption=none&security=xtls&type=tcp&host=${host}&headerType=none&sni=${host}&flow=xtls-rprx-direct#${email} +vless://${id}@${currentHost}:${currentDefaultPort}?encryption=none&security=xtls&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx-direct#${email} EOF echoContent yellow " ---> QR code VLESS(VLESS+TCP+TLS/xtls-rprx-direct)" - echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${host}%3A${port}%3F${encryption}%3Dnone%26security%3Dxtls%26type%3Dtcp%26${host}%3D${host}%26headerType%3Dnone%26sni%3D${host}%26flow%3Dxtls-rprx-direct%23${email}\n" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${currentHost}%3A${currentDefaultPort}%3Fencryption%3Dnone%26security%3Dxtls%26type%3Dtcp%26${currentHost}%3D${currentHost}%26headerType%3Dnone%26sni%3D${currentHost}%26flow%3Dxtls-rprx-direct%23${email}\n" echoContent skyBlue "----------------------------------------------------------------------------------" - echoContent yellow " ---> General format(VLESS+TCP+TLS/xtls-rprx-splice)" - echoContent green " vless://${id}@${host}:${port}?encryption=none&security=xtls&type=tcp&host=${host}&headerType=none&sni=${host}&flow=xtls-rprx-splice#${email}\n" + echoContent yellow " ---> General format (VLESS+TCP+TLS/xtls-rprx-splice)" + echoContent green " vless://${id}@${currentHost}:${currentDefaultPort}?encryption=none&security=xtls&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx-splice#${email/direct/splice}\n" - echoContent yellow " ---> Format clear text(VLESS+TCP+TLS/xtls-rprx-splice)" - echoContent green " agreement type:VLESS,address:${host},port:${port},user ID:${id},Safety:xtls,transfer method:tcp,flow:xtls-rprx-splice,account name:${email}\n" + echoContent yellow " ---> formatted plaintext (VLESS+TCP+TLS/xtls-rprx-splice)" + echoContent green " Protocol type: VLESS, address: ${currentHost}, port: ${currentDefaultPort}, user ID: ${id}, security: xtls, transmission method: tcp, flow: xtls-rprx-splice, account name: ${email/direct/splice}\n" cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" -vless://${id}@${host}:${port}?encryption=none&security=xtls&type=tcp&host=${host}&headerType=none&sni=${host}&flow=xtls-rprx-splice#${email} +vless://${id}@${currentHost}:${currentDefaultPort}?encryption=none&security=xtls&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx-splice#${email/direct/splice} EOF echoContent yellow " ---> QR code VLESS(VLESS+TCP+TLS/xtls-rprx-splice)" - echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${host}%3A${port}%3F${encryption}%3Dnone%26security%3Dxtls%26type%3Dtcp%26${host}%3D${host}%26headerType%3Dnone%26sni%3D${host}%26flow%3Dxtls-rprx-splice%23${email}\n" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${currentHost}%3A${currentDefaultPort}%3Fencryption%3Dnone%26security%3Dxtls%26type%3Dtcp%26${currentHost}%3D${currentHost}%26headerType%3Dnone%26sni%3D${currentHost}%26flow%3Dxtls-rprx-splice%23${email/direct/splice}\n" - elif [[ "${coreInstallType}" == "2" || "${coreInstallType}" == "3" ]]; then - echoContent yellow " ---> General format(VLESS+TCP+TLS)" - echoContent green " vless://${id}@${host}:${port}?security=tls&encryption=none&host=${host}&headerType=none&type=tcp#${email}\n" + elif [[ "${coreInstallType}" == 2 || "${coreInstallType}" == "3" ]]; then + echoContent yellow " ---> General format (VLESS+TCP+TLS)" + echoContent green " vless://${id}@${currentHost}:${currentDefaultPort}?security=tls&encryption=none&host=${currentHost}&headerType=none&type=tcp#${email}\n" - echoContent yellow " ---> Format clear text(VLESS+TCP+TLS/xtls-rprx-splice)" - echoContent green " agreement type:VLESS,address:${host},port:${port},user ID:${id}, Safety: TLS, Transmission mode: TCP, account name:${email}\n" + echoContent yellow " ---> formatted plaintext (VLESS+TCP+TLS/xtls-rprx-splice)" + echoContent green " Protocol type: VLESS, address: ${currentHost}, port: ${currentDefaultPort}, user ID: ${id}, security: tls, transmission method: tcp, account name: ${email/direct/splice} \n" cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" -vless://${id}@${host}:${port}?security=tls&encryption=none&host=${host}&headerType=none&type=tcp#${email} +vless://${id}@${currentHost}:${currentDefaultPort}?security=tls&encryption=none&host=${currentHost}&headerType=none&type=tcp#${email} EOF echoContent yellow " ---> QR code VLESS(VLESS+TCP+TLS)" - echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3a%2f%2f${id}%40${host}%3a${port}%3fsecurity%3dtls%26encryption%3dnone%26host%3d${host}%26headerType%3dnone%26type%3dtcp%23${email}\n" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3a%2f%2f${id}%40${currentHost}%3a${currentDefaultPort}%3fsecurity%3dtls%26encryption%3dnone%26host%3d${currentHost}%26headerType%3dnone%26type%3dtcp%23${email}\n" fi elif [[ "${type}" == "trojanTCPXTLS" ]]; then - echoContent yellow " ---> General format(Trojan+TCP+TLS/xtls-rprx-direct)" - echoContent green " trojan://${id}@${host}:${port}?encryption=none&security=xtls&type=tcp&host=${host}&headerType=none&sni=${host}&flow=xtls-rprx-direct#${email}\n" + echoContent yellow " ---> General format (Trojan+TCP+TLS/xtls-rprx-direct)" + echoContent green " trojan://${id}@${currentHost}:${currentDefaultPort}?encryption=none&security=xtls&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx-direct#${email}\n" - echoContent yellow " ---> Format clear text(Trojan+TCP+TLS/xtls-rprx-direct)" - echoContent green "Type: Trojan, address:${host},port:${port},user ID:${id},Safety:xtls,transfer method:tcp,flow:xtls-rprx-direct,account name:${email}\n" - cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" -trojan://${id}@${host}:${port}?encryption=none&security=xtls&type=tcp&host=${host}&headerType=none&sni=${host}&flow=xtls-rprx-direct#${email} + echoContent yellow " ---> formatted plaintext (Trojan+TCP+TLS/xtls-rprx-direct)" + echoContent green "Protocol type: Trojan, address: ${currentHost}, port: ${currentDefaultPort}, user ID: ${id}, security: xtls, transmission method: tcp, flow: xtls-rprx-direct, account name: ${email}\n" + cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" +trojan://${id}@${currentHost}:${currentDefaultPort}?encryption=none&security=xtls&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx-direct#${email} EOF - echoContent yellow " ---> QR code Trojan(Trojan+TCP+TLS/xtls-rprx-direct)" - echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=trojan%3A%2F%2F${id}%40${host}%3A${port}%3Fencryption%3Dnone%26security%3Dxtls%26type%3Dtcp%26${host}%3D${host}%26headerType%3Dnone%26sni%3D${host}%26flow%3Dxtls-rprx-direct%23${email}\n" + echoContent yellow " ---> QR code Trojan(Trojan+TCP+TLS/xtls-rprx-direct)" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=trojan%3A%2F%2F${id}%40${currentHost}%3A${currentDefaultPort}%3Fencryption%3Dnone%26security%3Dxtls%26type%3Dtcp%26${currentHost}%3D${currentHost}%26headerType%3Dnone%26sni%3D${currentHost}%26flow%3Dxtls-rprx-direct%23${email}\n" - echoContent skyBlue "----------------------------------------------------------------------------------" + echoContent skyBlue "----------------------------------------------------------------------------------" - echoContent yellow " ---> General format(Trojan+TCP+TLS/xtls-rprx-splice)" - echoContent green " trojan://${id}@${host}:${port}?encryption=none&security=xtls&type=tcp&host=${host}&headerType=none&sni=${host}&flow=xtls-rprx-splice#${email}\n" + echoContent yellow " ---> Common format (Trojan+TCP+TLS/xtls-rprx-splice)" + echoContent green " trojan://${id}@${currentHost}:${currentDefaultPort}?encryption=none&security=xtls&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx-splice#${email/direct/splice}\n" - echoContent yellow " ---> Format clear text(Trojan+TCP+TLS/xtls-rprx-splice)" - echoContent green " agreement type:VLESS,address:${host},port:${port},user ID:${id},Safety:xtls,transfer method:tcp,flow:xtls-rprx-splice,account name:${email}\n" - cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" -trojan://${id}@${host}:${port}?encryption=none&security=xtls&type=tcp&host=${host}&headerType=none&sni=${host}&flow=xtls-rprx-splice#${email} + echoContent yellow " ---> formatted plaintext (Trojan+TCP+TLS/xtls-rprx-splice)" + echoContent green " Protocol type: VLESS, address: ${currentHost}, port: ${currentDefaultPort}, user ID: ${id}, security: xtls, transmission method: tcp, flow: xtls-rprx-splice, account name: ${email/direct/splice}\n" + cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" +trojan://${id}@${currentHost}:${currentDefaultPort}?encryption=none&security=xtls&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx-splice#${email/direct/splice} EOF - echoContent yellow " ---> QR code Trojan(Trojan+TCP+TLS/xtls-rprx-splice)" - echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=trojan%3A%2F%2F${id}%40${host}%3A${port}%3Fencryption%3Dnone%26security%3Dxtls%26type%3Dtcp%26${host}%3D${host}%26headerType%3Dnone%26sni%3D${host}%26flow%3Dxtls-rprx-splice%23${email}\n" - + echoContent yellow " ---> QR code Trojan(Trojan+TCP+TLS/xtls-rprx-splice)" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=trojan%3A%2F%2F${id}%40${currentHost}%3A${currentDefaultPort}%3Fencryption%3Dnone%26security%3Dxtls%26type%3Dtcp%26${currentHost}%3D${currentHost}%26headerType%3Dnone%26sni%3D${currentHost}%26flow%3Dxtls-rprx-splice%23${email/direct/splice}\n" elif [[ "${type}" == "vmessws" ]]; then + qrCodeBase64Default=$(echo -n "{\"port\":${currentDefaultPort},\"ps\":\"${email}\",\"tls\":\"tls\",\"id\":\"${id}\",\"aid\":0,\"v\":2,\"host\":\"${currentHost}\",\"type\":\"none\",\"path\":\"/${currentPath}vws\",\"net\":\"ws\",\"add\":\"${currentAdd}\",\"allowInsecure\":0,\"method\":\"none\",\"peer\":\"${currentHost}\",\"sni\":\"${currentHost}\"}" | base64 -w 0) + qrCodeBase64Default="${qrCodeBase64Default// /}" - qrCodeBase64Default=$(echo -n '{"port":"'${port}'","ps":'\"${email}\"',"tls":"tls","id":'\"${id}\"',"aid":"0","v":"2","host":"'${host}'","type":"none","path":"/'${path}'","net":"ws","add":"'${add}'","allowInsecure":0,"method":"none","peer":"'${host}'","sni":"'${host}'"}' | sed 's#/#\\\/#g' | base64) - qrCodeBase64Default=$(echo ${qrCodeBase64Default} | sed 's/ //g') - - echoContent yellow " ---> Universal json(VMess+WS+TLS)" - echoContent green ' {"port":"'${port}'","ps":'\"${ps}\"',"tls":"tls","id":'\"${id}\"',"aid":"0","v":"2","host":"'${host}'","type":"none","path":"/'${path}'","net":"ws","add":"'${add}'","allowInsecure":0,"method":"none","peer":"'${host}'","sni":"'${host}'"}\n' - echoContent yellow " ---> Universal vmess(VMess+WS+TLS)Link" + echoContent yellow " ---> 通用json(VMess+WS+TLS)" + echoContent green " {\"port\":${currentDefaultPort},\"ps\":\"${email}\",\"tls\":\"tls\",\"id\":\"${id}\",\"aid\":0,\"v\":2,\"host\":\"${currentHost}\",\"type\":\"none\",\"path\":\"/${currentPath}vws\",\"net\":\"ws\",\"add\":\"${currentAdd}\",\"allowInsecure\":0,\"method\":\"none\",\"peer\":\"${currentHost}\",\"sni\":\"${currentHost}\"}\n" + echoContent yellow "---> Generic vmess(VMess+WS+TLS) link" echoContent green " vmess://${qrCodeBase64Default}\n" echoContent yellow " ---> QR code vmess(VMess+WS+TLS)" @@ -2461,154 +3191,134 @@ vmess://${qrCodeBase64Default} EOF echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vmess://${qrCodeBase64Default}\n" - elif [[ "${type}" == "vmesstcp" ]]; then - -# echoContent yellow " ---> 通用格式[新版,推荐]" -# -# echoContent green " vmess://tcp+tls:2e6257c5-1402-41a6-a96d-1e0bdad78159-0@vu3.s83h.xyz:443/?type=http&tlsServerName=vu3.s83h.xyz#vu3.s83h.xyz_vmess_tcp" -# echoContent green " vmess://tcp+tls:${id//\"/}-0@${add}:${port}/?type=http&path=/${path}&tlsServerName=${host}&alpn=http1.1#${ps//\"/}\n" -# -# echoContent yellow " ---> 格式化明文(vmess+http+tls)" -# echoContent green "协议类型:vmess,地址:${host},端口:${port},用户ID:${id},安全:tls,传输方式:http,账户名:${ps}\n" -# cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" -#vmess://http+tls:${id}-0@${add}:${port}/?path=/${path}&tlsServerName=${host}&alpn=http1.1#${ps} -#EOF -# echoContent yellow " ---> 二维码 vmess(http+tls)" -# echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vmess%3A%2F%2Fhttp%2Btls%3A${id}-0%40add%3A${port}%2F%3Fpath%3D%2F${path}%26tlsServerName%3D${host}%26alpn%3Dhttp1.1%23%24%7B${ps}%7D\n" - - echoContent red path:${path} - qrCodeBase64Default=$(echo -n '{"add":"'${add}'","aid":"0","host":"'${host}'","id":'"${id}"',"net":"tcp","path":"/'${path}'","port":"'${port}'","ps":'${ps}',"scy":"none","sni":"'${host}'","tls":"tls","v":"2","type":"http","allowInsecure":0,"peer":"'${host}'","obfs":"http","obfsParam":"'${host}'"}' | base64) - qrCodeBase64Default=$(echo ${qrCodeBase64Default} | sed 's/ //g') - - echoContent yellow " ---> Universal json(VMess+TCP+TLS)" - echoContent green ' {"port":"'${port}'","ps":'${ps}',"tls":"tls","id":'"${id}"',"aid":"0","v":"2","host":"'${host}'","type":"http","path":"/'${path}'","net":"http","add":"'${add}'","allowInsecure":0,"method":"post","peer":"'${host}'","obfs":"http","obfsParam":"'${host}'"}\n' - echoContent yellow " ---> Universalvmess(VMess+TCP+TLS)Link" - echoContent green " vmess://${qrCodeBase64Default}\n" - - cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" -vmess://${qrCodeBase64Default} -EOF - echoContent yellow " ---> QR code vmess(VMess+TCP+TLS)" - echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vmess://${qrCodeBase64Default}\n" + # elif [[ "${type}" == "vmesstcp" ]]; then + # + # echoContent red "path:${path}" + # qrCodeBase64Default=$(echo -n "{\"add\":\"${add}\",\"aid\":0,\"host\":\"${host}\",\"id\":\"${id}\",\"net\":\"tcp\",\"path\":\"${path}\",\"port\":${port},\"ps\":\"${email}\",\"scy\":\"none\",\"sni\":\"${host}\",\"tls\":\"tls\",\"v\":2,\"type\":\"http\",\"allowInsecure\":0,\"peer\":\"${host}\",\"obfs\":\"http\",\"obfsParam\":\"${host}\"}" | base64) + # qrCodeBase64Default="${qrCodeBase64Default// /}" + # + # echoContent yellow " ---> 通用json(VMess+TCP+TLS)" + # echoContent green " {\"port\":'${port}',\"ps\":\"${email}\",\"tls\":\"tls\",\"id\":\"${id}\",\"aid\":0,\"v\":2,\"host\":\"${host}\",\"type\":\"http\",\"path\":\"${path}\",\"net\":\"http\",\"add\":\"${add}\",\"allowInsecure\":0,\"method\":\"post\",\"peer\":\"${host}\",\"obfs\":\"http\",\"obfsParam\":\"${host}\"}\n" + # echoContent yellow " ---> Generic vmess(VMess+TCP+TLS) link" + # echoContent green " vmess://${qrCodeBase64Default}\n" + # + # cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" + #vmess://${qrCodeBase64Default} + #EOF + # echoContent yellow " ---> QR code vmess(VMess+TCP+TLS)" + # echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vmess://${qrCodeBase64Default}\n" elif [[ "${type}" == "vlessws" ]]; then - echoContent yellow " ---> General format(VLESS+WS+TLS)" - echoContent green " vless://${id}@${add}:${port}?encryption=none&security=tls&type=ws&host=${host}&sni=${host}&path=%2f${path}#${email}\n" + echoContent yellow " ---> General format (VLESS+WS+TLS)" + echoContent green " vless://${id}@${currentAdd}:${currentDefaultPort}?encryption=none&security=tls&type=ws&host=${currentHost}&sni=${currentHost}&path=/${currentPath}ws#${email}\n" - echoContent yellow " ---> Format clear text(VLESS+WS+TLS)" - echoContent green " agreement type:VLESS,address:${add},Camouflage domain name/SNI:${host},port:${port},user ID:${id},Safety:tls,transfer method:ws,path:/${path},account name:${email}\n" + echoContent yellow " ---> formatted plaintext (VLESS+WS+TLS)" + echoContent green " Protocol type: VLESS, address: ${currentAdd}, fake domain name/SNI: ${currentHost}, port: ${currentDefaultPort}, user ID: ${id}, security: tls, transmission method: ws, path :/${currentPath}ws, account name: ${email}\n" cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" -vless://${id}@${add}:${port}?encryption=none&security=tls&type=ws&host=${host}&sni=${host}&path=%2f${path}#${email} +vless://${id}@${currentAdd}:${currentDefaultPort}?encryption=none&security=tls&type=ws&host=${currentHost}&sni=${currentHost}&path=/${currentPath}ws#${email} EOF - echoContent yellow " ---> QR code VLESS(VLESS+TCP+TLS/XTLS)" - echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${add}%3A${port}%3Fencryption%3Dnone%26security%3Dtls%26type%3Dws%26host%3D${host}%26sni%3D${host}%26path%3D%252f${path}%23${email}" + echoContent yellow " ---> QR code VLESS(VLESS+WS+TLS)" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${currentAdd}%3A${currentDefaultPort}%3Fencryption%3Dnone%26security%3Dtls%26type%3Dws%26host%3D${currentHost}%26sni%3D${currentHost}%26path%3D%252f${currentPath}ws%23${email}" elif [[ "${type}" == "vlessgrpc" ]]; then - echoContent yellow " ---> General format(VLESS+gRPC+TLS)" - echoContent green " vless://${id}@${add}:${port}?encryption=none&security=tls&type=grpc&host=${host}&path=${path}&serviceName=${path}&alpn=h2&sni=${host}#${email}\n" + echoContent yellow " ---> General format (VLESS+gRPC+TLS)" + echoContent green " vless://${id}@${currentAdd}:${currentDefaultPort}?encryption=none&security=tls&type=grpc&host=${currentHost}&path=${currentPath}grpc&serviceName=${currentPath}grpc&alpn=h2&sni=${currentHost}#${email}\n" - echoContent yellow " ---> Format clear text(VLESS+gRPC+TLS)" - echoContent green " agreement type:VLESS,address:${add},Camouflage domain name/SNI:${host},port:${port},user ID:${id},Safety:tls,transfer method:gRPC,alpn:h2,serviceName:${path},account name:${email}\n" + echoContent yellow " ---> formatted plaintext (VLESS+gRPC+TLS)" + echoContent green " Protocol type: VLESS, address: ${currentAdd}, fake domain name/SNI: ${currentHost}, port: ${currentDefaultPort}, user ID: ${id}, security: tls, transmission method: gRPC, alpn :h2, serviceName: ${currentPath}grpc, account name: ${email}\n" cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" -vless://${id}@${add}:${port}?encryption=none&security=tls&type=grpc&host=${host}&path=${path}&serviceName=${path}&alpn=h2&sni=${host}#${email} +vless://${id}@${currentAdd}:${currentDefaultPort}?encryption=none&security=tls&type=grpc&host=${currentHost}&path=${currentPath}grpc&serviceName=${currentPath}grpc&alpn=h2&sni=${currentHost}#${email} EOF echoContent yellow " ---> QR code VLESS(VLESS+gRPC+TLS)" - echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${add}%3A${port}%3Fencryption%3Dnone%26security%3Dtls%26type%3Dgrpc%26host%3D${host}%26serviceName%3D${path}%26path%3D${path}%26sni%3D${host}%26alpn%3Dh2%23${email}" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${currentAdd}%3A${currentDefaultPort}%3Fencryption%3Dnone%26security%3Dtls%26type%3Dgrpc%26host%3D${currentHost}%26serviceName%3D${currentPath}grpc%26path%3D${currentPath}grpc%26sni%3D${currentHost}%26alpn%3Dh2%23${email}" elif [[ "${type}" == "trojan" ]]; then # URLEncode echoContent yellow " ---> Trojan(TLS)" - echoContent green " trojan://${id}@${host}:${port}?peer=${host}&sni=${host}&alpn=http1.1#${host}_Trojan\n" + echoContent green " trojan://${id}@${currentHost}:${currentDefaultPort}?peer=${currentHost}&sni=${currentHost}&alpn=http/1.1#${currentHost}_Trojan\n" cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" -trojan://${id}@${host}:${port}?peer=${host}&sni=${host}&alpn=http1.1#${host}_Trojan +trojan://${id}@${currentHost}:${currentDefaultPort}?peer=${currentHost}&sni=${currentHost}&alpn=http/1.1#${email}_Trojan EOF echoContent yellow " ---> QR code Trojan(TLS)" - echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=trojan%3a%2f%2f${id}%40${host}%3a${port}%3fpeer%3d${host}%26sni%3d${host}%26alpn%3Dhttp1.1%23${host}_Trojan\n" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=trojan%3a%2f%2f${id}%40${currentHost}%3a${port}%3fpeer%3d${currentHost}%26sni%3d${currentHost}%26alpn%3Dhttp/1.1%23${email}\n" elif [[ "${type}" == "trojangrpc" ]]; then # URLEncode echoContent yellow " ---> Trojan gRPC(TLS)" - echoContent green " trojan://${id}@${host}:${port}?encryption=none&peer=${host}&security=tls&type=grpc&sni=${host}&alpn=h2&path=${path}&serviceName=${path}#${host}_Trojan_gRPC\n" - + echoContent green " trojan://${id}@${currentAdd}:${currentDefaultPort}?encryption=none&peer=${currentHost}&security=tls&type=grpc&sni=${currentHost}&alpn=h2&path=${currentPath}trojangrpc&serviceName=${currentPath}trojangrpc#${email}\n" cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" -trojan://${id}@${host}:${port}?encryption=none&peer=${host}&security=tls&type=grpc&sni=${host}&alpn=h2&path=${path}&serviceName=${path}#${host}_Trojan_gRPC +trojan://${id}@${currentAdd}:${currentDefaultPort}?encryption=none&peer=${currentHost}&security=tls&type=grpc&sni=${currentHost}&alpn=h2&path=${currentPath}trojangrpc&serviceName=${currentPath}trojangrpc#${email} EOF echoContent yellow " ---> QR code Trojan gRPC(TLS)" - echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=trojan%3a%2f%2f${id}%40${host}%3a${port}%3Fencryption%3Dnone%26security%3Dtls%26peer%3d${host}%26type%3Dgrpc%26sni%3d${host}%26path%3D${path}%26alpn%3D=h2%26serviceName%3D${path}%23${host}_Trojan_gRPC\n" - - elif [[ "${type}" == "trojangows" ]]; then - # URLEncode - echoContent yellow " ---> Trojan-Go(WS+TLS) Shadowrocket" - echoContent green " trojan://${id}@${add}:${port}?allowInsecure=0&&peer=${host}&sni=${host}&plugin=obfs-local;obfs=websocket;obfs-host=${host};obfs-uri=${path}#${host}_Trojan_ws\n" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=trojan%3a%2f%2f${id}%40${currentAdd}%3a${currentDefaultPort}%3Fencryption%3Dnone%26security%3Dtls%26peer%3d${currentHost}%26type%3Dgrpc%26sni%3d${currentHost}%26path%3D${currentPath}trojangrpc%26alpn%3Dh2%26serviceName%3D${currentPath}trojangrpc%23${email}\n" + elif [[ "${type}" == "hysteria" ]]; then + echoContent yellow " ---> Hysteria(TLS)" + echoContent green " hysteria://${currentHost}:${hysteriaPort}?protocol=${hysteriaProtocol}&auth=${id}&peer=${currentHost}&insecure=0&alpn=h3&upmbps=${hysteriaClientUploadSpeed}&downmbps=${hysteriaClientDownloadSpeed}#${email}\n" cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" -trojan://${id}@${add}:${port}?allowInsecure=0&&peer=${host}&sni=${host}&plugin=obfs-local;obfs=websocket;obfs-host=${host};obfs-uri=${path}#${host}_Trojan_ws +hysteria://${currentHost}:${hysteriaPort}?protocol=${hysteriaProtocol}&auth=${id}&peer=${currentHost}&insecure=0&alpn=h3&upmbps=${hysteriaClientUploadSpeed}&downmbps=${hysteriaClientDownloadSpeed}#${email} EOF - echoContent yellow " ---> QR code Trojan-Go(WS+TLS) Shadowrocket" - echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=trojan%3a%2f%2f${id}%40${add}%3a${port}%3fallowInsecure%3d0%26peer%3d${host}%26plugin%3dobfs-local%3bobfs%3dwebsocket%3bobfs-host%3d${host}%3bobfs-uri%3d${path}%23${host}_Trojan_ws\n" - - path=$(echo "${path}" | awk -F "[/]" '{print $2}') - echoContent yellow " ---> Trojan-Go(WS+TLS) QV2ray" - - cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" -trojan-go://${id}@${add}:${port}?sni=${host}&type=ws&host=${host}&path=%2F${path}#${host}_Trojan_ws -EOF - - echoContent green " trojan-go://${id}@${add}:${port}?sni=${host}&type=ws&host=${host}&path=%2F${path}#${host}_Trojan_ws\n" - + echoContent yellow " ---> QR code Hysteria(TLS)" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=hysteria%3A%2F%2F${currentHost}%3A${hysteriaPort}%3Fprotocol%3D${hysteriaProtocol}%26auth%3D${id}%26peer%3D${currentHost}%26insecure%3D0%26alpn%3Dh3%26upmbps%3D${hysteriaClientUploadSpeed}%26downmbps%3D${hysteriaClientDownloadSpeed}%23${email}\n" fi + } + # account showAccounts() { readInstallType readInstallProtocolType readConfigHostPathUUID - echoContent skyBlue "\n schedule $1/${totalProgress} : account" + readHysteriaConfig + echoContent skyBlue "\nProgress $1/${totalProgress} : Account" local show # VLESS TCP if [[ -n "${configPath}" ]]; then show=1 - if echo "${currentInstallProtocolType}" | grep -q trojan ;then + if echo "${currentInstallProtocolType}" | grep -q trojan; then echoContent skyBlue "===================== Trojan TCP TLS/XTLS-direct/XTLS-splice ======================\n" - # cat ${configPath}02_VLESS_TCP_inbounds.json | jq .inbounds[0].settings.clients | jq -c '.[]' jq .inbounds[0].settings.clients ${configPath}02_trojan_TCP_inbounds.json | jq -c '.[]' | while read -r user; do - echoContent skyBlue "\n ---> account number:$(echo "${user}" | jq -r .email )_$(echo "${user}" | jq -r .password)" - echo - defaultBase64Code trojanTCPXTLS $(echo "${user}" | jq -r .email) $(echo "${user}" | jq -r .password) "${currentHost}:${currentPort}" ${currentHost} + local email= + email=$(echo "${user}" | jq -r .email) + echoContent skyBlue "\n ---> Account:${email}" + defaultBase64Code trojanTCPXTLS "${email}" "$(echo "${user}" | jq -r .password)" done else echoContent skyBlue "===================== VLESS TCP TLS/XTLS-direct/XTLS-splice ======================\n" - # cat ${configPath}02_VLESS_TCP_inbounds.json | jq .inbounds[0].settings.clients | jq -c '.[]' jq .inbounds[0].settings.clients ${configPath}02_VLESS_TCP_inbounds.json | jq -c '.[]' | while read -r user; do - echoContent skyBlue "\n ---> account number:$(echo "${user}" | jq -r .email )_$(echo "${user}" | jq -r .id)" + local email= + email=$(echo "${user}" | jq -r .email) + + echoContent skyBlue "\n ---> Account:${email}" echo - defaultBase64Code vlesstcp $(echo "${user}" | jq -r .email) $(echo "${user}" | jq -r .id) "${currentHost}:${currentPort}" ${currentHost} + defaultBase64Code vlesstcp "${email}" "$(echo "${user}" | jq -r .id)" done fi - # VLESS WS if echo ${currentInstallProtocolType} | grep -q 1; then echoContent skyBlue "\n================================ VLESS WS TLS CDN ================================\n" - # cat ${configPath}03_VLESS_WS_inbounds.json | jq .inbounds[0].settings.clients | jq -c '.[]' jq .inbounds[0].settings.clients ${configPath}03_VLESS_WS_inbounds.json | jq -c '.[]' | while read -r user; do - echoContent skyBlue "\n ---> account number:$(echo "${user}" | jq -r .email )_$(echo "${user}" | jq -r .id)" + local email= + email=$(echo "${user}" | jq -r .email) + + echoContent skyBlue "\n ---> Account:${email}" echo local path="${currentPath}ws" - if [[ ${coreInstallType} == "1" ]]; then - echoContent yellow "Xrayof0-RTT path Will there be? ED = 2048, is not compatible with clients with V2Ray as the core, please manually delete? ED = 2048 after use\n" - path="${currentPath}ws?ed=2048" - fi - defaultBase64Code vlessws $(echo "${user}" | jq -r .email) $(echo "${user}" | jq -r .id) "${currentHost}:${currentPort}" ${path} ${currentAdd} + # if [[ ${coreInstallType} == "1" ]]; then + # echoContent yellow "Xray's 0-RTT path will be behind it.It is not compatible with v2ray-based clients.Please delete it manually and use it\n" + # path="${currentPath}ws" + # fi + defaultBase64Code vlessws "${email}" "$(echo "${user}" | jq -r .id)" done fi @@ -2617,24 +3327,32 @@ showAccounts() { echoContent skyBlue "\n================================ VMess WS TLS CDN ================================\n" local path="${currentPath}vws" if [[ ${coreInstallType} == "1" ]]; then - path="${currentPath}vws?ed=2048" + path="${currentPath}vws" fi jq .inbounds[0].settings.clients ${configPath}05_VMess_WS_inbounds.json | jq -c '.[]' | while read -r user; do - echoContent skyBlue "\n ---> 账号:$(echo "${user}" | jq -r .email )_$(echo "${user}" | jq -r .id)" + local email= + email=$(echo "${user}" | jq -r .email) + + echoContent skyBlue "\n ---> Account:${email}" echo - defaultBase64Code vmessws $(echo "${user}" | jq -r .email) $(echo "${user}" | jq -r .id) "${currentHost}:${currentPort}" ${path} ${currentAdd} + defaultBase64Code vmessws "${email}" "$(echo "${user}" | jq -r .id)" done fi # VLESS grpc if echo ${currentInstallProtocolType} | grep -q 5; then echoContent skyBlue "\n=============================== VLESS gRPC TLS CDN ===============================\n" - echoContent red "\n --->gRPC Currently in the test phase, it may not be compatible with the client you use, if you can't use it, please ignore" - local serviceName=$(jq -r .inbounds[0].streamSettings.grpcSettings.serviceName ${configPath}06_VLESS_gRPC_inbounds.json) + echoContent red "\n ---> gRPC is in the testing stage and may not be compatible with the client you are using.If it cannot be used, please ignore it" + # local serviceName + # serviceName=$(jq -r .inbounds[0].streamSettings.grpcSettings.serviceName ${configPath}06_VLESS_gRPC_inbounds.json) jq .inbounds[0].settings.clients ${configPath}06_VLESS_gRPC_inbounds.json | jq -c '.[]' | while read -r user; do - echoContent skyBlue "\n ---> account number:$(echo "${user}" | jq -r .email )_$(echo "${user}" | jq -r .id)" + + local email= + email=$(echo "${user}" | jq -r .email) + + echoContent skyBlue "\n ---> Account:${email}" echo - defaultBase64Code vlessgrpc $(echo "${user}" | jq -r .email) $(echo "${user}" | jq -r .id) "${currentHost}:${currentPort}" ${serviceName} ${currentAdd} + defaultBase64Code vlessgrpc "${email}" "$(echo "${user}" | jq -r .id)" done fi fi @@ -2643,47 +3361,171 @@ showAccounts() { if echo ${currentInstallProtocolType} | grep -q 4; then echoContent skyBlue "\n================================== Trojan TLS ==================================\n" jq .inbounds[0].settings.clients ${configPath}04_trojan_TCP_inbounds.json | jq -c '.[]' | while read -r user; do - echoContent skyBlue "\n ---> account number:$(echo "${user}" | jq -r .email )_$(echo "${user}" | jq -r .password)" - echo - defaultBase64Code trojan trojan $(echo "${user}" | jq -r .password) ${currentHost} + local email= + email=$(echo "${user}" | jq -r .email) + echoContent skyBlue "\n ---> Account:${email}" + + defaultBase64Code trojan "${email}" "$(echo "${user}" | jq -r .password)" done fi if echo ${currentInstallProtocolType} | grep -q 2; then echoContent skyBlue "\n================================ Trojan gRPC TLS ================================\n" - echoContent red "\n --->gRPC Currently in the test phase, it may not be compatible with the client you use, if you can't use it, please ignore" - local serviceName=$(jq -r .inbounds[0].streamSettings.grpcSettings.serviceName ${configPath}04_trojan_gRPC_inbounds.json) + echoContent red "\n ---> gRPC is in the testing stage and may not be compatible with the client you are using.If it cannot be used, please ignore it" jq .inbounds[0].settings.clients ${configPath}04_trojan_gRPC_inbounds.json | jq -c '.[]' | while read -r user; do - echoContent skyBlue "\n ---> account number:$(echo "${user}" | jq -r .email )_$(echo "${user}" | jq -r .password)" + local email= + email=$(echo "${user}" | jq -r .email) + + echoContent skyBlue "\n ---> Account:${email}" echo - defaultBase64Code trojangrpc $(echo "${user}" | jq -r .email) $(echo "${user}" | jq -r .password) "${currentHost}:${currentPort}" ${serviceName} ${currentAdd} + defaultBase64Code trojangrpc "${email}" "$(echo "${user}" | jq -r .password)" done fi + if echo ${currentInstallProtocolType} | grep -q 6; then + echoContent skyBlue "\n================================ Hysteria TLS ================================\n" + echoContent red "\n ---> The speed of Hysteria depends on the local network environment.If it is used by QoS, the experience will be very poor.IDC may also consider it an attack, please use it with caution" + + jq .auth.config ${hysteriaConfigPath}config.json | jq -r '.[]' | while read -r user; do + local defaultUser= + local uuidType= + uuidType=".id" + + if [[ "${frontingType}" == "02_trojan_TCP_inbounds" ]]; then + uuidType=".password" + fi + + defaultUser=$(jq '.inbounds[0].settings.clients[]|select('${uuidType}'=="'"${user}"'")' ${configPath}${frontingType}.json) + local email= + email=$(echo "${defaultUser}" | jq -r .email) + + if [[ -n ${defaultUser} ]]; then + echoContent skyBlue "\n ---> Account:${email}" + echo + defaultBase64Code hysteria "${email}" "${user}" + fi + + done + + fi if [[ -z ${show} ]]; then - echoContent red " ---> Not Installed" + echoContent red "---> not installed" + fi +} +# Remove nginx302 configuration +removeNginx302() { + local count=0 + grep -n "return 302" <"/etc/nginx/conf.d/alone.conf" | while read -r line; do + + if ! echo "${line}" | grep -q "request_uri"; then + local removeIndex= + removeIndex=$(echo "${line}" | awk -F "[:]" '{print $1}') + removeIndex=$((removeIndex + count)) + sed -i "${removeIndex}d" /etc/nginx/conf.d/alone.conf + count=$((count - 1)) + fi + done +} + +# Check if 302 is successful +checkNginx302() { + local domain302Status= + domain302Status=$(curl -s "https://${currentHost}") + if echo "${domain302Status}" | grep -q "302"; then + local domain302Result= + domain302Result=$(curl -L -s "https://${currentHost}") + if [[ -n "${domain302Result}" ]]; then + echoContent green "---> 302 redirection set successfully" + exit 0 + fi + fi + echoContent red "---> 302 redirection setting failed, please double check if it is the same as the example" + backupNginxConfig restoreBackup +} + +# Backup and restore nginx files +backupNginxConfig() { + if [[ "$1" == "backup" ]]; then + cp /etc/nginx/conf.d/alone.conf /etc/v2ray-agent/alone_backup.conf + echoContent green " ---> nginx configuration file backup successfully" + fi + + if [[ "$1" == "restoreBackup" ]] && [[ -f "/etc/v2ray-agent/alone_backup.conf" ]]; then + cp /etc/v2ray-agent/alone_backup.conf /etc/nginx/conf.d/alone.conf + echoContent green " ---> nginx configuration file restore and backup successfully" + rm /etc/v2ray-agent/alone_backup.conf fi + +} +# Add 302 configuration +addNginx302() { + # local line302Result= + # line302Result=$(| tail -n 1) + local count=1 + grep -n "Strict-Transport-Security" <"/etc/nginx/conf.d/alone.conf" | while read -r line; do + if [[ -n "${line}" ]]; then + local insertIndex= + insertIndex="$(echo "${line}" | awk -F "[:]" '{print $1}')" + insertIndex=$((insertIndex + count)) + sed "${insertIndex}i return 302 '$1';" /etc/nginx/conf.d/alone.conf >/etc/nginx/conf.d/tmpfile && mv /etc/nginx/conf.d/tmpfile /etc/nginx/conf.d/alone.conf + count=$((count + 1)) + else + echoContent red "---> 302 Add failed" + backupNginxConfig restoreBackup + fi + + done } # Update camouflage station updateNginxBlog() { - echoContent skyBlue "\n schedule$1/${totalProgress} : Replace the camouflage site" + echoContent skyBlue "\nProgress $1/${totalProgress} : Change fake site" echoContent red "==============================================================" - echoContent yellow "# To customize, manually copy the template file to /usr/share/nginx/html \n" - echoContent yellow "1.Beginner's guide" + echoContent yellow "# For customization, please manually copy the template file to /usr/share/nginx/html \n" + echoContent yellow "1.Novice guide" echoContent yellow "2.Game website" - echoContent yellow "3.personal blog01" - echoContent yellow "4.Businesses" - echoContent yellow "5.Unlock the encrypted music file template[https://github.com/ix64/unlock-music]" + echoContent yellow "3.Personal blog 01" + echoContent yellow "4.Enterprise Station" + echoContent yellow "5.Unlock the encrypted music file template [https://github.com/ix64/unlock-music]" echoContent yellow "6.mikutap[https://github.com/HFIProgramming/mikutap]" echoContent yellow "7.Enterprise station 02" echoContent yellow "8.Personal blog 02" - echoContent yellow "9.404 Automatic jump Baidu" + echoContent yellow "9.404 Automatically jump to baidu" + echoContent yellow "10.302 redirect site" echoContent red "==============================================================" - read -r -p "please choose:" selectInstallNginxBlogType + read -r -p "Please select:" selectInstallNginxBlogType + + if [[ "${selectInstallNginxBlogType}" == "10" ]]; then + echoContent red "\n==============================================================" + echoContent yellow "The priority of redirection is higher.If you change the fake site after configuring 302, the fake site under the root route will not work" + echoContent yellow "If you want to disguise the site to achieve the effect, you need to delete the 302 redirect configuration\n" + echoContent yellow "1.Add" + echoContent yellow "2.Delete" + echoContent red "==============================================================" + read -r -p "Please select:" redirectStatus + if [[ "${redirectStatus}" == "1" ]]; then + backupNginxConfig backup + read -r -p "Please enter the domain name to be redirected, such as https://www.baidu.com:" redirectDomain + removeNginx302 + addNginx302 "${redirectDomain}" + handleNginx stop + handleNginx start + if [[ -z $(pgrep -f nginx) ]]; then + backupNginxConfig restoreBackup + handleNginx start + exit 0 + fi + checkNginx302 + exit 0 + fi + if [[ "${redirectStatus}" == "2" ]]; then + removeNginx302 + echoContent green " ---> Remove 302 redirect successfully" + exit 0 + fi + fi if [[ "${selectInstallNginxBlogType}" =~ ^[1-9]$ ]]; then -# rm -rf /usr/share/nginx/html rm -rf /usr/share/nginx/* if wget --help | grep -q show-progress; then wget -c -q --show-progress -P /usr/share/nginx "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${selectInstallNginxBlogType}.zip" >/dev/null @@ -2693,125 +3535,172 @@ updateNginxBlog() { unzip -o "/usr/share/nginx/html${selectInstallNginxBlogType}.zip" -d /usr/share/nginx/html >/dev/null rm -f "/usr/share/nginx/html${selectInstallNginxBlogType}.zip*" - echoContent green " ---> Replace the pseudo-station success" + echoContent green " ---> Replace the fake station successfully" else - echoContent red " ---> Select an error, please re-select" + echoContent red " ---> Selection error, please select again" updateNginxBlog fi } -# Add a new port +# add new port addCorePort() { - echoContent skyBlue "\n Function 1/${totalProgress} : Add a new port" + echoContent skyBlue "\nFunction 1/${totalProgress} : add new port" echoContent red "\n==============================================================" - echoContent yellow "# Precautions\n" - echoContent yellow "Support quantity added" - echoContent yellow "Does not affect the use of 443 ports" - echoContent yellow "When you view your account, you will only show the account number of the default port 443." - echoContent yellow "Do not allow special characters, pay attention to the format of comma" - echoContent yellow "Entry example: 2053, 2083, 2087\n" - - echoContent yellow "1.Adding ports" + echoContent yellow "# Notes\n" + echoContent yellow "Support batch add" + echoContent yellow "does not affect the use of the default port" + echoContent yellow "When viewing an account, only the account with the default port will be displayed" + echoContent yellow "Special characters are not allowed, pay attention to the comma format" + echoContent yellow "Entry example: 2053,2083,2087\n" + + echoContent yellow "1.Add port" echoContent yellow "2.Delete port" echoContent red "==============================================================" - read -r -p "please choose:" selectNewPortType + read -r -p "Please select:" selectNewPortType if [[ "${selectNewPortType}" == "1" ]]; then read -r -p "Please enter the port number:" newPort + read -r -p "Please enter the default port number, the subscription port and node port will be changed at the same time, [Enter] default 443:" defaultPort + + if [[ -n "${defaultPort}" ]]; then + rm -rf "$(find ${configPath}* | grep "default")" + fi + if [[ -n "${newPort}" ]]; then while read -r port; do - cat <${configPath}02_dokodemodoor_inbounds_${port}.json + rm -rf "$(find ${configPath}* | grep "${port}")" + + local fileName= + if [[ -n "${defaultPort}" && "${port}" == "${defaultPort}" ]]; then + fileName="${configPath}02_dokodemodoor_inbounds_${port}_default.json" + else + fileName="${configPath}02_dokodemodoor_inbounds_${port}.json" + fi + + # open port + allowPort "${port}" + + local settingsPort=443 + if [[ -n "${customPort}" ]]; then + settingsPort=${customPort} + fi + + cat <"${fileName}" { "inbounds": [ - { - "listen": "0.0.0.0", - "port": ${port}, - "protocol": "dokodemo-door", - "settings": { - "address": "127.0.0.1", - "port": 443, - "network": "tcp", - "followRedirect": false - }, - "tag": "dokodemo-door-newPort-${port}" - } + { + "listen": "0.0.0.0", + "port": ${port}, + "protocol": "dokodemo-door", + "settings": { + "address": "127.0.0.1", + "port": ${settingsPort}, + "network": "tcp", + "followRedirect": false + }, + "tag": "dokodemo-door-newPort-${port}" + } ] } EOF done < <(echo "${newPort}" | tr ',' '\n') - echoContent green " ---> Added successfully" + echoContent green " ---> Add successfully" reloadCore fi elif [[ "${selectNewPortType}" == "2" ]]; then - ls ${configPath} | grep dokodemodoor | awk -F "[_]" '{print $4}' | awk -F "[.]" '{print ""NR""":"$1}' - read -r -p "Please enter the port number you want to delete:" portIndex - - local dokoConfig=$(ls ${configPath} | grep dokodemodoor | awk '{print ""NR""":"$1}' | grep ${portIndex}":") + find ${configPath} -name "*dokodemodoor*" | awk -F "[c][o][n][f][/]" '{print ""NR""":"$2}' + read -r -p "Please enter the port number to delete:" portIndex + local dokoConfig + dokoConfig=$(find ${configPath} -name "*dokodemodoor*" | awk -F "[c][o][n][f][/]" '{print ""NR""":"$2}' | grep "${portIndex}:") if [[ -n "${dokoConfig}" ]]; then - rm ${configPath}/$(echo "${dokoConfig}" | awk -F "[:]" '{print $2}') + rm "${configPath}/$(echo "${dokoConfig}" | awk -F "[:]" '{print $2}')" reloadCore else - echoContent yellow "\n ---> Number Enter an error, please re-select" + echoContent yellow "\n ---> The input number is wrong, please select again" addCorePort fi fi } -# Uninstall +# uninstall script unInstall() { - read -r -p "Do you confirm that uninstall installation content?[y/n]:" unInstallStatus + read -r -p "Are you sure to uninstall the installation content? [y/n]:" unInstallStatus if [[ "${unInstallStatus}" != "y" ]]; then - echoContent green " ---> Abandon unload" + echoContent green " ---> Abort uninstall" menu exit 0 fi handleNginx stop if [[ -z $(pgrep -f "nginx") ]]; then - echoContent green " ---> Stop Nginx success" + echoContent green "---> stop Nginx successfully" fi - handleV2Ray stop -# handleTrojanGo stop + if [[ "${coreInstallType}" == "1" ]]; then + handleXray stop + rm -rf /etc/systemd/system/xray.service + echoContent green " ---> Delete Xray boot auto-start complete" + + elif [[ "${coreInstallType}" == "2" ]]; then + + handleV2Ray stop + rm -rf /etc/systemd/system/v2ray.service + echoContent green " ---> Delete V2Ray boot auto-start complete" + + fi + + if [[ -z "${hysteriaConfigPath}" ]]; then + handleHysteria stop + rm -rf /etc/systemd/system/hysteria.service + echoContent green " ---> Delete Hysteria boot auto-start complete" + fi + + if [[ -f "/root/.acme.sh/acme.sh.env" ]] && grep -q 'acme.sh.env' Delete acme.sh complete" - rm -rf /etc/systemd/system/v2ray.service - echoContent green " ---> Delete V2RAY boot self-start" + echoContent green "---> delete acme.sh complete" - rm -rf /etc/systemd/system/trojan-go.service - echoContent green " ---> Delete Trojan-GO boot self-start" rm -rf /tmp/v2ray-agent-tls/* if [[ -d "/etc/v2ray-agent/tls" ]] && [[ -n $(find /etc/v2ray-agent/tls/ -name "*.key") ]] && [[ -n $(find /etc/v2ray-agent/tls/ -name "*.crt") ]]; then mv /etc/v2ray-agent/tls /tmp/v2ray-agent-tls if [[ -n $(find /tmp/v2ray-agent-tls -name '*.key') ]]; then - echoContent yellow " ---> Keep paying attention to the backup certificate.[/tmp/v2ray-agent-tls]" + echoContent yellow " ---> The backup certificate is successful, please keep it.[/tmp/v2ray-agent-tls]" fi fi rm -rf /etc/v2ray-agent - rm -rf /etc/nginx/conf.d/alone.conf + rm -rf ${nginxConfigPath}alone.conf + + if [[ -d "/usr/share/nginx/html" && -f "/usr/share/nginx/html/check" ]]; then + rm -rf /usr/share/nginx/html + echoContent green " ---> Delete the fake website completed" + fi + rm -rf /usr/bin/vasma rm -rf /usr/sbin/vasma - echoContent green " ---> Uninstall shortcut" - echoContent green " ---> Uninstall V2RAY-Agent script completion" + echoContent green " ---> Uninstall shortcut completed" + echoContent green "---> Uninstall v2ray-agent script completed" } -# Modify V2RAY CDN node +#updateGeoSite + +# Modify V2Ray CDN node updateV2RayCDN() { - # todo Reconstruct this method - echoContent skyBlue "\n progress $1/${totalProgress} : Modify CDN node" + # todo refactor this method + echoContent skyBlue "\nProgress $1/${totalProgress} : Modify CDN node" - if [[ -n ${currentAdd} ]]; then + if [[ -n "${currentAdd}" ]]; then echoContent red "==============================================================" echoContent yellow "1.CNAME www.digitalocean.com" echoContent yellow "2.CNAME www.cloudflare.com" echoContent yellow "3.CNAME hostmonit.com" echoContent yellow "4.Manual input" echoContent red "==============================================================" - read -r -p "please choose:" selectCDNType + read -r -p "Please select:" selectCDNType case ${selectCDNType} in 1) setDomain="www.digitalocean.com" @@ -2823,278 +3712,268 @@ updateV2RayCDN() { setDomain="hostmonit.com" ;; 4) - read -r -p "Please enter you want to customize CDN IP or domain name:" setDomain + read -r -p "Please enter the CDN IP or domain name you want to customize:" setDomain ;; esac if [[ -n ${setDomain} ]]; then - if [[ -n ${currentAdd} ]]; then - sed -i "s/\"${currentAdd}\"/\"${setDomain}\"/g" $(grep "${currentAdd}" -rl ${configPath}${frontingType}.json) + if [[ -n "${currentAdd}" ]]; then + sed -i "s/\"${currentAdd}\"/\"${setDomain}\"/g" "$(grep "${currentAdd}" -rl ${configPath}${frontingType}.json)" fi - if [[ $(jq -r .inbounds[0].settings.clients[0].add ${configPath}${frontingType}.json) == ${setDomain} ]]; then - echoContent green " ---> CDN is successful" + if [[ $(jq -r .inbounds[0].settings.clients[0].add ${configPath}${frontingType}.json) == "${setDomain}" ]]; then + echoContent green " ---> CDN modified successfully" reloadCore else - echoContent red " ---> Modify CDN failure" + echoContent red " ---> Failed to modify CDN" fi fi else - echoContent red " ---> No available types" + echoContent red " ---> Available types are not installed" fi } -# manageUser User Management +# manageUser user management manageUser() { - echoContent skyBlue "\n progress $1/${totalProgress} : Multi-user management" + echoContent skyBlue "\nProgress $1/${totalProgress} : multi-user management" echoContent skyBlue "-----------------------------------------------------" echoContent yellow "1.Add user" - echoContent yellow "2.delete users" + echoContent yellow "2.Delete user" echoContent skyBlue "-----------------------------------------------------" - read -r -p "please choose:" manageUserType + read -r -p "Please select:" manageUserType if [[ "${manageUserType}" == "1" ]]; then addUser elif [[ "${manageUserType}" == "2" ]]; then removeUser else - echoContent red " ---> wrong selection" + echoContent red " ---> Selection error" fi } -# Customize UUID +# custom uuid customUUID() { - read -r -p "Whether to customize UUID ?[y/n]:" customUUIDStatus + # read -r -p "Do you want to customize UUID? [y/n]:" customUUIDStatus + # echo + # if [[ "${customUUIDStatus}" == "y" ]]; then + read -r -p "Please enter a valid UUID, [Enter] Random UUID:" currentCustomUUID echo - if [[ "${customUUIDStatus}" == "y" ]]; then - read -r -p "Please enter the legal UUID:" currentCustomUUID - echo - if [[ -z "${currentCustomUUID}" ]]; then - echoContent red " ---> UUID can not be empty" - else - local repeat= - jq -r -c '.inbounds[0].settings.clients[].id' ${configPath}${frontingType}.json | while read -r line; do - if [[ "${line}" == "${currentCustomUUID}" ]]; then - echo repeat >/tmp/v2ray-agent - fi - done - if [[ -f "/tmp/v2ray-agent" && -n $(cat /tmp/v2ray-agent) ]]; then - echoContent red " ---> UUID is not repeatable" - rm /tmp/v2ray-agent - exit 0 + if [[ -z "${currentCustomUUID}" ]]; then + # echoContent red " ---> UUID cannot be empty" + currentCustomUUID=$(${ctlPath} uuid) + echoContent yellow "uuid:${currentCustomUUID}\n" + + else + jq -r -c '.inbounds[0].settings.clients[].id' ${configPath}${frontingType}.json | while read -r line; do + if [[ "${line}" == "${currentCustomUUID}" ]]; then + echo >/tmp/v2ray-agent fi + done + if [[ -f "/tmp/v2ray-agent" && -n $(cat /tmp/v2ray-agent) ]]; then + echoContent red "---> UUID cannot be repeated" + rm /tmp/v2ray-agent + exit 0 fi fi + # fi } -# Custom Email +# custom email customUserEmail() { - read -r -p "Whether to customize Email ?[y/n]:" customEmailStatus + # read -r -p "Do you want to customize email? [y/n]:" customEmailStatus + # echo + # if [[ "${customEmailStatus}" == "y" ]]; then + read -r -p "Please enter a valid email, [Enter] random email:" currentCustomEmail echo - if [[ "${customEmailStatus}" == "y" ]]; then - read -r -p "Please enter legitimate Email:" currentCustomEmail - echo - if [[ -z "${currentCustomEmail}" ]]; then - echoContent red " ---> Email is not empty" - else - local repeat= - jq -r -c '.inbounds[0].settings.clients[].email' ${configPath}${frontingType}.json | while read -r line; do - if [[ "${line}" == "${currentCustomEmail}" ]]; then - echo repeat >/tmp/v2ray-agent - fi - done - if [[ -f "/tmp/v2ray-agent" && -n $(cat /tmp/v2ray-agent) ]]; then - echoContent red " ---> Email is not repeatable" - rm /tmp/v2ray-agent - exit 0 + if [[ -z "${currentCustomEmail}" ]]; then + currentCustomEmail="${currentHost}_${currentCustomUUID}" + echoContent yellow "email: ${currentCustomEmail}\n" + # echoContent red " ---> email cannot be empty" + else + jq -r -c '.inbounds[0].settings.clients[].email' ${configPath}${frontingType}.json | while read -r line; do + if [[ "${line}" == "${currentCustomEmail}" ]]; then + echo >/tmp/v2ray-agent fi + done + if [[ -f "/tmp/v2ray-agent" && -n $(cat /tmp/v2ray-agent) ]]; then + echoContent red " ---> email cannot be repeated" + rm /tmp/v2ray-agent + exit 0 fi fi + # fi } # Add user addUser() { - echoContent yellow "After adding new users, you need to re-view subscriptions." - read -r -p "Please enter the number of users you want to add:" userNum + echoContent yellow "After adding a new user, you need to review the subscription again" + read -r -p "Please enter the number of users to add:" userNum echo if [[ -z ${userNum} || ${userNum} -le 0 ]]; then - echoContent red " ---> Enter is incorrect, please re-enter" + echoContent red " ---> Input error, please re-enter" exit 0 fi - # Generate users - local users= - local trojanGoUsers= + # generate user if [[ "${userNum}" == "1" ]]; then customUUID customUserEmail fi while [[ ${userNum} -gt 0 ]]; do - + local users= ((userNum--)) || true if [[ -n "${currentCustomUUID}" ]]; then uuid=${currentCustomUUID} else uuid=$(${ctlPath} uuid) fi + if [[ -n "${currentCustomEmail}" ]]; then email=${currentCustomEmail} else email=${currentHost}_${uuid} fi - if [[ ${userNum} == 0 ]]; then - - users=${users}{\"id\":\"${uuid}\",\"flow\":\"xtls-rprx-direct\",\"email\":\"${email}\",\"alterId\":0} + # Compatible with v2ray-core + users="{\"id\":\"${uuid}\",\"flow\":\"xtls-rprx-direct\",\"email\":\"${email}\",\"alterId\":0}" - if echo ${currentInstallProtocolType} | grep -q 4; then - trojanGoUsers=${trojanGoUsers}\"${uuid}\" - fi - else - users=${users}{\"id\":\"${uuid}\",\"flow\":\"xtls-rprx-direct\",\"email\":\"${email}\",\"alterId\":0}, - - if echo ${currentInstallProtocolType} | grep -q 4; then - trojanGoUsers=${trojanGoUsers}\"${uuid}\", - fi + if [[ "${coreInstallType}" == "2" ]]; then + users="{\"id\":\"${uuid}\",\"email\":\"${email}\",\"alterId\":0}" fi - done - - # Compatible with V2Ray-core - if [[ "${coreInstallType}" == "2" ]]; then - # | sed 's/"flow":"xtls-rprx-direct",/"alterId":1,/g') - users="${users//\"flow\":\"xtls-rprx-direct\"\,/}" - fi - - if echo ${currentInstallProtocolType} | grep -q 0; then - local vlessUsers="${users//\,\"alterId\":0/}" - local vlessTcpResult - vlessTcpResult=$(jq -r '.inbounds[0].settings.clients += ['${vlessUsers}']' ${configPath}${frontingType}.json) - echo "${vlessTcpResult}" | jq . >${configPath}${frontingType}.json - fi + if echo ${currentInstallProtocolType} | grep -q 0; then + local vlessUsers="${users//\,\"alterId\":0/}" - if echo ${currentInstallProtocolType} | grep -q trojan; then - local trojanXTLSUsers="${users//\,\"alterId\":0/}" - trojanXTLSUsers=${trojanXTLSUsers//"id"/"password"} - echo trojanXTLSUsers:${trojanXTLSUsers} - local trojanXTLSResult - trojanXTLSResult=$(jq -r '.inbounds[0].settings.clients += ['${trojanXTLSUsers}']' ${configPath}${frontingType}.json) - echo "${trojanXTLSResult}" | jq . >${configPath}${frontingType}.json - fi + local vlessTcpResult + vlessTcpResult=$(jq -r ".inbounds[0].settings.clients += [${vlessUsers}]" ${configPath}${frontingType}.json) + echo "${vlessTcpResult}" | jq .>${configPath}${frontingType}.json + fi - # users="${users//"flow":"xtls-rprx-direct",/"alterId":1,}" + if echo ${currentInstallProtocolType} | grep -q trojan; then + local trojanXTLSUsers="${users//\,\"alterId\":0/}" + trojanXTLSUsers=${trojanXTLSUsers//"id"/"password"} - if echo ${currentInstallProtocolType} | grep -q 1; then - local vlessUsers="${users//\,\"alterId\":0/}" - vlessUsers="${vlessUsers//\"flow\":\"xtls-rprx-direct\"\,/}" - local vlessWsResult - vlessWsResult=$(jq -r '.inbounds[0].settings.clients += ['${vlessUsers}']' ${configPath}03_VLESS_WS_inbounds.json) - echo "${vlessWsResult}" | jq . >${configPath}03_VLESS_WS_inbounds.json - fi + local trojanXTLSResult + trojanXTLSResult=$(jq -r ".inbounds[0].settings.clients += [${trojanXTLSUsers}]" ${configPath}${frontingType}.json) + echo "${trojanXTLSResult}" | jq .>${configPath}${frontingType}.json + fi - if echo ${currentInstallProtocolType} | grep -q 2; then - local trojangRPCUsers="${users//\"flow\":\"xtls-rprx-direct\"\,/}" - trojangRPCUsers="${trojangRPCUsers//\,\"alterId\":0/}" - trojangRPCUsers=${trojangRPCUsers//"id"/"password"} + if echo ${currentInstallProtocolType} | grep -q 1; then + local vlessUsers="${users//\,\"alterId\":0/}" + vlessUsers="${vlessUsers//\"flow\":\"xtls-rprx-direct\"\,/}" + local vlessWsResult + vlessWsResult=$(jq -r ".inbounds[0].settings.clients += [${vlessUsers}]" ${configPath}03_VLESS_WS_inbounds.json) + echo "${vlessWsResult}" | jq .>${configPath}03_VLESS_WS_inbounds.json + fi - local trojangRPCResult - trojangRPCResult=$(jq -r '.inbounds[0].settings.clients += ['${trojangRPCUsers}']' ${configPath}04_trojan_gRPC_inbounds.json) - echo "${trojangRPCResult}" | jq . >${configPath}04_trojan_gRPC_inbounds.json - fi + if echo ${currentInstallProtocolType} | grep -q 2; then + local trojangRPCUsers="${users//\"flow\":\"xtls-rprx-direct\"\,/}" + trojangRPCUsers="${trojangRPCUsers//\,\"alterId\":0/}" + trojangRPCUsers=${trojangRPCUsers//"id"/"password"} - if echo ${currentInstallProtocolType} | grep -q 3; then - local vmessUsers="${users//\"flow\":\"xtls-rprx-direct\"\,/}" + local trojangRPCResult + trojangRPCResult=$(jq -r ".inbounds[0].settings.clients += [${trojangRPCUsers}]" ${configPath}04_trojan_gRPC_inbounds.json) + echo "${trojangRPCResult}" | jq .>${configPath}04_trojan_gRPC_inbounds.json + fi - local vmessWsResult - vmessWsResult=$(jq -r '.inbounds[0].settings.clients += ['${vmessUsers}']' ${configPath}05_VMess_WS_inbounds.json) - echo "${vmessWsResult}" | jq . >${configPath}05_VMess_WS_inbounds.json - fi + if echo ${currentInstallProtocolType} | grep -q 3; then + local vmessUsers="${users//\"flow\":\"xtls-rprx-direct\"\,/}" - if echo ${currentInstallProtocolType} | grep -q 5; then - local vlessGRPCUsers="${users//\"flow\":\"xtls-rprx-direct\"\,/}" - vlessGRPCUsers="${vlessGRPCUsers//\,\"alterId\":0/}" + local vmessWsResult + vmessWsResult=$(jq -r ".inbounds[0].settings.clients += [${vmessUsers}]" ${configPath}05_VMess_WS_inbounds.json) + echo "${vmessWsResult}" | jq .>${configPath}05_VMess_WS_inbounds.json + fi - local vlessGRPCResult - vlessGRPCResult=$(jq -r '.inbounds[0].settings.clients += ['${vlessGRPCUsers}']' ${configPath}06_VLESS_gRPC_inbounds.json) - echo "${vlessGRPCResult}" | jq . >${configPath}06_VLESS_gRPC_inbounds.json - fi + if echo ${currentInstallProtocolType} | grep -q 5; then + local vlessGRPCUsers="${users//\"flow\":\"xtls-rprx-direct\"\,/}" + vlessGRPCUsers="${vlessGRPCUsers//\,\"alterId\":0/}" - if echo ${currentInstallProtocolType} | grep -q 4; then - local trojanUsers="${users//\"flow\":\"xtls-rprx-direct\"\,/}" - trojanUsers="${trojanUsers//id/password}" - trojanUsers="${trojanUsers//\,\"alterId\":0/}" + local vlessGRPCResult + vlessGRPCResult=$(jq -r ".inbounds[0].settings.clients += [${vlessGRPCUsers}]" ${configPath}06_VLESS_gRPC_inbounds.json) + echo "${vlessGRPCResult}" | jq .>${configPath}06_VLESS_gRPC_inbounds.json + fi + if echo ${currentInstallProtocolType} | grep -q 4; then + local trojanUsers="${users//\"flow\":\"xtls-rprx-direct\"\,/}" + trojanUsers="${trojanUsers//id/password}" + trojanUsers="${trojanUsers//\,\"alterId\":0/}" - local trojanTCPResult - trojanTCPResult=$(jq -r '.inbounds[0].settings.clients += ['${trojanUsers}']' ${configPath}04_trojan_TCP_inbounds.json) - echo "${trojanTCPResult}" | jq . >${configPath}04_trojan_TCP_inbounds.json - fi + local trojanTCPResult + trojanTCPResult=$(jq -r ".inbounds[0].settings.clients += [${trojanUsers}]" ${configPath}04_trojan_TCP_inbounds.json) + echo "${trojanTCPResult}" | jq .>${configPath}04_trojan_TCP_inbounds.json + fi -# if echo ${currentInstallProtocolType} | grep -q 4; then -# local trojanResult -# trojanResult=$(jq -r '.password += ['${trojanGoUsers}']' ${configPath}../../trojan/config_full.json) -# echo "${trojanResult}" | jq . >${configPath}../../trojan/config_full.json -# handleTrojanGo stop -# handleTrojanGo start -# fi + if echo ${currentInstallProtocolType} | grep -q 6; then + local hysteriaResult + hysteriaResult=$(jq -r ".auth.config += [\"${uuid}\"]" ${hysteriaConfigPath}config.json) + echo "${hysteriaResult}" | jq .>${hysteriaConfigPath}config.json + fi + done reloadCore - echoContent green " ---> Add completion" - showAccounts 1 + echoContent green " ---> Add complete" + manageAccount 1 } -# Remove user +# remove user removeUser() { - if echo ${currentInstallProtocolType} | grep -q 0 || echo ${currentInstallProtocolType} | grep -q trojan ; then + if echo ${currentInstallProtocolType} | grep -q 0 || echo ${currentInstallProtocolType} | grep -q trojan; then jq -r -c .inbounds[0].settings.clients[].email ${configPath}${frontingType}.json | awk '{print NR""":"$0}' - read -r -p "Please select the user number you want to delete[Also supports single deletion]:" delUserIndex + read -r -p "Please select the user number to delete [only single delete is supported]:" delUserIndex if [[ $(jq -r '.inbounds[0].settings.clients|length' ${configPath}${frontingType}.json) -lt ${delUserIndex} ]]; then - echoContent red " ---> wrong selection" + echoContent red " ---> Selection error" else - delUserIndex=$((${delUserIndex} - 1)) + delUserIndex=$((delUserIndex - 1)) local vlessTcpResult vlessTcpResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}${frontingType}.json) - echo "${vlessTcpResult}" | jq . >${configPath}${frontingType}.json + echo "${vlessTcpResult}" | jq .>${configPath}${frontingType}.json fi fi if [[ -n "${delUserIndex}" ]]; then if echo ${currentInstallProtocolType} | grep -q 1; then local vlessWSResult vlessWSResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}03_VLESS_WS_inbounds.json) - echo "${vlessWSResult}" | jq . >${configPath}03_VLESS_WS_inbounds.json + echo "${vlessWSResult}" | jq .>${configPath}03_VLESS_WS_inbounds.json fi if echo ${currentInstallProtocolType} | grep -q 2; then local trojangRPCUsers trojangRPCUsers=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}04_trojan_gRPC_inbounds.json) - echo "${trojangRPCUsers}" | jq . >${configPath}04_trojan_gRPC_inbounds.json + echo "${trojangRPCUsers}" | jq .>${configPath}04_trojan_gRPC_inbounds.json fi if echo ${currentInstallProtocolType} | grep -q 3; then local vmessWSResult vmessWSResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}05_VMess_WS_inbounds.json) - echo "${vmessWSResult}" | jq . >${configPath}05_VMess_WS_inbounds.json + echo "${vmessWSResult}" | jq .>${configPath}05_VMess_WS_inbounds.json fi if echo ${currentInstallProtocolType} | grep -q 5; then local vlessGRPCResult vlessGRPCResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}06_VLESS_gRPC_inbounds.json) - echo "${vlessGRPCResult}" | jq . >${configPath}06_VLESS_gRPC_inbounds.json + echo "${vlessGRPCResult}" | jq .>${configPath}06_VLESS_gRPC_inbounds.json fi if echo ${currentInstallProtocolType} | grep -q 4; then local trojanTCPResult trojanTCPResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}04_trojan_TCP_inbounds.json) - echo "${trojanTCPResult}" | jq . >${configPath}04_trojan_TCP_inbounds.json + echo "${trojanTCPResult}" | jq .>${configPath}04_trojan_TCP_inbounds.json + fi + + if echo ${currentInstallProtocolType} | grep -q 6; then + local hysteriaResult + hysteriaResult=$(jq -r 'del(.auth.config['${delUserIndex}'])' ${hysteriaConfigPath}config.json) + echo "${hysteriaResult}" | jq .>${hysteriaConfigPath}config.json fi reloadCore fi + manageAccount 1 } -# Update script +# Updated script updateV2RayAgent() { - echoContent skyBlue "\n progress $1/${totalProgress} : Update V2RAY-Agent script" + echoContent skyBlue "\nProgress $1/${totalProgress} : Update v2ray-agent script" rm -rf /etc/v2ray-agent/install.sh if wget --help | grep -q show-progress; then wget -c -q --show-progress -P /etc/v2ray-agent/ -N --no-check-certificate "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/install.sh" @@ -3103,41 +3982,42 @@ updateV2RayAgent() { fi sudo chmod 700 /etc/v2ray-agent/install.sh - local version=$(cat /etc/v2ray-agent/install.sh | grep 'Current version: v' | awk -F "[v]" '{print $2}' | tail -n +2 | head -n 1 | awk -F "[\"]" '{print $1}') - - echoContent green "\n ---> update completed" - echoContent yellow " ---> Please manually[vasma]Open script" - echoContent green " ---> current version:${version}\n" - echoContent yellow "If the update is unsuccessful, please manually perform the following command.\n" - echoContent skyBlue "wget -P /root -N --no-check-certificate "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/install.sh" && chmod 700 /root/install.sh && /root/install.sh" + local version + version=$(grep 'Current version:v' "/etc/v2ray-agent/install.sh" | awk -F "[v]" '{print $2}' | tail -n +2 | head -n 1 | awk -F "[\"]" '{print $1}') + + echoContent green "\n ---> Update completed" + echoContent yellow " ---> Please manually execute [vasma] to open the script" + echoContent green " ---> Current version: ${version}\n" + echoContent yellow "If the update is unsuccessful, please manually execute the following command\n" + echoContent skyBlue "wget -P /root -N --no-check-certificate https://raw.githubusercontent.com/mack-a/v2ray-agent/master/install.sh && chmod 700 /root/install.sh && /root/install.sh" echo exit 0 } # Firewall -handleFirewall(){ - if systemctl status ufw 2>/dev/null|grep -q "active (exited)" && [[ "$1" == "stop" ]]; then +handleFirewall() { + if systemctl status ufw 2>/dev/null | grep -q "active (exited)" && [[ "$1" == "stop" ]]; then systemctl stop ufw >/dev/null 2>&1 systemctl disable ufw >/dev/null 2>&1 - echoContent green " ---> ufw Close successfully" + echoContent green "---> ufw closed successfully" fi - if systemctl status firewalld 2>/dev/null|grep -q "active (running)" && [[ "$1" == "stop" ]]; then + if systemctl status firewalld 2>/dev/null | grep -q "active (running)" && [[ "$1" == "stop" ]]; then systemctl stop firewalld >/dev/null 2>&1 systemctl disable firewalld >/dev/null 2>&1 - echoContent green " ---> firewalld Close successfully" + echoContent green "---> firewalld closed successfully" fi } # install BBR bbrInstall() { echoContent red "\n==============================================================" - echoContent green "BBR、DDMature works for [YLX2016] with scripts, address [https://github.com/ylx2016/linux-netspeed], please be familiar" - echoContent yellow "1.Installation script【Recommended original BBR+FQ】" - echoContent yellow "2.Return the rendering" + echoContent green "The mature works of [ylx2016] for BBR and DD scripts, the address is [https://github.com/ylx2016/Linux-NetSpeed], please be familiar with" + echoContent yellow "1.Installation script [recommended original BBR+FQ]" + echoContent yellow "2.Fallback home directory" echoContent red "==============================================================" - read -r -p "please choose:" installBBRStatus + read -r -p "Please select:" installBBRStatus if [[ "${installBBRStatus}" == "1" ]]; then wget -N --no-check-certificate "https://raw.githubusercontent.com/ylx2016/Linux-NetSpeed/master/tcp.sh" && chmod +x tcp.sh && ./tcp.sh else @@ -3145,34 +4025,34 @@ bbrInstall() { fi } -# View, check the log +# View and check logs checkLog() { if [[ -z ${configPath} ]]; then - echoContent red " ---> No installation directory is detected, please perform script installation content" + echoContent red " ---> No installation directory detected, please execute the script to install the content" fi local logStatus=false - if [[ -n $(cat ${configPath}00_log.json | grep access) ]]; then + if grep -q "access" ${configPath}00_log.json; then logStatus=true fi - echoContent skyBlue "\n function $1/${totalProgress} : View log" + echoContent skyBlue "\nFunction $1/${totalProgress} : View log" echoContent red "\n==============================================================" - echoContent yellow "# It is recommended to open the Access log when you debug it.\n" + echoContent yellow "# It is recommended to open access log only when debugging\n" if [[ "${logStatus}" == "false" ]]; then - echoContent yellow "1.Open Access log" + echoContent yellow "1.Open access log" else - echoContent yellow "1.Close Access log" + echoContent yellow "1.Close the access log" fi - echoContent yellow "2.Monitor Access Log" - echoContent yellow "3.Monitor Error log" - echoContent yellow "4.View certificate timing task log" + echoContent yellow "2.Monitor access log" + echoContent yellow "3.Monitor error log" + echoContent yellow "4.View the certificate timing task log" echoContent yellow "5.View certificate installation log" - echoContent yellow "6.Empty log" + echoContent yellow "6.Clear the log" echoContent red "==============================================================" - read -r -p "please choose:" selectAccessLogType + read -r -p "Please select:" selectAccessLogType local configPathLog=${configPath//conf\//} case ${selectAccessLogType} in @@ -3222,76 +4102,79 @@ EOF # Script shortcut aliasInstall() { - if [[ -f "$HOME/install.sh" ]] && [[ -d "/etc/v2ray-agent" ]] && grep <$HOME/install.sh -q "author:mack-a"; then + if [[ -f "$HOME/install.sh" ]] && [[ -d "/etc/v2ray-agent" ]] && grep <"$HOME/install.sh" -q "作者:mack-a"; then mv "$HOME/install.sh" /etc/v2ray-agent/install.sh local vasmaType= - if [[ -d "/usr/bin/" ]] ; then - if [[ ! -f "/usr/bin/vasma" ]];then + if [[ -d "/usr/bin/" ]]; then + if [[ ! -f "/usr/bin/vasma" ]]; then ln -s /etc/v2ray-agent/install.sh /usr/bin/vasma chmod 700 /usr/bin/vasma vasmaType=true fi rm -rf "$HOME/install.sh" - elif [[ -d "/usr/sbin" ]] ; then - if [[ ! -f "/usr/sbin/vasma" ]];then + elif [[ -d "/usr/sbin" ]]; then + if [[ ! -f "/usr/sbin/vasma" ]]; then ln -s /etc/v2ray-agent/install.sh /usr/sbin/vasma chmod 700 /usr/sbin/vasma vasmaType=true fi rm -rf "$HOME/install.sh" fi - if [[ "${vasmaType}" == "true" ]];then - echoContent green "Quick way to create success, executable[vasma]Re-opening the script" + if [[ "${vasmaType}" == "true" ]]; then + echoContent green "Shortcut created successfully, executable [vasma] to reopen the script" fi fi } -# Check IPv6, IPv4 +# check ipv6, ipv4 checkIPv6() { - pingIPv6=$(ping6 -c 1 www.google.com | sed '2{s/[^(]*(//;s/).*//;q;}' | tail -n +2) + # pingIPv6=$(ping6 -c 1 www.google.com | sed '2{s/[^(]*(//;s/).*//;q;}' | tail -n +2) + pingIPv6=$(ping6 -c 1 www.google.com | sed -n '1p' | sed 's/.*(//g;s/).*//g') + if [[ -z "${pingIPv6}" ]]; then - echoContent red " ---> IPv6 does not support" + echoContent red " ---> ipv6 is not supported" exit 0 fi } -# ipv6 Divert +# ipv6 offload ipv6Routing() { if [[ -z "${configPath}" ]]; then - echoContent red " ---> Not installed, please use the script installation" + echoContent red " ---> Not installed, please use script to install" menu exit 0 fi checkIPv6 - echoContent skyBlue "\n function 1/${totalProgress} : IPv6 diversion" + echoContent skyBlue "\nFunction 1/${totalProgress} : IPv6 offload" echoContent red "\n==============================================================" echoContent yellow "1.Add domain name" - echoContent yellow "2.Uninstall IPv6 diversion" + echoContent yellow "2.Uninstall IPv6 offload" echoContent red "==============================================================" - read -r -p "please choose:" ipv6Status + read -r -p "Please select:" ipv6Status if [[ "${ipv6Status}" == "1" ]]; then echoContent red "==============================================================" - echoContent yellow "# Precautions\n" - echoContent yellow "1.Rules only support a predefined domain name list[https://github.com/v2fly/domain-list-community]" - echoContent yellow "2.Detailed documentation[https://www.v2fly.org/config/routing.html]" - echoContent yellow "3.If the kernel starts fail, check the domain name and re-add domain name." - echoContent yellow "4.Do not allow special characters, pay attention to the format of comma" - echoContent yellow "5.Every time you add it, it is re-added, and the last domain name will not be retained." - echoContent yellow "6.Enride example:google,youtube,facebook\n" - read -r -p "Please follow the example name of the above:" domainList + echoContent yellow "# Notes\n" + echoContent yellow "1.The rule only supports the predefined domain name list [https://github.com/v2fly/domain-list-community]" + echoContent yellow "2.Detailed documentation [https://www.v2fly.org/config/routing.html]" + echoContent yellow "3.If the kernel fails to start, please check the domain name and add the domain name again" + echoContent yellow "4.Special characters are not allowed, pay attention to the format of commas" + echoContent yellow "5.Every time you add it, it will be added again, and the last domain name will not be retained" + echoContent yellow "6.It is strongly recommended to block domestic websites, enter [cn] below to block" + echoContent yellow "7.Input example: google,youtube,facebook,cn\n" + read -r -p "Please enter the domain name according to the above example:" domainList - if [[ -f "${configPath}09_routing.json" ]];then + if [[ -f "${configPath}09_routing.json" ]]; then - unInstallRouting IPv6-out + unInstallRouting IPv6-out outboundTag - routing=$(jq -r '.routing.rules += [{"type":"field","domain":["geosite:'${domainList//,/\",\"geosite:}'"],"outboundTag":"IPv6-out"}]' ${configPath}09_routing.json) + routing=$(jq -r ".routing.rules += [{\"type\":\"field\",\"domain\":[\"geosite:${domainList//,/\",\"geosite:}\"],\"outboundTag\":\"IPv6-out\"}]" ${configPath}09_routing.json) - echo "${routing}"|jq . >${configPath}09_routing.json + echo "${routing}" | jq .>${configPath}09_routing.json else - cat <${configPath}09_routing.json + cat <"${configPath}09_routing.json" { "routing":{ "domainStrategy": "IPOnDemand", @@ -3307,44 +4190,44 @@ ipv6Routing() { } } EOF -fi + fi unInstallOutbounds IPv6-out outbounds=$(jq -r '.outbounds += [{"protocol":"freedom","settings":{"domainStrategy":"UseIPv6"},"tag":"IPv6-out"}]' ${configPath}10_ipv4_outbounds.json) - echo "${outbounds}"|jq . >${configPath}10_ipv4_outbounds.json + echo "${outbounds}" | jq .>${configPath}10_ipv4_outbounds.json - echoContent green " ---> Added successfully" + echoContent green " ---> Add successfully" elif [[ "${ipv6Status}" == "2" ]]; then - unInstallRouting IPv6-out + unInstallRouting IPv6-out outboundTag unInstallOutbounds IPv6-out - echoContent green " ---> IPv6 shunt uninstallation is successful" + echoContent green "---> IPv6 offloading succeeded" else - echoContent red " ---> wrong selection" + echoContent red " ---> Selection error" exit 0 fi reloadCore } -# BT download management +# bt download management btTools() { if [[ -z "${configPath}" ]]; then - echoContent red " ---> Not installed, please use the script installation" + echoContent red " ---> Not installed, please use script to install" menu exit 0 fi - echoContent skyBlue "\n function 1/${totalProgress} : BT download management" + echoContent skyBlue "\nFunction 1/${totalProgress} : bt download management" echoContent red "\n==============================================================" - if [[ -f ${configPath}09_routing.json ]] && grep -q bittorrent < ${configPath}09_routing.json;then - echoContent yellow "Current status: Disabled" + if [[ -f ${configPath}09_routing.json ]] && grep -q bittorrent <${configPath}09_routing.json; then + echoContent yellow "Current Status: Disabled" else echoContent yellow "Current status: not disabled" fi @@ -3352,16 +4235,16 @@ btTools() { echoContent yellow "1.Disable" echoContent yellow "2.Open" echoContent red "==============================================================" - read -r -p "please choose:" btStatus + read -r -p "Please select:" btStatus if [[ "${btStatus}" == "1" ]]; then - if [[ -f "${configPath}09_routing.json" ]];then + if [[ -f "${configPath}09_routing.json" ]]; then - unInstallRouting blackhole-out + unInstallRouting blackhole-out outboundTag routing=$(jq -r '.routing.rules += [{"type":"field","outboundTag":"blackhole-out","protocol":["bittorrent"]}]' ${configPath}09_routing.json) - echo "${routing}"|jq . >${configPath}09_routing.json + echo "${routing}" | jq .>${configPath}09_routing.json else cat <${configPath}09_routing.json @@ -3378,7 +4261,7 @@ btTools() { } } EOF -fi + fi installSniffing @@ -3386,119 +4269,203 @@ fi outbounds=$(jq -r '.outbounds += [{"protocol":"blackhole","tag":"blackhole-out"}]' ${configPath}10_ipv4_outbounds.json) - echo "${outbounds}"|jq . >${configPath}10_ipv4_outbounds.json - + echo "${outbounds}" | jq .>${configPath}10_ipv4_outbounds.json - - echoContent green " ---> BT download disabled" + echoContent green "---> BT download disabled successfully" elif [[ "${btStatus}" == "2" ]]; then unInstallSniffing - unInstallRouting blackhole-out + unInstallRouting blackhole-out outboundTag bittorrent - unInstallOutbounds blackhole-out + # unInstallOutbounds blackhole-out - echoContent green " ---> BT download is successful" + echoContent green " ---> BT download successfully opened" else - echoContent red " ---> wrong selection" + echoContent red " ---> Selection error" exit 0 fi reloadCore } -# Uninstall Routing according to TAG -unInstallRouting(){ +# Domain blacklist +blacklist() { + if [[ -z "${configPath}" ]]; then + echoContent red " ---> Not installed, please use script to install" + menu + exit 0 + fi + + echoContent skyBlue "\nProgress $1/${totalProgress} : domain name blacklist" + echoContent red "\n==============================================================" + echoContent yellow "1.Add domain name" + echoContent yellow "2.Delete blacklist" + echoContent red "==============================================================" + read -r -p "Please select:" blacklistStatus + if [[ "${blacklistStatus}" == "1" ]]; then + echoContent red "==============================================================" + echoContent yellow "# Notes\n" + echoContent yellow "1.The rule only supports the predefined domain name list [https://github.com/v2fly/domain-list-community]" + echoContent yellow "2.Detailed documentation [https://www.v2fly.org/config/routing.html]" + echoContent yellow "3.If the kernel fails to start, please check the domain name and add the domain name again" + echoContent yellow "4.Special characters are not allowed, pay attention to the format of commas" + echoContent yellow "5.Every time you add it, it will be added again, and the last domain name will not be retained" + echoContent yellow "6.Input example: speedtest,facebook\n" + read -r -p "Please enter the domain name according to the above example:" domainList + + if [[ -f "${configPath}09_routing.json" ]]; then + unInstallRouting blackhole-out outboundTag + + routing=$(jq -r ".routing.rules += [{\"type\":\"field\",\"domain\":[\"geosite:${domainList//,/\",\"geosite:}\"],\"outboundTag\":\"blackhole-out\"}]" ${configPath}09_routing.json) + + echo "${routing}" | jq .>${configPath}09_routing.json + + else + cat <${configPath}09_routing.json +{ + "routing":{ + "domainStrategy": "IPOnDemand", + "rules": [ + { + "type": "field", + "domain": [ + "geosite:${domainList//,/\",\"geosite:}" + ], + "outboundTag": "blackhole-out" + } + ] + } +} +EOF + fi + + echoContent green " ---> Add successfully" + + elif [[ "${blacklistStatus}" == "2" ]]; then + + unInstallRouting blackhole-out outboundTag + + echoContent green " ---> Domain name blacklist deleted successfully" + else + echoContent red " ---> Selection error" + exit 0 + fi + reloadCore +} + +# Uninstall Routing according to tag +unInstallRouting() { local tag=$1 + local type=$2 + local protocol=$3 + + if [[ -f "${configPath}09_routing.json" ]]; then + local routing + if grep -q "${tag}" ${configPath}09_routing.json && grep -q "${type}" ${configPath}09_routing.json; then + + jq -c .routing.rules[] ${configPath}09_routing.json | while read -r line; do + local index=$((index + 1)) + local delStatus=0 + if [[ "${type}" == "outboundTag" ]] && echo "${line}" | jq .outboundTag | grep -q "${tag}"; then + partStatus=1 + elif [[ "${type}" == "inboundTag" ]] && echo "${line}" | jq .inboundTag | grep -q "${tag}"; then + partStatus=1 + fi - if [[ -f "${configPath}09_routing.json" ]];then - local routing= - if grep -q "${tag}" ${configPath}09_routing.json;then - local index=$(jq .routing.rules[].outboundTag ${configPath}09_routing.json|awk '{print ""NR""":"$0}'|grep "${tag}"|awk -F "[:]" '{print $1}'|head -1) - if [[ ${index} -gt 0 ]];then - routing=$(jq -r 'del(.routing.rules['$(expr ${index} - 1)'])' ${configPath}09_routing.json) - echo "${routing}" |jq . >${configPath}09_routing.json - fi + if [[ -n ${protocol} ]] && echo "${line}" | jq .protocol | grep -q "${protocol}"; then + partStatus=1 + elif [[ -z ${protocol} ]] && [[ $(echo "${line}" | jq .protocol) != "null" ]]; then + partStatus=0 + fi + + if [[ ${delStatus} == 1 ]]; then + routing=$(jq -r 'del(.routing.rules['"$(("${index}" - 1))"'])' ${configPath}09_routing.json) + echo "${routing}" | jq .>${configPath}09_routing.json + fi + done fi fi } -# Uninstalling station according to TAG -unInstallOutbounds(){ +# Uninstall outbound according to tag +unInstallOutbounds() { local tag=$1 - if grep -q "${tag}" ${configPath}10_ipv4_outbounds.json;then - local ipv6OutIndex=$(jq .outbounds[].tag ${configPath}10_ipv4_outbounds.json|awk '{print ""NR""":"$0}'|grep "${tag}"|awk -F "[:]" '{print $1}'|head -1) - if [[ ${ipv6OutIndex} -gt 0 ]];then - routing=$(jq -r 'del(.outbounds['$(expr ${ipv6OutIndex} - 1)'])' ${configPath}10_ipv4_outbounds.json) - echo "${routing}" |jq . >${configPath}10_ipv4_outbounds.json + if grep -q "${tag}" ${configPath}10_ipv4_outbounds.json; then + local ipv6OutIndex + ipv6OutIndex=$(jq .outbounds[].tag ${configPath}10_ipv4_outbounds.json | awk '{print ""NR""":"$0}' | grep "${tag}" | awk -F "[:]" '{print $1}' | head -1) + if [[ ${ipv6OutIndex} -gt 0 ]]; then + routing=$(jq -r 'del(.outbounds['$(("${ipv6OutIndex}" - 1))'])' ${configPath}10_ipv4_outbounds.json) + echo "${routing}" | jq .>${configPath}10_ipv4_outbounds.json fi fi } -# Uninstall -unInstallSniffing(){ - ls ${configPath}|grep inbounds.json|while read -r inbound;do - sniffing=$(jq -r 'del(.inbounds[0].sniffing)' ${configPath}${inbound}) - echo "${sniffing}" |jq . >${configPath}${inbound} +# uninstall sniffing +unInstallSniffing() { + + find ${configPath} -name "*inbounds.json*" | awk -F "[c][o][n][f][/]" '{print $2}' | while read -r inbound; do + sniffing=$(jq -r 'del(.inbounds[0].sniffing)' "${configPath}${inbound}") + echo "${sniffing}" | jq .>"${configPath}${inbound}" done } -# Install a sniff -installSniffing(){ - ls ${configPath}|grep inbounds.json|while read -r inbound;do - sniffing=$(jq -r '.inbounds[0].sniffing = {"enabled":true,"destOverride":["http","tls"]}' ${configPath}${inbound}) - echo "${sniffing}" |jq . >${configPath}${inbound} +# install sniff +installSniffing() { + + find ${configPath} -name "*inbounds.json*" | awk -F "[c][o][n][f][/]" '{print $2}' | while read -r inbound; do + sniffing=$(jq -r '.inbounds[0].sniffing = {"enabled":true,"destOverride":["http","tls"]}' "${configPath}${inbound}") + echo "${sniffing}" | jq .>"${configPath}${inbound}" done } -# WARP diversion -warpRouting(){ - echoContent skyBlue "\n $1/${totalProgress} : WARP diversion" +# warp triage +warpRouting() { + echoContent skyBlue "\nProgress $1/${totalProgress} : WARP diversion" echoContent red "==============================================================" - echoContent yellow "# Cautions\n" - echoContent yellow "1.The official warp has a bug after several rounds of testing, rebooting will cause warp to fail and not start, there is also a possibility of CPU usage spike" - echoContent yellow "2.It can be used normally without rebooting the machine, if you have to use the official warp, it is recommended not to reboot the machine" - echoContent yellow "3.Some machines still work normally after reboot" - echoContent yellow "4.Uninstall and reinstall if you can't use it after reboot" - # Install WARP - if [[ -z $(which warp-cli) ]];then + # echoContent yellow "# Notes\n" + # echoContent yellow "1.There are bugs in the official warp after several rounds of testing.Restarting the warp will cause the warp to fail and fail to start, and the CPU usage may also skyrocket" + # echoContent yellow "2.The machine can be used normally without restarting the machine.If you have to use the official warp, it is recommended not to restart the machine" + # echoContent yellow "3.Some machines still work normally after restarting" + # echoContent yellow "4.Can't be used after restart, you can also uninstall and reinstall" + # install warp + if [[ -z $(which warp-cli) ]]; then echo - read -r -p "WARP not installed, installed or not ?[y/n]:" installCloudflareWarpStatus - if [[ "${installCloudflareWarpStatus}" == "y" ]];then + read -r -p "WARP is not installed, is it installed? [y/n]:" installCloudflareWarpStatus + if [[ "${installCloudflareWarpStatus}" == "y" ]]; then installWarp else - echoContent yellow " ---> Abandonment of installation" + echoContent yellow " ---> Abort installation" exit 0 fi fi echoContent red "\n==============================================================" - echoContent yellow "1.Add Domain" - echoContent yellow "2.Uninstall the WARP diversion" + echoContent yellow "1.Add domain name" + echoContent yellow "2.Uninstall WARP offload" echoContent red "==============================================================" - read -r -p "please choose:" warpStatus + read -r -p "Please select:" warpStatus if [[ "${warpStatus}" == "1" ]]; then echoContent red "==============================================================" - echoContent yellow "# Cautions\n" - echoContent yellow "1.Rules only support predefined domain lists[https://github.com/v2fly/domain-list-community]" - echoContent yellow "2.Detailed documentation[https://www.v2fly.org/config/routing.html]" - echoContent yellow "3.You can only divert traffic to warp, you cannot specify ipv4 or ipv6" - echoContent yellow "4.If the kernel fails to start, please check the domain name and add it again" - echoContent yellow "5.No special characters allowed, note the comma format" - echoContent yellow "6.Each time you add it, it is re-added and will not keep the last domain name" - echoContent yellow "7.Entry Example:google,youtube,facebook\n" - read -r -p "Please enter the domain name according to the example above:" domainList + echoContent yellow "# Notes\n" + echoContent yellow "1.The rule only supports the predefined domain name list [https://github.com/v2fly/domain-list-community]" + echoContent yellow "2.Detailed documentation [https://www.v2fly.org/config/routing.html]" + echoContent yellow "3.Only traffic can be distributed to warp, not ipv4 or ipv6" + echoContent yellow "4.If the kernel fails to start, please check the domain name and add the domain name again" + echoContent yellow "5.Special characters are not allowed, pay attention to the format of comma" + echoContent yellow "6.Every time you add it, it will be added again, and the last domain name will not be retained" + echoContent yellow "7.Input example: google,youtube,facebook\n" + read -r -p "Please enter the domain name according to the above example:" domainList - if [[ -f "${configPath}09_routing.json" ]];then - unInstallRouting warp-socks-out + if [[ -f "${configPath}09_routing.json" ]]; then + unInstallRouting warp-socks-out outboundTag - routing=$(jq -r '.routing.rules += [{"type":"field","domain":["geosite:'${domainList//,/\",\"geosite:}'"],"outboundTag":"warp-socks-out"}]' ${configPath}09_routing.json) + routing=$(jq -r ".routing.rules += [{\"type\":\"field\",\"domain\":[\"geosite:${domainList//,/\",\"geosite:}\"],\"outboundTag\":\"warp-socks-out\"}]" ${configPath}09_routing.json) - echo "${routing}"|jq . >${configPath}09_routing.json + echo "${routing}" | jq .>${configPath}09_routing.json else cat <${configPath}09_routing.json @@ -3520,96 +4487,213 @@ EOF fi unInstallOutbounds warp-socks-out - local outbounds=$(jq -r '.outbounds += [{"protocol":"socks","settings":{"servers":[{"address":"127.0.0.1","port":31303}]},"tag":"warp-socks-out"}]' ${configPath}10_ipv4_outbounds.json) + local outbounds + outbounds=$(jq -r '.outbounds += [{"protocol":"socks","settings":{"servers":[{"address":"127.0.0.1","port":31303}]},"tag":"warp-socks-out"}]' ${configPath}10_ipv4_outbounds.json) - echo "${outbounds}"|jq . >${configPath}10_ipv4_outbounds.json + echo "${outbounds}" | jq .>${configPath}10_ipv4_outbounds.json - echoContent green " ---> Added successfully" + echoContent green " ---> Add successfully" elif [[ "${warpStatus}" == "2" ]]; then ${removeType} cloudflare-warp >/dev/null 2>&1 - unInstallRouting warp-socks-out + unInstallRouting warp-socks-out outboundTag unInstallOutbounds warp-socks-out - echoContent green " ---> WARP shunt uninstall success" + echoContent green " ---> WARP offloading uninstalled successfully" else - echoContent red " ---> wrong selection" + echoContent red " ---> Selection error" exit 0 fi reloadCore } -# Streaming media toolbox +# Streaming Toolbox streamingToolbox() { - echoContent skyBlue "\n function 1/${totalProgress} : Streaming media toolbox" + echoContent skyBlue "\nFunction 1/${totalProgress} : Streaming Toolbox" echoContent red "\n==============================================================" -# echoContent yellow "1.Netflix detection" - echoContent yellow "1.Any door floor machine unlock Netflix" - echoContent yellow "2.DNS unlock stream" - read -r -p "please choose:" selectType + # echoContent yellow "1.Netflix detection" + echoContent yellow "1.Any door landing machine unlocks streaming media" + echoContent yellow "2.DNS unlock streaming" + echoContent yellow "3.VMess+WS+TLS unlock streaming" + read -r -p "Please select:" selectType case ${selectType} in -# 1) -# checkNetflix -# ;; - 1) - checkNetflix - ;; 1) - dokodemoDoorUnblockNetflix + dokodemoDoorUnblockStreamingMedia ;; 2) dnsUnlockNetflix ;; + 3) + unblockVMessWSTLSStreamingMedia + ;; esac } -# Any door unlock Netflix -dokodemoDoorUnblockNetflix() { - echoContent skyBlue "\n function 1/${totalProgress} : Any door floor machine unlock Netflix" +# Arbitrary door unlock streaming +dokodemoDoorUnblockStreamingMedia() { + echoContent skyBlue "\nFunction 1/${totalProgress} : Unlock streaming media with any door landing machine" echoContent red "\n==============================================================" - echoContent yellow "# Precautions" - echoContent yellow "Any door unlock detailed, please check this article[https://github.com/mack-a/v2ray-agent/blob/master/documents/netflix/dokodemo-unblock_netflix.md]\n" + echoContent yellow "# Notes" + echoContent yellow "Any door unlock details, please check this article [https://github.com/mack-a/v2ray-agent/blob/master/documents/netflix/dokodemo-unblock_netflix.md]\n" - echoContent yellow "1.Add an outbound" - echoContent yellow "2.Adding a station" + echoContent yellow "1.Add outbound" + echoContent yellow "2.Add inbound" echoContent yellow "3.Uninstall" - read -r -p "please choose:" selectType + read -r -p "Please select:" selectType case ${selectType} in 1) - setDokodemoDoorUnblockNetflixOutbounds + setDokodemoDoorUnblockStreamingMediaOutbounds ;; 2) - setDokodemoDoorUnblockNetflixInbounds + setDokodemoDoorUnblockStreamingMediaInbounds ;; 3) - removeDokodemoDoorUnblockNetflix + removeDokodemoDoorUnblockStreamingMedia ;; esac } -# Set any door unlock Netflix@ outbound] -setDokodemoDoorUnblockNetflixOutbounds() { - read -r -p "Please enter unlock Netflix VPS IP:" setIP +# VMess+WS+TLS to unlock streaming media [outbound only] +unblockVMessWSTLSStreamingMedia() { + echoContent skyBlue "\nFunction 1/${totalProgress} : VMess+WS+TLS outbound unblock streaming" + echoContent red "\n==============================================================" + echoContent yellow "# Notes" + echoContent yellow "Suitable for unlocking services via VMess provided by other service providers\n" + + echoContent yellow "1.Add outbound" + echoContent yellow "2.Uninstall" + read -r -p "Please select:" selectType + + case ${selectType} in + 1) + setVMessWSTLSUnblockStreamingMediaOutbounds + ;; + 2) + removeVMessWSTLSUnblockStreamingMedia + ;; + esac +} + +# Set VMess+WS+TLS to unblock Netflix [outbound only] +setVMessWSTLSUnblockStreamingMediaOutbounds() { + read -r -p "Please enter the address to unlock the streaming media VMess+WS+TLS:" setVMessWSTLSAddress + echoContent red "==============================================================" + echoContent yellow "# Notes\n" + echoContent yellow "1.The rule only supports the predefined domain name list [https://github.com/v2fly/domain-list-community]" + echoContent yellow "2.Detailed documentation [https://www.v2fly.org/config/routing.html]" + echoContent yellow "3.If the kernel fails to start, please check the domain name and add the domain name again" + echoContent yellow "4.Special characters are not allowed, pay attention to the format of commas" + echoContent yellow "5.Every time you add it, it will be added again, and the last domain name will not be retained" + echoContent yellow "6.Input example: netflix, disney, hulu\n" + read -r -p "Please enter the domain name according to the above example:" domainList + + if [[ -z ${domainList} ]]; then + echoContent red " ---> The domain name cannot be empty" + setVMessWSTLSUnblockStreamingMediaOutbounds + fi + + if [[ -n "${setVMessWSTLSAddress}" ]]; then + + unInstallOutbounds VMess-out + + echo + read -r -p "Please enter the port of VMess+WS+TLS:" setVMessWSTLSPort + echo + if [[ -z "${setVMessWSTLSPort}" ]]; then + echoContent red " ---> Port cannot be empty" + fi + + read -r -p "Please enter the UUID of VMess+WS+TLS:" setVMessWSTLSUUID + echo + if [[ -z "${setVMessWSTLSUUID}" ]]; then + echoContent red " ---> UUID cannot be empty" + fi + + read -r -p "Please enter the Path of VMess+WS+TLS:" setVMessWSTLSPath + echo + if [[ -z "${setVMessWSTLSPath}" ]]; then + echoContent red " ---> Path cannot be empty" + fi + + outbounds=$(jq -r ".outbounds += [{\"tag\":\"VMess-out\",\"protocol\":\"vmess\",\"streamSettings\":{\"network\":\"ws\",\"security\":\"tls\",\"tlsSettings\":{\"allowInsecure\":false},\"wsSettings\":{\"path\":\"${setVMessWSTLSPath}\"}},\"mux\":{\"enabled\":true,\"concurrency\":8},\"settings\":{\"vnext\":[{\"address\":\"${setVMessWSTLSAddress}\",\"port\":${setVMessWSTLSPort},\"users\":[{\"id\":\"${setVMessWSTLSUUID}\",\"security\":\"auto\",\"alterId\":0}]}]}}]" ${configPath}10_ipv4_outbounds.json) + + echo "${outbounds}" | jq .>${configPath}10_ipv4_outbounds.json + + if [[ -f "${configPath}09_routing.json" ]]; then + unInstallRouting VMess-out outboundTag + + local routing + + routing=$(jq -r ".routing.rules += [{\"type\":\"field\",\"domain\":[\"ip.sb\",\"geosite:${domainList//,/\",\"geosite:}\"],\"outboundTag\":\"VMess-out\"}]" ${configPath}09_routing.json) + + echo "${routing}" | jq .>${configPath}09_routing.json + else + cat <${configPath}09_routing.json +{ + "routing": { + "rules": [ + { + "type": "field", + "domain": [ + "ip.sb", + "geosite:${domainList//,/\",\"geosite:}" + ], + "outboundTag": "VMess-out" + } + ] + } +} +EOF + fi + reloadCore + echoContent green " ---> Add outbound unlock success" + exit 0 + fi + echoContent red " ---> The address cannot be empty" + setVMessWSTLSUnblockStreamingMediaOutbounds +} + +# Set any door to unlock Netflix [outbound] +setDokodemoDoorUnblockStreamingMediaOutbounds() { + read -r -p "Please enter the IP to unlock the streaming vps:" setIP + echoContent red "==============================================================" + echoContent yellow "# Notes\n" + echoContent yellow "1.The rule only supports the predefined domain name list [https://github.com/v2fly/domain-list-community]" + echoContent yellow "2.Detailed documentation [https://www.v2fly.org/config/routing.html]" + echoContent yellow "3.If the kernel fails to start, please check the domain name and add the domain name again" + echoContent yellow "4.Special characters are not allowed, pay attention to the format of commas" + echoContent yellow "5.Every time you add it, it will be added again, and the last domain name will not be retained" + echoContent yellow "6.Input example: netflix, disney, hulu\n" + read -r -p "Please enter the domain name according to the above example:" domainList + + if [[ -z ${domainList} ]]; then + echoContent red " ---> The domain name cannot be empty" + setDokodemoDoorUnblockStreamingMediaOutbounds + fi + if [[ -n "${setIP}" ]]; then - unInstallOutbounds netflix-80 - unInstallOutbounds netflix-443 + unInstallOutbounds streamingMedia-80 + unInstallOutbounds streamingMedia-443 + + outbounds=$(jq -r ".outbounds += [{\"tag\":\"streamingMedia-80\",\"protocol\":\"freedom\",\"settings\":{\"domainStrategy\":\"AsIs\",\"redirect\":\"${setIP}:22387\"}},{\"tag\":\"streamingMedia-443\",\"protocol\":\"freedom\",\"settings\":{\"domainStrategy\":\"AsIs\",\"redirect\":\"${setIP}:22388\"}}]" ${configPath}10_ipv4_outbounds.json) + + echo "${outbounds}" | jq .>${configPath}10_ipv4_outbounds.json - outbounds=$(jq -r '.outbounds += [{"tag":"netflix-80","protocol":"freedom","settings":{"domainStrategy":"AsIs","redirect":"'${setIP}':22387"}},{"tag":"netflix-443","protocol":"freedom","settings":{"domainStrategy":"AsIs","redirect":"'${setIP}':22388"}}]' ${configPath}10_ipv4_outbounds.json) + if [[ -f "${configPath}09_routing.json" ]]; then + unInstallRouting streamingMedia-80 outboundTag + unInstallRouting streamingMedia-443 outboundTag - echo "${outbounds}"|jq . >${configPath}10_ipv4_outbounds.json + local routing - if [[ -f "${configPath}09_routing.json" ]] ;then - unInstallRouting netflix-80 - unInstallRouting netflix-443 + routing=$(jq -r ".routing.rules += [{\"type\":\"field\",\"port\":80,\"domain\":[\"ip.sb\",\"geosite:${domainList//,/\",\"geosite:}\"],\"outboundTag\":\"streamingMedia-80\"},{\"type\":\"field\",\"port\":443,\"domain\":[\"ip.sb\",\"geosite:${domainList//,/\",\"geosite:}\"],\"outboundTag\":\"streamingMedia-443\"}]" ${configPath}09_routing.json) - local routing=$(jq -r '.routing.rules += [{"type":"field","port":80,"domain":["ip.sb","geosite:netflix"],"outboundTag":"netflix-80"},{"type":"field","port":443,"domain":["ip.sb","geosite:netflix"],"outboundTag":"netflix-443"}]' ${configPath}09_routing.json) - echo "${routing}"|jq . >${configPath}09_routing.json + echo "${routing}" | jq .>${configPath}09_routing.json else cat <${configPath}09_routing.json { @@ -3621,18 +4705,18 @@ setDokodemoDoorUnblockNetflixOutbounds() { "port": 80, "domain": [ "ip.sb", - "geosite:netflix" + "geosite:${domainList//,/\",\"geosite:}" ], - "outboundTag": "netflix-80" + "outboundTag": "streamingMedia-80" }, { "type": "field", "port": 443, "domain": [ "ip.sb", - "geosite:netflix" + "geosite:${domainList//,/\",\"geosite:}" ], - "outboundTag": "netflix-443" + "outboundTag": "streamingMedia-443" } ] } @@ -3640,24 +4724,33 @@ setDokodemoDoorUnblockNetflixOutbounds() { EOF fi reloadCore - echoContent green " ---> Add Netflix to unlock successfully" -# echoContent yellow " ---> Trojan related nodes do not support" + echoContent green " ---> Add outbound unlock success" exit 0 fi - echoContent red " ---> IP cannot be empty" + echoContent red " ---> ip cannot be empty" } -# Set up any door unlock Netflix [inbound] -setDokodemoDoorUnblockNetflixInbounds() { +# Set any door to unlock Netflix [inbound] +setDokodemoDoorUnblockStreamingMediaInbounds() { - echoContent skyBlue "\n function 1/${totalProgress} : Any door to add station" + echoContent skyBlue "\nFunction 1/${totalProgress} : add inbound to any door" echoContent red "\n==============================================================" - echoContent yellow "# Precautions\n" - echoContent yellow "Support quantity added" - echoContent yellow "Do not allow special characters, pay attention to the format of comma" - echoContent yellow "Enride example:1.1.1.1,1.1.1.2\n" - read -r -p "Please enter the allowed access to the unlock Netflix VPS IP:" setIPs + echoContent yellow "# Notes\n" + echoContent yellow "1.The rule only supports the predefined domain name list [https://github.com/v2fly/domain-list-community]" + echoContent yellow "2.Detailed documentation [https://www.v2fly.org/config/routing.html]" + echoContent yellow "3.If the kernel fails to start, please check the domain name and add the domain name again" + echoContent yellow "4.Special characters are not allowed, pay attention to the format of commas" + echoContent yellow "5.Every time you add it, it will be added again, and the last domain name will not be retained" + echoContent yellow "6.ip input example: 1.1.1.1,1.1.1.2" + echoContent yellow "7.The domain name below must be the same as the outbound vps" + # echoContent yellow "8.If there is a firewall, please manually open ports 22387 and 22388" + echoContent yellow "8.Example of domain name entry: netflix, disney, hulu\n" + read -r -p "Please enter the IP that is allowed to access the unlocked vps:" setIPs if [[ -n "${setIPs}" ]]; then + read -r -p "Please enter the domain name according to the above example:" domainList + allowPort 22387 + allowPort 22388 + cat <${configPath}01_netflix_inbounds.json { "inbounds": [ @@ -3677,7 +4770,7 @@ setDokodemoDoorUnblockNetflixInbounds() { "http" ] }, - "tag": "unblock-80" + "tag": "streamingMedia-80" }, { "listen": "0.0.0.0", @@ -3695,13 +4788,13 @@ setDokodemoDoorUnblockNetflixInbounds() { "tls" ] }, - "tag": "unblock-443" + "tag": "streamingMedia-443" } ] } EOF - cat <${configPath}10_ipv4_outbounds.json + cat <${configPath}10_ipv4_outbounds.json { "outbounds":[ { @@ -3726,66 +4819,84 @@ EOF } EOF - cat <${configPath}09_routing.json -{ - "routing": { - "rules": [ - { - "source": [], - "type": "field", - "inboundTag": [ - "unblock-80", - "unblock-443" - ], - "outboundTag": "direct" - }, - { - "domains": [ - "geosite:netflix" - ], - "type": "field", - "inboundTag": [ - "unblock-80", - "unblock-443" - ], - "outboundTag": "blackhole-out" - } - ] - } -} + if [[ -f "${configPath}09_routing.json" ]]; then + unInstallRouting streamingMedia-80 inboundTag + unInstallRouting streamingMedia-443 inboundTag + + local routing + routing=$(jq -r ".routing.rules += [{\"source\":[\"${setIPs//,/\",\"}\"],\"type\":\"field\",\"inboundTag\":[\"streamingMedia-80\",\"streamingMedia-443\"],\"outboundTag\":\"direct\"},{\"domains\":[\"geosite:${domainList//,/\",\"geosite:}\"],\"type\":\"field\",\"inboundTag\":[\"streamingMedia-80\",\"streamingMedia-443\"],\"outboundTag\":\"blackhole-out\"}]" ${configPath}09_routing.json) + echo "${routing}" | jq .>${configPath}09_routing.json + else + cat <${configPath}09_routing.json + { + "routing": { + "rules": [ + { + "source": [ + "${setIPs//,/\",\"}" + ], + "type": "field", + "inboundTag": [ + "streamingMedia-80", + "streamingMedia-443" + ], + "outboundTag": "direct" + }, + { + "domains": [ + "geosite:${domainList//,/\",\"geosite:}" + ], + "type": "field", + "inboundTag": [ + "streamingMedia-80", + "streamingMedia-443" + ], + "outboundTag": "blackhole-out" + } + ] + } + } EOF - local ips= - while read -r ip; do - if [[ -z ${ips} ]];then - ips=\"${ip}\" - else - ips=${ips},\"${ip}\" - fi - done< <(echo ${setIPs}|tr ',' '\n') - local routing=$(jq -r '.routing.rules[0].source += ['${ips}']' ${configPath}09_routing.json) - echo "${routing}" | jq . >${configPath}09_routing.json + fi + reloadCore - echoContent green " ---> Add a landing machine entry to unlock Netflix success" + echoContent green " ---> Add landing machine inbound unlock successfully" exit 0 fi - echoContent red " ---> IP cannot be empty" + echoContent red " ---> ip cannot be empty" } -# Remove any door unlock Netflix -removeDokodemoDoorUnblockNetflix() { +# Remove any door to unlock Netflix +removeDokodemoDoorUnblockStreamingMedia() { + + unInstallOutbounds streamingMedia-80 + unInstallOutbounds streamingMedia-443 + + unInstallRouting streamingMedia-80 inboundTag + unInstallRouting streamingMedia-443 inboundTag + + unInstallRouting streamingMedia-80 outboundTag + unInstallRouting streamingMedia-443 outboundTag - unInstallOutbounds netflix-80 - unInstallOutbounds netflix-443 - unInstallRouting netflix-80 - unInstallRouting netflix-443 rm -rf ${configPath}01_netflix_inbounds.json reloadCore - echoContent green " ---> Uninstall success" + echoContent green " ---> Uninstall successful" +} + +# Remove VMess+WS+TLS to unlock streaming +removeVMessWSTLSUnblockStreamingMedia() { + + unInstallOutbounds VMess-out + + unInstallRouting VMess-out outboundTag + + reloadCore + echoContent green " ---> Uninstall successful" } -# Restart the core +# restart the core reloadCore() { if [[ "${coreInstallType}" == "1" ]]; then handleXray stop @@ -3794,44 +4905,25 @@ reloadCore() { handleV2Ray stop handleV2Ray start fi -} - -# an examination Does VPS support Netflix -checkNetflix() { - echoContent red "\n precautions" - echoContent yellow " 1.Only if the VPS can support Netflix" - echoContent yellow " 2.Netflix supports Netflix after the agent is not detecting the agent configuration DNS unlock" - echoContent yellow " 3.Can detect VPS configuration DNS unlocking Netflix\n" - echoContent skyBlue " ---> checking" - netflixResult=$(curl -s -m 2 https://www.netflix.com | grep "Not Available") - if [[ -n ${netflixResult} ]]; then - echoContent red " ---> Netflix is not available" - exit 0 - fi - netflixResult=$(curl -s -m 2 https://www.netflix.com | grep "NSEZ-403") - if [[ -n ${netflixResult} ]]; then - echoContent red " ---> Netflix is not available" - exit 0 - fi - - echoContent skyBlue " ---> Detect whether the desperate poisoning teacher can play" - result=$(curl -s -m 2 https://www.netflix.com/title/70143836 | grep "page-404") - if [[ -n ${result} ]]; then - echoContent green " ---> Only" - exit 0 + if [[ -n "${hysteriaConfigPath}" ]]; then + handleHysteria stop + handleHysteria start fi - echoContent green " ---> Netflix unlocked" - exit 0 } -# DNS unlock Netflix +# dns unblock Netflix dnsUnlockNetflix() { - echoContent skyBlue "\n function 1/${totalProgress} : DNS unlock Netflix" + if [[ -z "${configPath}" ]]; then + echoContent red " ---> Not installed, please use script to install" + menu + exit 0 + fi + echoContent skyBlue "\nFunction 1/${totalProgress} : DNS unblock streaming" echoContent red "\n==============================================================" - echoContent yellow "1.Add to" + echoContent yellow "1.Add" echoContent yellow "2.Uninstall" - read -r -p "please choose:" selectType + read -r -p "Please select:" selectType case ${selectType} in 1) @@ -3843,52 +4935,82 @@ dnsUnlockNetflix() { esac } -# Set DNS +# set dns setUnlockDNS() { - read -r -p "Please enter the DNS unlocked Netflix:" setDNS + read -r -p "Please enter Unblock Streaming DNS:" setDNS if [[ -n ${setDNS} ]]; then - cat <${configPath}11_dns.json -{ - "dns": { - "servers": [ - { - "address": "${setDNS}", - "port": 53, - "domains": [ - "geosite:netflix", - "geosite:bahamut", - "geosite:hulu", - "geosite:hbo", - "geosite:disney", - "geosite:bbc", - "geosite:4chan", - "geosite:fox", - "geosite:abema", - "geosite:dmm", - "geosite:niconico", - "geosite:pixiv", - "geosite:bilibili", - "geosite:viu" - ] - }, - "localhost" - ] - } -} + echoContent red "==============================================================" + echoContent yellow "# Notes\n" + echoContent yellow "1.The rule only supports the predefined domain name list [https://github.com/v2fly/domain-list-community]" + echoContent yellow "2.Detailed documentation [https://www.v2fly.org/config/routing.html]" + echoContent yellow "3.If the kernel fails to start, please check the domain name and add the domain name again" + echoContent yellow "4.Special characters are not allowed, pay attention to the format of commas" + echoContent yellow "5.Every time you add it, it will be added again, and the last domain name will not be retained" + echoContent yellow "6.Input example: netflix, disney, hulu" + echoContent yellow "7.Please enter 1 for the default scheme, the default scheme includes the following" + echoContent yellow "netflix,bahamut,hulu,hbo,disney,bbc,4chan,fox,abema,dmm,niconico,pixiv,bilibili,viu" + read -r -p "Please enter the domain name according to the above example:" domainList + if [[ "${domainList}" == "1" ]]; then + cat <${configPath}11_dns.json + { + "dns": { + "servers": [ + { + "address": "${setDNS}", + "port": 53, + "domains": [ + "geosite:netflix", + "geosite:bahamut", + "geosite:hulu", + "geosite:hbo", + "geosite:disney", + "geosite:bbc", + "geosite:4chan", + "geosite:fox", + "geosite:abema", + "geosite:dmm", + "geosite:niconico", + "geosite:pixiv", + "geosite:bilibili", + "geosite:viu" + ] + }, + "localhost" + ] + } + } +EOF + elif [[ -n "${domainList}" ]]; then + cat <${configPath}11_dns.json + { + "dns": { + "servers": [ + { + "address": "${setDNS}", + "port": 53, + "domains": [ + "geosite:${domainList//,/\",\"geosite:}" + ] + }, + "localhost" + ] + } + } EOF + fi + reloadCore - echoContent green "\n ---> DNS unlocks add success, this setting is invalid for Trojan-Go" - echoContent yellow "\n ---> If you can't watch it, you can try the following two programs." - echoContent yellow " 1.Restart VPS" - echoContent yellow " 2.After uninstalling the DNS unlock, modify the local [/etc/resolv.conf]DNs settings and restart VPS \ N)" + echoContent yellow "\n ---> If you still can't watch it, you can try the following two solutions" + echoContent yellow "1.Restart vps" + echoContent yellow " 2.After uninstalling dns unlock, modify the local [/etc/resolv.conf] DNS settings and restart vps\n" else - echoContent red " ---> DNS cannot be empty" + echoContent red " ---> dns cannot be empty" fi exit 0 } -# Remove Netflix unlock +# remove Netflix unblock removeUnlockDNS() { cat <${configPath}11_dns.json { @@ -3901,28 +5023,22 @@ removeUnlockDNS() { EOF reloadCore - echoContent green " ---> Uninstall success" + echoContent green " ---> Uninstall successful" exit 0 } -# v2ray-Core Personalization +# v2ray-core personalized installation customV2RayInstall() { - echoContent skyBlue "\n========================Personalization installation============================" - echoContent yellow "Vless front, you must install 0, if you only need to install 0, enter" - if [[ "${selectCoreType}" == "2" ]]; then - echoContent yellow "0.VLESS+TLS+TCP" - else - echoContent yellow "0.VLESS+TLS/XTLS+TCP" - fi - + echoContent skyBlue "\n========================Personalized installation==================== ==========" + echoContent yellow "VLESS is pre-installed, and 0 is installed by default.If only 0 needs to be installed, only 0 can be selected" + echoContent yellow "0.VLESS+TLS/XTLS+TCP" echoContent yellow "1.VLESS+TLS+WS[CDN]" - echoContent yellow "2.VMess+TLS+TCP" + echoContent yellow "2.Trojan+TLS+gRPC[CDN]" echoContent yellow "3.VMess+TLS+WS[CDN]" -# echoContent yellow "4.Trojan、Trojan+WS[CDN]" echoContent yellow "4.Trojan" echoContent yellow "5.VLESS+TLS+gRPC[CDN]" - read -r -p "Please select [Multiple Select], [for example: 123]:" selectCustomInstallType + read -r -p "Please select [multiple choices], [eg: 123]:" selectCustomInstallType echoContent skyBlue "--------------------------------------------------------------" if [[ -z ${selectCustomInstallType} ]]; then selectCustomInstallType=0 @@ -3931,10 +5047,11 @@ customV2RayInstall() { cleanUp xrayClean totalProgress=17 installTools 1 - # Apply for TLS + # apply for tls initTLSNginxConfig 2 installTLS 3 handleNginx stop + # random path if echo ${selectCustomInstallType} | grep -q 1 || echo ${selectCustomInstallType} | grep -q 3 || echo ${selectCustomInstallType} | grep -q 4; then randomPathFunction 5 customCDNIP 6 @@ -3943,7 +5060,7 @@ customV2RayInstall() { updateRedirectNginxConf handleNginx start - # Install v2ray + # Install V2Ray installV2Ray 8 installV2RayService 9 initV2RayConfig custom 10 @@ -3951,40 +5068,43 @@ customV2RayInstall() { installCronTLS 14 handleV2Ray stop handleV2Ray start - # Account + # generate account checkGFWStatue 15 showAccounts 16 else - echoContent red " ---> Input is not legal" + echoContent red " ---> Invalid input" customV2RayInstall fi } -# Xray-core Personalization installation +# Xray-core personalized installation customXrayInstall() { - echoContent skyBlue "\n========================Personalization installation============================" - echoContent yellow "Vless front, default installation 0, if only 0 is required, only 0 can be selected" + echoContent skyBlue "\n========================Personalized installation==================== ==========" + echoContent yellow "VLESS is pre-installed, and 0 is installed by default.If only 0 needs to be installed, only 0 can be selected" echoContent yellow "0.VLESS+TLS/XTLS+TCP" echoContent yellow "1.VLESS+TLS+WS[CDN]" echoContent yellow "2.Trojan+TLS+gRPC[CDN]" echoContent yellow "3.VMess+TLS+WS[CDN]" - # echoContent yellow "4.Trojan、Trojan+WS[CDN]" echoContent yellow "4.Trojan" echoContent yellow "5.VLESS+TLS+gRPC[CDN]" - read -r -p "Please select [Multiple Select], [for example: 123]:" selectCustomInstallType + read -r -p "Please select [multiple choices], [eg: 123]:" selectCustomInstallType echoContent skyBlue "--------------------------------------------------------------" if [[ -z ${selectCustomInstallType} ]]; then - echoContent red " ---> Cannot be empty" + echoContent red " ---> cannot be empty" customXrayInstall elif [[ "${selectCustomInstallType}" =~ ^[0-5]+$ ]]; then cleanUp v2rayClean totalProgress=17 installTools 1 - # Apply for TLS + # apply for tls initTLSNginxConfig 2 + handleXray stop + handleNginx start + checkIP + installTLS 3 handleNginx stop - + # random path if echo "${selectCustomInstallType}" | grep -q 1 || echo "${selectCustomInstallType}" | grep -q 2 || echo "${selectCustomInstallType}" | grep -q 3 || echo "${selectCustomInstallType}" | grep -q 5; then randomPathFunction 5 customCDNIP 6 @@ -3993,7 +5113,7 @@ customXrayInstall() { updateRedirectNginxConf handleNginx start - # Install v2ray + # Install V2Ray installXray 8 installXrayService 9 initXrayConfig custom 10 @@ -4002,23 +5122,23 @@ customXrayInstall() { installCronTLS 14 handleXray stop handleXray start - # Account + # generate account checkGFWStatue 15 showAccounts 16 else - echoContent red " ---> Input is not legal" + echoContent red " ---> Invalid input" customXrayInstall fi } -# Select the core installation --- v2ray-core, xray-core, lock version of V2RAY-CORE [XTLS] +# Select core installation---v2ray-core, xray-core selectCoreInstall() { - echoContent skyBlue "\n function 1/${totalProgress} : Select core installation" + echoContent skyBlue "\nFunction 1/${totalProgress} : select core installation" echoContent red "\n==============================================================" echoContent yellow "1.Xray-core" echoContent yellow "2.v2ray-core" echoContent red "==============================================================" - read -r -p "please choose:" selectCoreType + read -r -p "Please select:" selectCoreType case ${selectCoreType} in 1) if [[ "${selectInstallType}" == "2" ]]; then @@ -4044,25 +5164,30 @@ selectCoreInstall() { fi ;; *) - echoContent red ' ---> Select an error, reselect' + echoContent red ' ---> selection error, re-select' selectCoreInstall ;; esac } -# v2ray-core Install +# v2ray-core install v2rayCoreInstall() { cleanUp xrayClean selectCustomInstallType= totalProgress=13 installTools 2 - # Apply for tls + # apply for tls initTLSNginxConfig 3 + + handleV2Ray stop + handleNginx start + checkIP + installTLS 4 handleNginx stop - # initNginxConfig 5 + # initNginxConfig 5 randomPathFunction 5 - # Installing V2Ray + # Install V2Ray installV2Ray 6 installV2RayService 7 customCDNIP 8 @@ -4075,24 +5200,29 @@ v2rayCoreInstall() { sleep 2 handleV2Ray start handleNginx start - # Generate account + # generate account checkGFWStatue 12 showAccounts 13 } -# xray-core Install +# xray-core install xrayCoreInstall() { cleanUp v2rayClean selectCustomInstallType= totalProgress=13 installTools 2 - # Apply for tls + # apply for tls initTLSNginxConfig 3 + + handleXray stop + handleNginx start + checkIP + installTLS 4 handleNginx stop randomPathFunction 5 - # Installing Xray - handleV2Ray stop + # install Xray + # handleV2Ray stop installXray 6 installXrayService 7 customCDNIP 8 @@ -4106,16 +5236,43 @@ xrayCoreInstall() { handleXray start handleNginx start - # Generate account + # generate account checkGFWStatue 12 showAccounts 13 } +# Hysteria installation +hysteriaCoreInstall() { + if [[ -z "${coreInstallType}" ]]; then + echoContent red "\n ---> Due to environment dependencies, such as installing hysteria, please install Xray/V2ray first" + menu + exit 0 + fi + totalProgress=5 + installHysteria 1 + initHysteriaConfig 2 + installHysteriaService 3 + handleHysteria stop + handleHysteria start + showAccounts 5 +} +# uninstall hysteria +unInstallHysteriaCore() { + + if [[ -z "${hysteriaConfigPath}" ]]; then + echoContent red "\n ---> Not installed" + exit 0 + fi + handleHysteria stop + rm -rf /etc/v2ray-agent/hysteria/* + rm -rf /etc/systemd/system/hysteria.service + echoContent green " ---> Uninstallation completed" +} # Core management coreVersionManageMenu() { if [[ -z "${coreInstallType}" ]]; then - echoContent red "\n ---> No installation directory is detected, please perform script installation content" + echoContent red "\n ---> No installation directory detected, please execute the script to install the content" menu exit 0 fi @@ -4130,7 +5287,7 @@ coreVersionManageMenu() { v2rayVersionManageMenu 1 fi } -# Timing task check certificate +# cron task check certificate cronRenewTLS() { if [[ "${renewTLS}" == "RenewTLS" ]]; then renewalTLS @@ -4139,15 +5296,16 @@ cronRenewTLS() { } # Account management manageAccount() { - echoContent skyBlue "\n function 1/${totalProgress} : Account management" + echoContent skyBlue "\nFunction 1/${totalProgress} : Account Management" echoContent red "\n==============================================================" - echoContent yellow "# Every time you delete, after adding an account, you need to re-view subscription generation subscriptions.\n" + echoContent yellow "# Every time you delete or add an account, you need to re-check the subscription to generate a subscription" + echoContent yellow "# If Hysteria is installed, the account will be added to Hysteria at the same time\n" echoContent yellow "1.View account" - echoContent yellow "2.View subscriptions" + echoContent yellow "2.View subscription" echoContent yellow "3.Add user" - echoContent yellow "4.delete users" + echoContent yellow "4.Delete user" echoContent red "==============================================================" - read -r -p "please enter:" manageAccountStatus + read -r -p "Please enter:" manageAccountStatus if [[ "${manageAccountStatus}" == "1" ]]; then showAccounts 1 elif [[ "${manageAccountStatus}" == "2" ]]; then @@ -4157,81 +5315,171 @@ manageAccount() { elif [[ "${manageAccountStatus}" == "4" ]]; then removeUser else - echoContent red " ---> wrong selection" + echoContent red " ---> Selection error" fi } -# subscription +# subscribe subscribe() { if [[ -n "${configPath}" ]]; then - echoContent skyBlue "-------------------------Remark---------------------------------" - echoContent yellow "# When you check the subscription, you will regenerate your subscription." - echoContent yellow "# Each time you add, delete your account needs to reserve subscriptions" + echoContent skyBlue "-------------------------Note-------------------------" + echoContent yellow "# Subscriptions will be regenerated when viewing subscriptions" + echoContent yellow "# Every time you add or delete an account, you need to check the subscription again" rm -rf /etc/v2ray-agent/subscribe/* rm -rf /etc/v2ray-agent/subscribe_tmp/* showAccounts >/dev/null mv /etc/v2ray-agent/subscribe_tmp/* /etc/v2ray-agent/subscribe/ - if [[ -n $(ls /etc/v2ray-agent/subscribe) ]]; then - ls /etc/v2ray-agent/subscribe | while read -r email; do - local base64Result=$(base64 -w 0 /etc/v2ray-agent/subscribe/${email}) - echo ${base64Result} >"/etc/v2ray-agent/subscribe/${email}" + if [[ -n $(ls /etc/v2ray-agent/subscribe/) ]]; then + find /etc/v2ray-agent/subscribe/* | while read -r email; do + email=$(echo "${email}" | awk -F "[b][e][/]" '{print $2}') + + local base64Result + base64Result=$(base64 -w 0 "/etc/v2ray-agent/subscribe/${email}") + echo "${base64Result}" >"/etc/v2ray-agent/subscribe/${email}" echoContent skyBlue "--------------------------------------------------------------" - echoContent yellow "email:$(echo "${email}" | awk -F "[_]" '{print $1}')\n" - echoContent yellow "url:https://${currentHost}/s/${email}\n" - echoContent yellow "Online QR code:https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=https://${currentHost}/s/${email}\n" - echo "https://${currentHost}/s/${email}" | qrencode -s 10 -m 1 -t UTF8 + echoContent yellow "email:${email}\n" + local currentDomain=${currentHost} + + if [[ -n "${currentDefaultPort}" && "${currentDefaultPort}" != "443" ]]; then + currentDomain="${currentHost}:${currentDefaultPort}" + fi + + echoContent yellow "url:https://${currentDomain}/s/${email}\n" + echoContent yellow "Online QR code: https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=https://${currentDomain}/s/${email}\n" + echo "https://${currentDomain}/s/${email}" | qrencode -s 10 -m 1 -t UTF8 echoContent skyBlue "--------------------------------------------------------------" done fi else - echoContent red " ---> Not Installed" + echoContent red "---> not installed" fi } +# toggle alpn +switchAlpn() { + echoContent skyBlue "\nFunction 1/${totalProgress} : toggle alpn" + if [[ -z ${currentAlpn} ]]; then + echoContent red " ---> Unable to read alpn, please check if it is installed" + exit 0 + fi + + echoContent red "\n==============================================================" + echoContent green "The current alpn first is: ${currentAlpn}" + echoContent yellow " 1.When http/1.1 is the first, trojan is available, and some gRPC clients are available [client supports manual selection of alpn available]" + echoContent yellow " 2.When h2 is the first, gRPC is available, and some trojan clients are available [clients support manual selection of alpn available]" + echoContent yellow " 3.If the client does not support manual replacement of alpn, it is recommended to use this function to change the order of alpn on the server to use the corresponding protocol" + echoContent red "==============================================================" + + if [[ "${currentAlpn}" == "http/1.1" ]]; then + echoContent yellow "1.Switch the first position of alpn h2" + elif [[ "${currentAlpn}" == "h2" ]]; then + echoContent yellow "1.Switch alpn http/1.1 first" + else + echoContent red 'incompatible' + fi + + echoContent red "==============================================================" + + read -r -p "Please select:" selectSwitchAlpnType + if [[ "${selectSwitchAlpnType}" == "1" && "${currentAlpn}" == "http/1.1" ]]; then + + local frontingTypeJSON + frontingTypeJSON=$(jq -r ".inbounds[0].streamSettings.xtlsSettings.alpn = [\"h2\",\"http/1.1\"]" ${configPath}${frontingType}.json) + echo "${frontingTypeJSON}" | jq .>${configPath}${frontingType}.json + + elif [[ "${selectSwitchAlpnType}" == "1" && "${currentAlpn}" == "h2" ]]; then + local frontingTypeJSON + frontingTypeJSON=$(jq -r ".inbounds[0].streamSettings.xtlsSettings.alpn =[\"http/1.1\",\"h2\"]" ${configPath}${frontingType}.json) + echo "${frontingTypeJSON}" | jq .>${configPath}${frontingType}.json + else + echoContent red " ---> Selection error" + exit 0 + fi + reloadCore +} + +#hysteria management +manageHysteria() { + + echoContent skyBlue "\nProgress 1/1: Hysteria Management" + echoContent red "\n==============================================================" + local hysteriaStatus= + if [[ -n "${hysteriaConfigPath}" ]]; then + echoContent yellow "1.Reinstall" + echoContent yellow "2.Uninstall" + echoContent yellow "3.upgrade core" + echoContent yellow "4.View log" + hysteriaStatus=true + else + echoContent yellow "1.Install" + fi + + echoContent red "==============================================================" + read -r -p "Please select:" installHysteriaStatus + if [[ "${installHysteriaStatus}" == "1" ]]; then + hysteriaCoreInstall + elif [[ "${installHysteriaStatus}" == "2" && "${hysteriaStatus}" == "true" ]]; then + unInstallHysteriaCore + elif [[ "${installHysteriaStatus}" == "3" && "${hysteriaStatus}" == "true" ]]; then + installHysteria 1 + handleHysteria start + elif [[ "${installHysteriaStatus}" == "4" && "${hysteriaStatus}" == "true" ]]; then + journalctl -fu hysteria + fi +} # main menu menu() { cd "$HOME" || exit echoContent red "\n==============================================================" - echoContent green "author:mack-a" - echoContent green "current version:v2.5.28" - echoContent green "Github:https://github.com/mack-a/v2ray-agent" - echoContent green "describe:Eight-in-one copy script\c" + echoContent green "author:mack-a" + echoContent green "Current version: v2.6.10" + echoContent green "Github:https://github.com/mack-a/v2ray-agent" + echoContent green "Description: 8-in-1 coexistence script\c" showInstallStatus echoContent red "\n==============================================================" + echoContent red "Promotion Area" + echoContent green "AFF donation: https://github.com/mack-a/v2ray-agent/blob/master/documents/donation_aff.md\n" + echoContent green "Virtual currency donation: 0xB08b731653515b083deE362fefFc45d5eb96c35d\n" + echoContent green "Contact TG for promotion: https://t.me/mackaff" + echoContent red "==============================================================" if [[ -n "${coreInstallType}" ]]; then - echoContent yellow "1.re-install" + echoContent yellow "1.Reinstall" else echoContent yellow "1.Install" fi - echoContent yellow "2.Arbitrary combination installation" + echoContent yellow "2.Install in any combination" if echo ${currentInstallProtocolType} | grep -q trojan; then echoContent yellow "3.Switch VLESS[XTLS]" - elif echo ${currentInstallProtocolType} | grep -q 0;then + elif echo ${currentInstallProtocolType} | grep -q 0; then echoContent yellow "3.Switch Trojan[XTLS]" fi - echoContent skyBlue "-------------------------Tool management-----------------------------" - echoContent yellow "4.Account management" - echoContent yellow "5.Replace the camouflage station" - echoContent yellow "6.Update certificate" - echoContent yellow "7.Replace CDN node" - echoContent yellow "8.IPv6 Divert" - echoContent yellow "9.WARP diversion" - echoContent yellow "10.Stream media tool" - echoContent yellow "11.Add a new port" - echoContent yellow "12.BT download management" - echoContent skyBlue "-------------------------Version management-----------------------------" - echoContent yellow "13.Core Management" - echoContent yellow "14.Update script" - echoContent yellow "15.Install BBR, DD script" - echoContent skyBlue "-------------------------Scripting management-----------------------------" - echoContent yellow "16.View log" - echoContent yellow "17.Uninstall" + + echoContent yellow "4.Hysteria management" + echoContent skyBlue "-------------------------Tool management--------------------" + echoContent yellow "5.Account Management" + echoContent yellow "6.Replace camouflage station" + echoContent yellow "7.Update certificate" + echoContent yellow "8.Replace CDN node" + echoContent yellow "9.IPv6 offload" + echoContent yellow "10.WARP shunt" + echoContent yellow "11.Streaming tools" + echoContent yellow "12.Add new port" + echoContent yellow "13.BT download management" + echoContent yellow "14.Switch alpn" + echoContent yellow "15.Domain blacklist" + echoContent skyBlue "-------------------------Version Management--------------------" + echoContent yellow "16.core management" + echoContent yellow "17.Update script" + echoContent yellow "18.Install BBR and DD scripts" + echoContent skyBlue "-------------------------Script management--------------------" + echoContent yellow "19.View log" + echoContent yellow "20.Uninstall script" echoContent red "==============================================================" mkdirTools aliasInstall - read -r -p "please choose:" selectInstallType + read -r -p "Please select:" selectInstallType case ${selectInstallType} in 1) selectCoreInstall @@ -4243,45 +5491,54 @@ menu() { initXrayFrontingConfig 1 ;; 4) - manageAccount 1 + manageHysteria ;; 5) - updateNginxBlog 1 + manageAccount 1 ;; 6) - renewalTLS 1 + updateNginxBlog 1 ;; 7) - updateV2RayCDN 1 + renewalTLS 1 ;; 8) - ipv6Routing 1 + updateV2RayCDN 1 ;; 9) - warpRouting 1 + ipv6Routing 1 ;; 10) - streamingToolbox 1 + warpRouting 1 ;; 11) - addCorePort 1 + streamingToolbox 1 ;; 12) - btTools 1 + addCorePort 1 ;; 13) - coreVersionManageMenu 1 + btTools 1 ;; 14) - updateV2RayAgent 1 + switchAlpn 1 ;; 15) - bbrInstall + blacklist 1 ;; 16) - checkLog 1 + coreVersionManageMenu 1 ;; 17) + updateV2RayAgent 1 + ;; + 18) + bbrInstall + ;; + 19) + checkLog 1 + ;; + 20) unInstall 1 ;; esac