From b67204c5e7f13c75ed20f37e1a8a9b47e97b0e41 Mon Sep 17 00:00:00 2001 From: mack-a <57424792+mack-a@users.noreply.github.com> Date: Thu, 21 Sep 2023 17:25:59 +0800 Subject: [PATCH] feat(script): update english version --- install.sh | 2 +- shell/install_en.sh | 10520 ++++++++++++++++++++++++++---------------- 2 files changed, 6493 insertions(+), 4029 deletions(-) diff --git a/install.sh b/install.sh index c428fef..212b45a 100644 --- a/install.sh +++ b/install.sh @@ -7896,7 +7896,7 @@ menu() { cd "$HOME" || exit echoContent red "\n==============================================================" echoContent green "作者:mack-a" - echoContent green "当前版本:v2.10.19" + echoContent green "当前版本:v2.10.20" echoContent green "Github:https://github.com/mack-a/v2ray-agent" echoContent green "描述:八合一共存脚本\c" showInstallStatus diff --git a/shell/install_en.sh b/shell/install_en.sh index e7039c3..edf181a 100644 --- a/shell/install_en.sh +++ b/shell/install_en.sh @@ -1,589 +1,736 @@ #!/usr/bin/env bash -# detection area -#---------------------------------------------------- -# check system +# Detection area +#------------------------------------------------ ---------- +# Check system export LANG=en_US.UTF-8 echoContent() { - case $1 in - # red - "red") - # shellcheck disable=SC2154 - ${echoType} "\033[31m${printN}$2 \033[0m" - ;; - # sky blue - "skyBlue") - ${echoType} "\033[1;36m${printN}$2 \033[0m" - ;; - # green - "green") - ${echoType} "\033[32m${printN}$2 \033[0m" - ;; - # White - "white") - ${echoType} "\033[37m${printN}$2 \033[0m" - ;; - "magenta") - ${echoType} "\033[31m${printN}$2 \033[0m" - ;; - # yellow - "yellow") - ${echoType} "\033[33m${printN}$2 \033[0m" - ;; - esac + case $1 in + # red + "red") + # shellcheck disable=SC2154 + ${echoType} "\033[31m${printN}$2 \033[0m" + ;; + # sky blue + "skyBlue") + ${echoType} "\033[1;36m${printN}$2 \033[0m" + ;; + # green + "green") + ${echoType} "\033[32m${printN}$2 \033[0m" + ;; + # White + "white") + ${echoType} "\033[37m${printN}$2 \033[0m" + ;; + "magenta") + ${echoType} "\033[31m${printN}$2 \033[0m" + ;; + #yellow + "yellow") + ${echoType} "\033[33m${printN}$2 \033[0m" + ;; + esac +} +# Check SELinux status +checkCentosSELinux() { + if [[ -f "/etc/selinux/config" ]] && ! grep -q "SELINUX=disabled" <"/etc/selinux/config"; then + echoContent yellow "# Notes" + echoContent yellow "It is detected that SELinux is turned on. Please turn it off manually. The tutorial is as follows" + echoContent yellow "https://www.v2ray-agent.com/archives/1679931532764#heading-8 " + exit 0 + fi } checkSystem() { - if [[ -n $(find /etc -name "redhat-release") ]] || grep " - exit 1 - ;; - esac - fi - else - echoContent red "This CPU architecture cannot be recognized, default amd64, x86_64--->" - xrayCoreCPUVendor="Xray-linux-64" - v2rayCoreCPUVendor="v2ray-linux-64" - fi + if [[ -n $(which uname) ]]; then + if [[ "$(uname)" == "Linux" ]]; then + case "$(uname -m)" in + 'amd64' | 'x86_64') + xrayCoreCPUVendor="Xray-linux-64" + v2rayCoreCPUVendor="v2ray-linux-64" + hysteriaCoreCPUVendor="hysteria-linux-amd64" + tuicCoreCPUVendor="-x86_64-unknown-linux-musl" + warpRegCoreCPUVendor="main-linux-amd64" + ;; + 'armv8' | 'aarch64') + cpuVendor="arm" + xrayCoreCPUVendor="Xray-linux-arm64-v8a" + v2rayCoreCPUVendor="v2ray-linux-arm64-v8a" + hysteriaCoreCPUVendor="hysteria-linux-arm64" + tuicCoreCPUVendor="-aarch64-unknown-linux-musl" + warpRegCoreCPUVendor="main-linux-arm64" + ;; + *) + echo "This CPU architecture is not supported --->" + exit 1 + ;; + esac + fi + else + echoContent red "This CPU architecture cannot be recognized, the default is amd64, x86_64--->" + xrayCoreCPUVendor="Xray-linux-64" + v2rayCoreCPUVendor="v2ray-linux-64" + fi } -# initialize global variables +#Initialize global variables initVar() { - installType='yum -y install' - removeType='yum -y remove' - upgrade="yum -y update" - echoType='echo -e' + installType='yum -y install' + removeType='yum -y remove' + upgrade="yum -y update" + echoType='echo -e' - # Core supported cpu version - xrayCoreCPUVendor="" - v2rayCoreCPUVendor="" - hysteriaCoreCPUVendor="" + #CPU version supported by the core + xrayCoreCPUVendor="" + v2rayCoreCPUVendor="" + hysteriaCoreCPUVendor="" + warpRegCoreCPUVendor="" + cpuVendor="" - # domain name - domain= + # domain name + domain= - # address of the CDN node - add= + #Address of CDN node + add= - # The total progress of the installation - totalProgress=1 + # Total installation progress + totalProgress=1 - # 1.xray-core installation - # 2.v2ray-core installation - # 3.v2ray-core[xtls] installation - coreInstallType= + #1.xray-core installation + #2.v2ray-core installation + #3.v2ray-core[xtls] installation + coreInstallType= - # core installation path - # coreInstallPath= + # Core installation path + # coreInstallPath= - # v2ctl Path - ctlPath= - # 1.Install all - # 2.Personalized installation - # v2rayAgentInstallType= + # v2ctl Path + ctlPath= + #1.Install all + #2.Personalized installation + # v2rayAgentInstallType= - # Current personalized installation method 01234 - currentInstallProtocolType= + # Current personalized installation method 01234 + currentInstallProtocolType= - # The order of the current alpn - currentAlpn= + # The order of the current alpn + currentAlpn= - # prepended type - frontingType= + # Prefix type + frontingType= - # Personalized installation method selected - selectCustomInstallType= + # Selected personalized installation method + selectCustomInstallType= - # Path to v2ray-core, xray-core configuration files - configPath= + # Path to v2ray-core, xray-core configuration files + configPath= - # Path to hysteria configuration file - hysteriaConfigPath= + # xray-core reality state + realityStatus= - # The path to the configuration file - currentPath= + # Path to hysteria configuration file + hysteriaConfigPath= + # interfaceName= + # Port hopping + portHoppingStart= + portHoppingEnd= + portHopping= - # config file host - currentHost= + # tuic configuration file path + tuicConfigPath= + tuicAlgorithm= + tuicPort= - # The core type selected during installation - selectCoreType= + # Path to configuration file + currentPath= - # Default core version - v2rayCoreVersion= + #Configuration file host + currentHost= - # random path - customPath= + #The core type selected during installation + selectCoreType= - # centos version - centosVersion= + #Default core version + v2rayCoreVersion= - # UUID - currentUUID= + # Random path + customPath= - # previousClients - previousClients= + # centos version + centosVersion= - localIP= + #UUID + currentUUID= - # Integrated update certificate logic no longer uses a separate script --RenewTLS - renewTLS=$1 + #clients + currentClients= - # The number of attempts after tls install failed - installTLSCount= + # previousClients + previousClients= - # BTPanel state - # BTPanelStatus= + localIP= - # nginx configuration file path - nginxConfigPath=/etc/nginx/conf.d/ + # Scheduled task execution task name RenewTLS-update certificate UpdateGeo-update geo file + cronName=$1 - # Is it a preview version - prereleaseStatus=false + #Number of attempts after tls installation failure + installTLSCount= - # ssl type - sslType= + #BTPanel status + # BTPanelStatus= + # Pagoda domain name + btDomain= + # nginx configuration file path + nginxConfigPath=/etc/nginx/conf.d/ + nginxStaticPath=/usr/share/nginx/html/ - # ssl mailbox - sslEmail= + # Is it a preview version? + prereleaseStatus=false - # check the number of days - sslRenewalDays=90 + # ssl type + sslType= - # dns ssl status - dnsSSLStatus= + #sslmail + sslEmail= - # dns tls domain - dnsTLSDomain= + # Check the number of days + sslRenewalDays=90 - # Whether the domain name installs a wildcard certificate through dns - installDNSACMEStatus= + # dns ssl status + dnsSSLStatus= - # custom port - customPort= + # dns tls domain + dnsTLSDomain= - # hysteria port - hysteriaPort= + # Whether the domain name installs a wildcard certificate through dns + installDNSACMEStatus= - # hysteria protocol - hysteriaProtocol= + # Custom port + customPort= - # hysteria delay - hysteriaLag= + #hysteriaport + hysteriaPort= - # hysteria downlink speed - hysteriaClientDownloadSpeed= + #hysteriaprotocol + hysteriaProtocol= - # hysteria uplink speed - hysteriaClientUploadSpeed= + #hysteriadelay + hysteriaLag= + # hysteriadownload speed + hysteriaClientDownloadSpeed= + + # hysteria uplink speed + hysteriaClientUploadSpeed= + + #Reality + realityPrivateKey= + realityServerNames= + realityDestDomain= + + #Port status + # isPortOpen= + # Wildcard domain name status + # wildcardDomainStatus= + # Port checked by nginx + #nginxIPort= + + # wget show progress + wgetShowProgressStatus= + + #warp + reservedWarpReg= + publicKeyWarpReg= + addressWarpReg= + secretKeyWarpReg= } -# read tls certificate details +# 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 + 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 + if [[ -n "${configPath}" && -z "${realityStatus}" ]]; then + local port= + port=$(jq -r .inbounds[0].port "${configPath}${frontingType}.json") + if [[ "${port}" != "443" ]]; then + customPort=${port} + fi + fi } -# Check the installation method +# Detect installation method readInstallType() { - coreInstallType= - configPath= - hysteriaConfigPath= + coreInstallType= + configPath= + hysteriaConfigPath= - # 1.Detect the installation directory - if [[ -d "/etc/v2ray-agent" ]]; then - # 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 Wrong selection, please select again" + checkBTPanel + else + domain=${btDomain} + if [[ ! -f "/etc/v2ray-agent/tls/${btDomain}.crt" && ! -f "/etc/v2ray-agent/tls/${btDomain}.key" ]]; then + ln -s "/www/server/panel/vhost/cert/${btDomain}/fullchain.pem" "/etc/v2ray-agent/tls/${btDomain}.crt" + ln -s "/www/server/panel/vhost/cert/${btDomain}/privkey.pem" "/etc/v2ray-agent/tls/${btDomain}.key" + fi + + nginxStaticPath="/www/wwwroot/${btDomain}/" + if [[ -f "/www/wwwroot/${btDomain}/.user.ini" ]]; then + chattr -i "/www/wwwroot/${btDomain}/.user.ini" + fi + nginxConfigPath="/www/server/panel/vhost/nginx/" + fi + else + echoContent red " ---> Wrong selection, please select again" + checkBTPanel + fi + fi + fi } -# Read the order of the current alpn +# Read the current alpn order readInstallAlpn() { - if [[ -n ${currentInstallProtocolType} ]]; then - local alpn - alpn=$(jq -r .inbounds[0].streamSettings.xtlsSettings.alpn[0] ${configPath}${frontingType}.json) - if [[ -n ${alpn} ]]; then - currentAlpn=${alpn} - fi - fi + if [[ -n "${currentInstallProtocolType}" && -z "${realityStatus}" ]]; then + local alpn + alpn=$(jq -r .inbounds[0].streamSettings.tlsSettings.alpn[0] ${configPath}${frontingType}.json) + if [[ -n ${alpn} ]]; then + currentAlpn=${alpn} + fi + fi } -# check firewall +# Check firewall allowPort() { - # If the firewall is enabled, add the corresponding open port - if systemctl status netfilter-persistent 2>/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 + local type=$2 + if [[ -z "${type}" ]]; then + type=tcp + fi + # If the firewall is enabled, add the corresponding open port + if systemctl status netfilter-persistent 2>/dev/null | grep -q "active (exited)"; then + local updateFirewalldStatus= + if ! iptables -L | grep -q "$1/${type}(mack-a)"; then + updateFirewalldStatus=true + iptables -I INPUT -p ${type} --dport "$1" -m comment --comment "allow $1/${type}(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 + 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/${type}"; then + sudo ufw allow "$1/${type}" + 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 + elif systemctl status firewalld 2>/dev/null | grep -q "active (running)"; then + local updateFirewalldStatus= + if ! firewall-cmd --list-ports --permanent | grep -qw "$1/${type}"; then + updateFirewalldStatus=true + local firewallPort=$1 + + if echo "${firewallPort}" | grep ":"; then + firewallPort=$(echo "${firewallPort}" | awk -F ":" '{print $1-$2}') + fi + + firewall-cmd --zone=public --add-port="${firewallPort}/${type}" --permanent + checkFirewalldAllowPort "${firewallPort}" + fi + + if echo "${updateFirewalldStatus}" | grep -q "true"; then + firewall-cmd --reload + fi + fi +} +# Get public IP +getPublicIP() { + local type=4 + if [[ -n "$1" ]]; then + type=$1 + fi + if [[ -n "${currentHost}" && -n "${currentRealityServerNames}" && "${currentRealityServerNames}" == "${currentHost}" && -z "$1" ]]; then + echo "${currentHost}" + else + local currentIP= + currentIP=$(curl -s "-${type}" http://www.cloudflare.com/cdn-cgi/trace | grep "ip" | awk -F "[=]" '{print $2}') + if [[ -z "${currentIP}" && -z "$1" ]]; then + currentIP=$(curl -s "-6" http://www.cloudflare.com/cdn-cgi/trace | grep "ip" | awk -F "[=]" '{print $2}') + fi + echo "${currentIP}" + 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 +# 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 + if ufw status | grep -q "$1"; then + echoContent green " ---> $1 port opened successfully" + else + echoContent red " ---> $1 port opening failed" + exit 0 + fi } # 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 + 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 } -# Read the hysteria network environment +# Read 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 + 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 +# Read Tuic configuration +readTuicConfig() { + if [[ -n "${tuicConfigPath}" ]]; then + tuicPort=$(jq -r .server <"${tuicConfigPath}config.json" | cut -d ':' -f 4) + tuicAlgorithm=$(jq -r .congestion_control <"${tuicConfigPath}config.json") + fi +} +# Read xray reality configuration +readXrayCoreRealityConfig() { + currentRealityServerNames= + currentRealityPublicKey= + currentRealityPrivateKey= + currentRealityPort= + + if [[ -n "${realityStatus}" ]]; then + currentRealityServerNames=$(jq -r .inbounds[0].streamSettings.realitySettings.serverNames[0] "${configPath}07_VLESS_vision_reality_inbounds.json") + currentRealityPublicKey=$(jq -r .inbounds[0].streamSettings.realitySettings.publicKey "${configPath}07_VLESS_vision_reality_inbounds.json") + currentRealityPrivateKey=$(jq -r .inbounds[0].streamSettings.realitySettings.privateKey "${configPath}07_VLESS_vision_reality_inbounds.json") + currentRealityPort=$(jq -r .inbounds[0].port "${configPath}07_VLESS_vision_reality_inbounds.json") + fi +} + +# Check the file directory and path readConfigHostPathUUID() { - currentPath= - currentDefaultPort= - currentUUID= - currentHost= - currentPort= - currentAdd= - # read path - if [[ -n "${configPath}" ]]; then - local fallback - fallback=$(jq -r -c '.inbounds[0].settings.fallbacks[]|select(.path)' ${configPath}${frontingType}.json | head -1) + currentPath= + currentDefaultPort= + currentUUID= + currentClients= + currentHost= + currentPort= + currentAdd= - local path - path=$(echo "${fallback}" | jq -r .path | awk -F "[/]" '{print $2}') + if [[ "${coreInstallType}" == "1" ]]; 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 - currentPath=$(echo "${path}" | awk -F "[t][c][p]" '{print $1}') - elif [[ $(echo "${fallback}" | jq -r .dest) == 31299 ]]; then - currentPath=$(echo "${path}" | awk -F "[v][w][s]" '{print $1}') - fi - # try to read alpn h2 Path + # Install + if [[ -n "${frontingType}" ]]; then + 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}') + currentAdd=$(jq -r .inbounds[0].add ${configPath}${frontingType}.json) - 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 [[ "${currentAdd}" == "null" ]]; then + currentAdd=${currentHost} + fi + currentPort=$(jq .inbounds[0].port ${configPath}${frontingType}.json) - 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") - 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 + currentUUID=$(jq -r .inbounds[0].settings.clients[0].id ${configPath}${frontingType}.json) + currentClients=$(jq -r .inbounds[0].settings.clients ${configPath}${frontingType}.json) + fi - if [[ -n "${defaultPortFile}" ]]; then - currentDefaultPort=$(echo "${defaultPortFile}" | awk -F [_] '{print $4}') - else - currentDefaultPort=$(jq -r .inbounds[0].port ${configPath}${frontingType}.json) - fi + # reality + if [[ -n "${realityStatus}" && -z "${currentClients}" ]]; then + currentUUID=$(jq -r .inbounds[0].settings.clients[0].id ${configPath}07_VLESS_vision_reality_inbounds.json) + currentClients=$(jq -r .inbounds[0].settings.clients ${configPath}07_VLESS_vision_reality_inbounds.json) - 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 - currentAdd=${currentHost} - fi - currentPort=$(jq .inbounds[0].port ${configPath}${frontingType}.json) + fi + elif [[ "${coreInstallType}" == "2" ]]; then + 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}') + currentAdd=$(jq -r .inbounds[0].settings.clients[0].add ${configPath}${frontingType}.json) - elif [[ "${coreInstallType}" == "2" || "${coreInstallType}" == "3" ]]; then - if [[ "${coreInstallType}" == "3" ]]; then + if [[ "${currentAdd}" == "null" ]]; then + currentAdd=${currentHost} + fi + currentUUID=$(jq -r .inbounds[0].settings.clients[0].id ${configPath}${frontingType}.json) + currentPort=$(jq .inbounds[0].port ${configPath}${frontingType}.json) + fi - 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) + #Read path + if [[ -n "${configPath}" && -n "${frontingType}" ]]; then + local fallback + fallback=$(jq -r -c '.inbounds[0].settings.fallbacks[]|select(.path)' ${configPath}${frontingType}.json | head -1) - if [[ "${currentAdd}" == "null" ]]; then - currentAdd=${currentHost} - fi - currentUUID=$(jq -r .inbounds[0].settings.clients[0].id ${configPath}${frontingType}.json) - currentPort=$(jq .inbounds[0].port ${configPath}${frontingType}.json) - fi + local path + path=$(echo "${fallback}" | jq -r .path | awk -F "[/]" '{print $2}') + + if [[ $(echo "${fallback}" | jq -r .dest) == 31297 ]]; then + currentPath=$(echo "${path}" | awk -F "[w][s]" '{print $1}') + elif [[ $(echo "${fallback}" | jq -r .dest) == 31299 ]]; then + currentPath=$(echo "${path}" | awk -F "[v][w][s]" '{print $1}') + 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 + checkBTPanel + 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 + + fi } -# status display +# Status display showInstallStatus() { - if [[ -n "${coreInstallType}" ]]; then - if [[ "${coreInstallType}" == 1 ]]; then - if [[ -n $(pgrep -f xray/xray) ]]; then - echoContent yellow "\nCore: Xray-core [running]" - else - echoContent yellow "\nCore: Xray-core[not running]" - fi + if [[ -n "${coreInstallType}" ]]; then + if [[ "${coreInstallType}" == 1 ]]; then + if [[ -n $(pgrep -f "xray/xray") ]]; then + echoContent yellow "\nCore: Xray-core[Running]" + else + echoContent yellow "\nCore: Xray-core[not running]" + fi - elif [[ "${coreInstallType}" == 2 || "${coreInstallType}" == 3 ]]; then - if [[ -n $(pgrep -f v2ray/v2ray) ]]; then - echoContent yellow "\nCore: v2ray-core[running]" - else - echoContent yellow "\nCore: v2ray-core[not running]" - fi - fi - # read protocol type - readInstallProtocolType + elif [[ "${coreInstallType}" == 2 || "${coreInstallType}" == 3 ]]; then + if [[ -n $(pgrep -f "v2ray/v2ray") ]]; then + echoContent yellow "\nCore: v2ray-core[Running]" + else + echoContent yellow "\nCore: v2ray-core[not running]" + fi + fi + #Read protocol type + readInstallProtocolType - if [[ -n ${currentInstallProtocolType} ]]; then - echoContent yellow "Protocol installed: \c" - fi - if echo ${currentInstallProtocolType} | grep -q 0; then - if [[ "${coreInstallType}" == 2 ]]; then - echoContent yellow "VLESS+TCP[TLS] \c" - else - echoContent yellow "VLESS+TCP[TLS/XTLS] \c" - fi - fi + if [[ -n ${currentInstallProtocolType} ]]; then + echoContent yellow "Installed protocol: \c" + fi + if echo ${currentInstallProtocolType} | grep -q 0; then + if [[ "${coreInstallType}" == 2 ]]; then + echoContent yellow "VLESS+TCP[TLS] \c" + else + echoContent yellow "VLESS+TCP[TLS_Vision] \c" + fi + fi - if echo ${currentInstallProtocolType} | grep -q trojan; then - if [[ "${coreInstallType}" == 1 ]]; then - echoContent yellow "Trojan+TCP[TLS/XTLS] \c" - fi - fi + if echo ${currentInstallProtocolType} | grep -q trojan; then + if [[ "${coreInstallType}" == 1 ]]; then + echoContent yellow "Trojan+TCP[TLS_Vision] \c" + fi + fi - if echo ${currentInstallProtocolType} | grep -q 1; then - echoContent yellow "VLESS+WS[TLS] \c" - fi + if echo ${currentInstallProtocolType} | grep -q 1; then + echoContent yellow "VLESS+WS[TLS] \c" + fi - if echo ${currentInstallProtocolType} | grep -q 2; then - echoContent yellow "Trojan+gRPC[TLS] \c" - fi + if echo ${currentInstallProtocolType} | grep -q 2; then + echoContent yellow "Trojan+gRPC[TLS] \c" + fi - if echo ${currentInstallProtocolType} | grep -q 3; then - echoContent yellow "VMess+WS[TLS] \c" - fi + if echo ${currentInstallProtocolType} | grep -q 3; then + echoContent yellow "VMess+WS[TLS] \c" + fi - if echo ${currentInstallProtocolType} | grep -q 4; then - echoContent yellow "Trojan+TCP[TLS] \c" - fi + if echo ${currentInstallProtocolType} | grep -q 4; then + echoContent yellow "Trojan+TCP[TLS] \c" + fi - if echo ${currentInstallProtocolType} | grep -q 5; then - echoContent yellow "VLESS+gRPC[TLS] \c" - fi - fi + if echo ${currentInstallProtocolType} | grep -q 5; then + echoContent yellow "VLESS+gRPC[TLS] \c" + fi + if echo ${currentInstallProtocolType} | grep -q 7; then + echoContent yellow "VLESS+Reality+Vision \c" + fi + if echo ${currentInstallProtocolType} | grep -q 8; then + echoContent yellow "VLESS+Reality+gRPC \c" + fi + 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)')" - handleV2Ray stop >/dev/null - rm -f /etc/systemd/system/v2ray.service - elif [[ "$1" == "xrayClean" ]]; then - rm -rf "$(find /etc/v2ray-agent/xray/* | grep -E '(config_full.json|conf)')" - handleXray stop >/dev/null - rm -f /etc/systemd/system/xray.service + if [[ "$1" == "v2rayClean" ]]; then + rm -rf "$(find /etc/v2ray-agent/v2ray/* | grep -E '(config_full.json|conf)')" + handleV2Ray stop >/dev/null + rm -f /etc/systemd/system/v2ray.service + elif [[ "$1" == "xrayClean" ]]; then + rm -rf "$(find /etc/v2ray-agent/xray/* | grep -E '(config_full.json|conf)')" + handleXray stop >/dev/null + rm -f /etc/systemd/system/xray.service - elif [[ "$1" == "v2rayDel" ]]; then - rm -rf /etc/v2ray-agent/v2ray/* + elif [[ "$1" == "v2rayDel" ]]; then + rm -rf /etc/v2ray-agent/v2ray/* - elif [[ "$1" == "xrayDel" ]]; then - rm -rf /etc/v2ray-agent/xray/* - fi + elif [[ "$1" == "xrayDel" ]]; then + rm -rf /etc/v2ray-agent/xray/* + fi } - initVar "$1" checkSystem checkCPUVendor @@ -592,207 +739,227 @@ readInstallProtocolType readConfigHostPathUUID readInstallAlpn readCustomPort -checkBTPanel -#---------------------------------------------------- +readXrayCoreRealityConfig +#------------------------------------------------ ---------- -# Initialize the 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/ + mkdir -p /etc/v2ray-agent/tls + mkdir -p /etc/v2ray-agent/subscribe_local/default + mkdir -p /etc/v2ray-agent/subscribe_local/clashMeta + + mkdir -p /etc/v2ray-agent/subscribe_remote/default + mkdir -p /etc/v2ray-agent/subscribe_remote/clashMeta + + mkdir -p /etc/v2ray-agent/subscribe/default + mkdir -p /etc/v2ray-agent/subscribe/clashMetaProfiles + mkdir -p /etc/v2ray-agent/subscribe/clashMeta + + 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/hysteria/conf + mkdir -p /etc/systemd/system/ + mkdir -p /tmp/v2ray-agent-tls/ + + mkdir -p /etc/v2ray-agent/warp + + mkdir -p /etc/v2ray-agent/tuic/conf } -# install toolkit +# Install toolkit installTools() { - echoContent skyBlue "\nProgress $1/${totalProgress} : Install Tool" - # Fix ubuntu individual system issues - if [[ "${release}" == "ubuntu" ]]; then - dpkg --configure -a - fi + echoContent skyBlue "\nProgress$1/${totalProgress}: Installation tools" + # Repair individual system problems in ubuntu + if [[ "${release}" == "ubuntu" ]]; then + dpkg --configure -a + fi - if [[ -n $(pgrep -f "apt") ]]; then - pgrep -f apt | xargs kill -9 - fi + if [[ -n $(pgrep -f "apt") ]]; then + pgrep -f apt | xargs kill -9 + fi - 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]" + 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 then 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} >/etc/v2ray-agent/install.log 2>&1 + if grep <"/etc/v2ray-agent/install.log" -q "changed"; then + ${updateReleaseInfoChange} >/dev/null 2>&1 + fi - if [[ "${release}" == "centos" ]]; then - rm -rf /var/run/yum.pid - ${installType} epel-release >/dev/null 2>&1 - fi + if [[ "${release}" == "centos" ]]; then + rm -rf /var/run/yum.pid + ${installType} epel-release >/dev/null 2>&1 + fi - # [[ -z `find /usr/bin /usr/sbin |grep -v grep|grep -w curl` ]] + # [[ -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" - ${installType} wget >/dev/null 2>&1 - fi + if ! find /usr/bin /usr/sbin | grep -q -w wget; then + 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" - ${installType} curl >/dev/null 2>&1 - fi + if ! find /usr/bin /usr/sbin | grep -q -w curl; then + 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" - ${installType} unzip >/dev/null 2>&1 - fi + if ! find /usr/bin /usr/sbin | grep -q -w unzip; then + 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" - ${installType} socat >/dev/null 2>&1 - fi + if ! find /usr/bin /usr/sbin | grep -q -w socat; then + 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" - ${installType} tar >/dev/null 2>&1 - fi + if ! find /usr/bin /usr/sbin | grep -q -w tar; then + 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" - if [[ "${release}" == "ubuntu" ]] || [[ "${release}" == "debian" ]]; then - ${installType} cron >/dev/null 2>&1 - else - ${installType} crontabs >/dev/null 2>&1 - fi - fi - if ! find /usr/bin /usr/sbin | grep -q -w jq; then - echoContent green " ---> install jq" - ${installType} jq >/dev/null 2>&1 - fi + if ! find /usr/bin /usr/sbin | grep -q -w cron; then + echoContent green " ---> install crontabs" + if [[ "${release}" == "ubuntu" ]] || [[ "${release}" == "debian" ]]; then + ${installType} cron >/dev/null 2>&1 + else + ${installType} crontabs >/dev/null 2>&1 + fi + fi + if ! find /usr/bin /usr/sbin | grep -q -w jq; then + 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" - ${installType} binutils >/dev/null 2>&1 - fi + if ! find /usr/bin /usr/sbin | grep -q -w binutils; then + 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" - ${installType} inetutils-ping >/dev/null 2>&1 - fi + if ! find /usr/bin /usr/sbin | grep -q -w ping6; then + 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" - ${installType} qrencode >/dev/null 2>&1 - fi + if ! find /usr/bin /usr/sbin | grep -q -w qrencode; then + echoContent green " ---> Install qrencode" + ${installType} qrencode >/dev/null 2>&1 + fi - 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 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" - ${installType} lsb-release >/dev/null 2>&1 - fi + if ! find /usr/bin /usr/sbin | grep -q -w lsb-release; then + echoContent green " ---> install lsb-release" + ${installType} lsb-release >/dev/null 2>&1 + fi - 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 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 + 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 + # Detect nginx version and provide the option of uninstalling it + if [[ "${selectCustomInstallType}" == "7" ]]; then + echoContent green " ---> Detected services that do not depend on Nginx, skip installation" + else + if ! find /usr/bin /usr/sbin | grep -q -w nginx; then + 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 "Read that the current Nginx version does not support gRPC, which will cause the installation to fail. Do you want to uninstall Nginx and reinstall it? [y/n]:" unInstallNginxStatus + if [[ "${unInstallNginxStatus}" == "y" ]]; then + ${removeType} nginx >/dev/null 2>&1 + echoContent yellow " ---> nginx uninstall completed" + echoContent green " ---> Install nginx" + installNginxTools >/dev/null 2>&1 + else + exit 0 + fi + fi + fi + fi - if ! find /usr/bin /usr/sbin | grep -q -w nginx; then - 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 "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 uninstallation completed" - echoContent green " ---> install nginx" - installNginxTools >/dev/null 2>&1 - else - exit 0 - fi - fi - fi - if ! find /usr/bin /usr/sbin | grep -q -w semanage; then - echoContent green " ---> install semanage" - ${installType} bash-completion >/dev/null 2>&1 + if ! find /usr/bin /usr/sbin | grep -q -w semanage; then + echoContent green " ---> Install semanage" + ${installType} bash-completion >/dev/null 2>&1 - if [[ "${centosVersion}" == "7" ]]; then - policyCoreUtils="policycoreutils-python.x86_64" - elif [[ "${centosVersion}" == "8" ]]; then - policyCoreUtils="policycoreutils-python-utils-2.9-9.el8.noarch" - fi + if [[ "${centosVersion}" == "7" ]]; then + policyCoreUtils="policycoreutils-python.x86_64" + elif [[ "${centosVersion}" == "8" ]]; then + policyCoreUtils="policycoreutils-python-utils-2.9-9.el8.noarch" + fi - if [[ -n "${policyCoreUtils}" ]]; then - ${installType} ${policyCoreUtils} >/dev/null 2>&1 - fi - if [[ -n $(which semanage) ]]; then - semanage port -a -t http_port_t -p tcp 31300 + if [[ -n "${policyCoreUtils}" ]]; then + ${installType} ${policyCoreUtils} >/dev/null 2>&1 + fi + if [[ -n $(which semanage) ]]; then + semanage port -a -t http_port_t -p tcp 31300 - fi - fi + fi + fi + if [[ "${selectCustomInstallType}" == "7" ]]; then + echoContent green " ---> Detected services that do not depend on certificates, skip installation" + else + 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 >/etc/v2ray-agent/tls/acme.log 2>&1 - 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 >/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--->" + tail -n 100 /etc/v2ray-agent/tls/acme.log + echoContent yellow "Error troubleshooting:" + echoContent red "1.Failed to obtain Github files. Please wait for Github to recover and try again. The recovery progress can be viewed [https://www.githubstatus.com/]" + echoContent red "2.There is a bug in the acme.sh script, please check [https://github.com/acmesh-official/acme.sh] issues" + echoContent red "3.For pure IPv6 machines, please set up NAT64.You can execute the following command. If it still does not work after adding the following command, please try to change to another NAT64" + # echoContent skyBlue " echo -e \"nameserver 2001:67c:2b0::4\\\nnameserver 2a00:1098:2c::1\" >> /etc/resolv.conf" + echoContent skyBlue "sed -i \"1i\\\nameserver 2001:67c:2b0::4\\\nnameserver 2a00:1098:2c::1\" /etc/resolv.conf" + exit 0 + fi + fi + fi - if [[ ! -d "$HOME/.acme.sh" ]] || [[ -z $(find "$HOME/.acme.sh/acme.sh") ]]; then - echoContent red "acme installation failed--->" - tail -n 100 /etc/v2ray-agent/tls/acme.log - 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 installNginxTools() { - if [[ "${release}" == "debian" ]]; then - sudo apt install gnupg2 ca-certificates lsb-release -y >/dev/null 2>&1 - echo "deb http://nginx.org/packages/mainline/debian $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list >/dev/null 2>&1 - echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" | sudo tee /etc/apt/preferences.d/99nginx >/dev/null 2>&1 - curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key >/dev/null 2>&1 - # gpg --dry-run --quiet --import --import-options import-show /tmp/nginx_signing.key - sudo mv /tmp/nginx_signing.key /etc/apt/trusted.gpg.d/nginx_signing.asc - sudo apt update >/dev/null 2>&1 + if [[ "${release}" == "debian" ]]; then + sudo apt install gnupg2 ca-certificates lsb-release -y >/dev/null 2>&1 + echo "deb http://nginx.org/packages/mainline/debian $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list >/dev/null 2>&1 + echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" | sudo tee /etc/apt/preferences.d/99nginx >/dev/null 2>&1 + curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key >/dev/null 2>&1 + # gpg --dry-run --quiet --import --import-options import-show /tmp/nginx_signing.key + sudo mv /tmp/nginx_signing.key /etc/apt/trusted.gpg.d/nginx_signing.asc + sudo apt update >/dev/null 2>&1 - elif [[ "${release}" == "ubuntu" ]]; then - sudo apt install gnupg2 ca-certificates lsb-release -y >/dev/null 2>&1 - echo "deb http://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list >/dev/null 2>&1 - echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" | sudo tee /etc/apt/preferences.d/99nginx >/dev/null 2>&1 - curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key >/dev/null 2>&1 - # gpg --dry-run --quiet --import --import-options import-show /tmp/nginx_signing.key - sudo mv /tmp/nginx_signing.key /etc/apt/trusted.gpg.d/nginx_signing.asc - sudo apt update >/dev/null 2>&1 + elif [[ "${release}" == "ubuntu" ]]; then + sudo apt install gnupg2 ca-certificates lsb-release -y >/dev/null 2>&1 + echo "deb http://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" | sudo tee /etc/apt/sources.list.d/nginx.list >/dev/null 2>&1 + echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" | sudo tee /etc/apt/preferences.d/99nginx >/dev/null 2>&1 + curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key >/dev/null 2>&1 + # gpg --dry-run --quiet --import --import-options import-show /tmp/nginx_signing.key + sudo mv /tmp/nginx_signing.key /etc/apt/trusted.gpg.d/nginx_signing.asc + sudo apt update >/dev/null 2>&1 - elif [[ "${release}" == "centos" ]]; then - ${installType} yum-utils >/dev/null 2>&1 - cat </etc/yum.repos.d/nginx.repo + elif [[ "${release}" == "centos" ]]; then + ${installType} yum-utils >/dev/null 2>&1 + cat </etc/yum.repos.d/nginx.repo [nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/\$releasever/\$basearch/ @@ -809,164 +976,246 @@ enabled=0 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true EOF - sudo yum-config-manager --enable nginx-mainline >/dev/null 2>&1 - fi - ${installType} nginx >/dev/null 2>&1 - systemctl daemon-reload - systemctl enable nginx + sudo yum-config-manager --enable nginx-mainline >/dev/null 2>&1 + fi + ${installType} nginx >/dev/null 2>&1 + systemctl daemon-reload + systemctl enable nginx } -# install warp +# 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 - sudo apt update >/dev/null 2>&1 + if [[ "${cpuVendor}" == "arm" ]]; then + echoContent red " ---> The official WARP client does not support ARM architecture" + exit 0 + fi - elif [[ "${release}" == "ubuntu" ]]; then - curl -s https://pkg.cloudflareclient.com/pubkey.gpg | sudo apt-key add - >/dev/null 2>&1 - echo "deb http://pkg.cloudflareclient.com/ focal main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list >/dev/null 2>&1 - sudo apt update >/dev/null 2>&1 + ${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 + sudo apt update >/dev/null 2>&1 - 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 - fi + elif [[ "${release}" == "ubuntu" ]]; then + curl -s https://pkg.cloudflareclient.com/pubkey.gpg | sudo apt-key add - >/dev/null 2>&1 + echo "deb http://pkg.cloudflareclient.com/ focal main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list >/dev/null 2>&1 + sudo apt update >/dev/null 2>&1 - echoContent green " ---> install WARP" - ${installType} cloudflare-warp >/dev/null 2>&1 - 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 - warp-cli --accept-tos enable-always-on + 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 + fi - # 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 + echoContent green " ---> Install WARP" + ${installType} cloudflare-warp >/dev/null 2>&1 + 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 + warp-cli --accept-tos enable-always-on + + local warpStatus= + warpStatus=$(curl -s --socks5 127.0.0.1:31303 https://www.cloudflare.com/cdn-cgi/trace | grep "warp" | cut -d "=" -f 2) + + if [[ "${warpStatus}" == "on" ]]; then + echoContent green " ---> WARP started successfully" + fi } + +# Check the IP of the domain name through dns +checkDNSIP() { + local domain=$1 + local dnsIP= + local type=4 + dnsIP=$(dig @1.1.1.1 +time=1 +short "${domain}") + if [[ -z "${dnsIP}" ]]; then + dnsIP=$(dig @8.8.8.8 +time=1 +short "${domain}") + fi + if echo "${dnsIP}" | grep -q "timed out" || [[ -z "${dnsIP}" ]]; then + echo + echoContent red " ---> Unable to obtain domain name IPv4 address through DNS" + echoContent green " ---> Try to check the domain name IPv6 address" + dnsIP=$(dig @2606:4700:4700::1111 +time=1 aaaa +short "${domain}") + type=6 + if echo "${dnsIP}" | grep -q "network unreachable" || [[ -z "${dnsIP}" ]]; then + echoContent red " ---> Unable to obtain domain name IPv6 address through DNS, exit installation" + exit 0 + fi + fi + local publicIP= + + publicIP=$(getPublicIP "${type}") + if [[ "${publicIP}" != "${dnsIP}" ]]; then + echoContent red " ---> The domain name resolution IP is inconsistent with the current server IP\n" + echoContent yellow " ---> Please check whether the domain name resolution is valid and correct" + echoContent green " ---> Current VPS IP: ${publicIP}" + echoContent green " ---> DNS resolution IP: ${dnsIP}" + exit 0 + else + echoContent green " ---> Domain name IP verification passed" + fi +} +# Check the actual open status of the port +checkPortOpen() { + + local port=$1 + local domain=$2 + local checkPortOpenResult= + + allowPort "${port}" + + #Initialize nginx configuration + touch ${nginxConfigPath}checkPortOpen.conf + cat <${nginxConfigPath}checkPortOpen.conf + server { + listen ${port}; + listen [::]:${port}; + server_name ${domain}; + location /checkPort { + return 200 'fjkvymb6len'; + } + location /ip { + proxy_set_header Host \$host; + proxy_set_header X-Real-IP \$remote_addr; + proxy_set_header REMOTE-HOST \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + default_type text/plain; + return 200 \$proxy_add_x_forwarded_for; + } + } +EOF + handleNginx start + + # Check domain name + port opening + checkPortOpenResult=$(curl -s -m 2 "http://${domain}:${port}/checkPort") + localIP=$(curl -s -m 2 "http://${domain}:${port}/ip") + rm "${nginxConfigPath}checkPortOpen.conf" + handleNginx stop + if [[ "${checkPortOpenResult}" == "fjkvymb6len" ]]; then + echoContent green " ---> Detected that ${port} port is open" + else + echoContent green " ---> No open ${port} port detected, exit installation" + if echo "${checkPortOpenResult}" | grep -q "cloudflare"; then + echoContent yellow " ---> Please close the cloud and wait three minutes to try again" + else + if [[ -z "${checkPortOpenResult}" ]]; then + echoContent red " ---> Please check if there is a web firewall, such as Oracle and other cloud service providers" + echoContent red " ---> Check whether you have installed nginx and there are configuration conflicts. You can try DD pure system and try again" + else + echoContent red " ---> Error log: ${checkPortOpenResult}, please submit feedback on this error log through issues" + fi + fi + exit 0 + fi + checkIP "${localIP}" +} + # Initialize Nginx application certificate configuration initTLSNginxConfig() { - handleNginx stop - echoContent skyBlue "\nProgress $1/${totalProgress} : Initialize Nginx application certificate configuration" - if [[ -n "${currentHost}" ]]; then - echo - 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}" - else - echo - 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 to be configured Example: www.v2ray-agent.com --->" - read -r -p "domain name:" domain - fi + handleNginx stop + echoContent skyBlue "\nProgress $1/${totalProgress}: Initializing Nginx application certificate configuration" + if [[ -n "${currentHost}" ]]; then + echo + read -r -p "Read the last installation record. Do you want to use the domain name from the last installation? [y/n]:" historyDomainStatus + if [[ "${historyDomainStatus}" == "y" ]]; then + domain=${currentHost} + echoContent yellow "\n ---> Domain name: ${domain}" + else + echo + echoContent yellow "Please enter the domain name to be configured: www.v2ray-agent.com --->" + read -r -p "domain name:" domain + fi + else + echo + echoContent yellow "Please enter the domain name to be configured: www.v2ray-agent.com --->" + read -r -p "domain name:" domain + fi - if [[ -z ${domain} ]]; then - echoContent red "The domain name cannot be empty--->" - initTLSNginxConfig 3 - else - dnsTLSDomain=$(echo "${domain}" | awk -F "[.]" '{print $(NF-1)"."$NF}') - customPortFunction - local port=80 - if [[ -n "${customPort}" ]]; then - port=${customPort} - fi + if [[ -z ${domain} ]]; then + echoContent red "Domain name cannot be empty--->" + initTLSNginxConfig 3 + else + dnsTLSDomain=$(echo "${domain}" | awk -F "[.]" '{print $(NF-1)"."$NF}') + customPortFunction + # Change setting + handleNginx stop + # touch ${nginxConfigPath}alone.conf + # nginxIPort=80 + # if [[ "${wildcardDomainStatus}" == "true" ]]; then + # nginxIPort=${port} + # fi + # + # cat <${nginxConfigPath}alone.conf + #server { + # listen ${port}; + # listen [::]:${port}; + # server_name ${domain}; + # location /test { + # return 200 'fjkvymb6len'; + # } + # location /ip { + # proxy_set_header Host \$host; + # proxy_set_header X-Real-IP \$remote_addr; + # proxy_set_header REMOTE-HOST \$remote_addr; + # proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + # default_type text/plain; + # return 200 \$proxy_add_x_forwarded_for; + # } + #} + #EOF + fi - # Change setting - touch ${nginxConfigPath}alone.conf - cat <${nginxConfigPath}alone.conf -server { - listen ${port}; - listen [::]:${port}; - server_name ${domain}; - root /usr/share/nginx/html; - location ~ /.well-known { - allow all; - } - location /test { - return 200 'fjkvymb6len'; - } - location /ip { - proxy_set_header Host \$host; - proxy_set_header X-Real-IP \$remote_addr; - proxy_set_header REMOTE-HOST \$remote_addr; - proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; - default_type text/plain; - return 200 \$proxy_add_x_forwarded_for; - } -} -EOF - fi - - readAcmeTLS + # readAcmeTLS + # handleNginx start } -# Modify nginx redirect configuration +# Delete nginx default configuration +removeNginxDefaultConf() { + if [[ -f ${nginxConfigPath}default.conf ]]; then + if [[ "$(grep -c "server_name" <${nginxConfigPath}default.conf)" == "1" ]] && [[ "$(grep -c "server_name localhost;" <${nginxConfigPath}default.conf)" == "1" ]]; then + echoContent green " ---> Delete Nginx default configuration" + rm -rf ${nginxConfigPath}default.conf + fi + fi +} +# Modify nginx redirection configuration updateRedirectNginxConf() { + local redirectDomain= + redirectDomain=${domain}:${port} - # 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 + cat <${nginxConfigPath}alone.conf server { - listen 80; - server_name ${domain}; - return 302 https://${redirectDomain}; -} -server { - listen 127.0.0.1:31300; - server_name _; - return 403; + listen 127.0.0.1:31300; + server_name _; + return 403; } EOF - if echo "${selectCustomInstallType}" | grep -q 2 && echo "${selectCustomInstallType}" | grep -q 5 || [[ -z "${selectCustomInstallType}" ]]; then + if echo "${selectCustomInstallType}" | grep -q 2 && echo "${selectCustomInstallType}" | grep -q 5 || [[ -z "${selectCustomInstallType}" ]]; then + local nginxH2Conf= + nginxH2Conf="listen 127.0.0.1:31302 http2 so_keepalive=on;" + nginxVersion=$(nginx -v 2>&1) - cat <>${nginxConfigPath}alone.conf + if echo "${nginxVersion}" | grep -q "1.25"; then + nginxH2Conf="listen 127.0.0.1:31302 so_keepalive=on;http2 on;" + fi + cat <>${nginxConfigPath}alone.conf server { - listen 127.0.0.1:31302 http2 so_keepalive=on; + ${nginxH2Conf} server_name ${domain}; - root /usr/share/nginx/html; + root ${nginxStaticPath}; client_header_timeout 1071906480m; keepalive_timeout 1071906480m; - location /s/ { - add_header Content-Type text/plain; - alias /etc/v2ray-agent/subscribe/; + location ~ ^/s/(clashMeta|default|clashMetaProfiles)/(.*) { + default_type 'text/plain; charset=utf-8'; + alias /etc/v2ray-agent/subscribe/\$1/\$2; } location /${currentPath}grpc { @@ -995,19 +1244,19 @@ server { } } EOF - elif echo "${selectCustomInstallType}" | grep -q 5 || [[ -z "${selectCustomInstallType}" ]]; then - cat <>${nginxConfigPath}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}; - root /usr/share/nginx/html; - location /s/ { - add_header Content-Type text/plain; - alias /etc/v2ray-agent/subscribe/; + root ${nginxStaticPath}; + location ~ ^/s/(clashMeta|default|clashMetaProfiles)/(.*) { + default_type 'text/plain; charset=utf-8'; + alias /etc/v2ray-agent/subscribe/\$1/\$2; } location /${currentPath}grpc { client_max_body_size 0; -# keepalive_time 1071906480m; +# keepalive_time 1071906480m; keepalive_requests 4294967296; client_body_timeout 1071906480m; send_timeout 1071906480m; @@ -1019,16 +1268,16 @@ server { } EOF - elif echo "${selectCustomInstallType}" | grep -q 2 || [[ -z "${selectCustomInstallType}" ]]; then + elif echo "${selectCustomInstallType}" | grep -q 2 || [[ -z "${selectCustomInstallType}" ]]; then - cat <>${nginxConfigPath}alone.conf + cat <>${nginxConfigPath}alone.conf server { listen 127.0.0.1:31302 http2; server_name ${domain}; - root /usr/share/nginx/html; - location /s/ { - add_header Content-Type text/plain; - alias /etc/v2ray-agent/subscribe/; + root ${nginxStaticPath}; + location ~ ^/s/(clashMeta|default|clashMetaProfiles)/(.*) { + default_type 'text/plain; charset=utf-8'; + alias /etc/v2ray-agent/subscribe/\$1/\$2; } location /${currentPath}trojangrpc { client_max_body_size 0; @@ -1043,899 +1292,986 @@ server { } } EOF - else + else - cat <>${nginxConfigPath}alone.conf + cat <>${nginxConfigPath}alone.conf server { listen 127.0.0.1:31302 http2; server_name ${domain}; - root /usr/share/nginx/html; - location /s/ { - add_header Content-Type text/plain; - alias /etc/v2ray-agent/subscribe/; - } + root ${nginxStaticPath}; + + location ~ ^/s/(clashMeta|default|clashMetaProfiles)/(.*) { + default_type 'text/plain; charset=utf-8'; + alias /etc/v2ray-agent/subscribe/\$1/\$2; + } location / { } } EOF - fi + fi - cat <>${nginxConfigPath}alone.conf + cat <>${nginxConfigPath}alone.conf server { listen 127.0.0.1:31300; server_name ${domain}; - root /usr/share/nginx/html; - location /s/ { - add_header Content-Type text/plain; - alias /etc/v2ray-agent/subscribe/; - } + root ${nginxStaticPath}; + location ~ ^/s/(clashMeta|default|clashMetaProfiles)/(.*) { + default_type 'text/plain; charset=utf-8'; + alias /etc/v2ray-agent/subscribe/\$1/\$2; + } location / { add_header Strict-Transport-Security "max-age=15552000; preload" always; } } EOF - + handleNginx stop } # check ip checkIP() { - 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") + echoContent skyBlue "\n ---> Check the domain name ip" + local localIP=$1 - 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 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 + 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 the dns to take effect, which is expected to take effect within three minutes" + echoContent yellow " --->4.If you report Nginx startup problems, please start nginx manually to check the errors. If you cannot handle it yourself, please submit issues" + echo + echoContent skyBlue " ---> If the above settings are correct, please reinstall a pure system and try again" + if [[ -n ${localIP} ]]; then + echoContent yellow " ---> Detection of abnormal return value, it is recommended to manually uninstall nginx and re-execute the script" + echoContent red " ---> Exception result: ${localIP}" + fi + exit 0 + else + if echo "${localIP}" | awk -F "[,]" '{print $2}' | grep -q "." || echo "${localIP}" | awk -F "[,]" '{ print $2}' | grep -q ":"; then + echoContent red "\n ---> Multiple IPs were detected, please confirm whether to turn off cloudflare" + echoContent yellow " ---> Wait three minutes after closing the cloud and try again" + echoContent yellow " ---> The detected IP is as follows: [${localIP}]" + exit 0 + fi + # echoContent green " ---> The current domain name ip is: [${localIP}]" + echoContent green " ---> Check that the current domain name IP is correct" + fi } -# custom email +# 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 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 + 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 your email address:" sslEmail + if echo "${sslEmail}" | grep -q "@"; then + echo "ACCOUNT_EMAIL='${sslEmail}'" >>/root/.acme.sh/account.conf + echoContent green " ---> Added successfully" + else + echoContent yellow "Please re-enter the correct email format [Example: username@example.com]" + customSSLEmail + fi + fi + fi } -# select ssl installation type +#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 + if [[ -z "${sslType}" ]]; then + echoContent red "\n==============================================================" + echoContent yellow "1.letsencrypt[default]" + echoContent yellow "2.zerossl" + echoContent yellow "3.buypass[Does not support DNS application]" + echoContent red "================================================== ===============" + read -r -p "Please select [Enter] to use the default:" selectSSLType + case ${selectSSLType} in + 1) + sslType="letsencrypt" + ;; + 2) + sslType="zerossl" + ;; + 3) + sslType="buypass" + ;; + *) + sslType="letsencrypt" + ;; + esac + echo "${sslType}" >/etc/v2ray-agent/tls/ssl_type - fi + fi } -# Select the acme installation certificate method +#Select 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 - 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 + local installSSLIPv6= - readAcmeTLS + 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 + dnsSSLStatus=true + #else + # if [[ -z "${dnsSSLStatus}" ]]; then + # read -r -p "Whether to use DNS to apply for a certificate? If you do not know how to use DNS to apply for a certificate, please enter n[y/n]:" installSSLDNStatus + # + # if [[ ${installSSLDNStatus} == 'y' ]]; then + # dnsSSLStatus=true + #else + #dnsSSLStatus=false + #fi + # fi + + fi + acmeInstallSSL + + readAcmeTLS } # Install SSL certificate acmeInstallSSL() { - if [[ "${dnsSSLStatus}" == "true" ]]; then + if [[ "${dnsSSLStatus}" == "true" ]]; then - 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 + sudo "$HOME/.acme.sh/acme.sh" --issue -d "*.${dnsTLSDomain}" -d "${dnsTLSDomain}" --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please -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 + 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 add DNS TXT record manually" + echoContent yellow " ---> Please refer to this tutorial for adding method, https://github.com/mack-a/v2ray-agent/blob/master/documents/dns_txt.md" + echoContent yellow " ---> Just like installing wildcard certificates on multiple machines with the same domain name, please add multiple TXT records. There is no need to modify the previously added TXT records." + echoContent green " ---> name: _acme-challenge" + echoContent green " ---> value: ${txtValue}" + echoContent yellow " ---> Please wait 1-2 minutes after the addition is completed" + echo + read -r -p "Whether the addition is completed [y/n]:" addDNSTXTRecordStatus + if [[ "${addDNSTXTRecordStatus}" == "y" ]]; then + local txtAnswer= + txtAnswer=$(dig @1.1.1.1 +nocmd "_acme-challenge.${dnsTLSDomain}" txt +noall +answer | awk -F "[\"]" '{print $2}') + if echo "${txtAnswer}" | grep -q "^${txtValue}"; then + echoContent green " ---> TXT record verification passed" + echoContent green " ---> Generating certificate" + if [[ -n "${installSSLIPv6}" ]]; then + sudo "$HOME/.acme.sh/acme.sh" --renew -d "*.${dnsTLSDomain}" -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 + sudo "$HOME/.acme.sh/acme.sh" --renew -d "*.${dnsTLSDomain}" -d "${dnsTLSDomain}" --yes-I-know-dns-manual-mode-enough-go-ahead-please --ecc --server "${sslType}" 2>&1 | tee -a /etc/v2ray-agent/tls/acme.log >/dev/null + fi + else + echoContent red " ---> Verification failed, please wait 1-2 minutes and try again" + 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 +# 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 + local historyCustomPortStatus= + if [[ -n "${customPort}" || -n "${currentPort}" ]]; then + echo + read -r -p "Read the port from the last installation. Do you want to use the port from the last installation? [y/n]:" historyCustomPortStatus + if [[ "${historyCustomPortStatus}" == "y" ]]; then + port=${currentPort} + echoContent yellow "\n ---> Port: ${port}" + fi + fi + if [[ -z "${currentPort}" ]] || [[ "${historyCustomPortStatus}" == "n" ]]; then + echo - 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 + if [[ -n "${btDomain}" ]]; then + echoContent yellow "Please enter the port [cannot be the same as the BT Panel port, press Enter to be random]" + read -r -p "port:" port + if [[ -z "${port}" ]]; then + port=$((RANDOM % 20001 + 10000)) + fi + else + echo + echoContent yellow "Please enter the port [default: 443], you can customize the port [press Enter to use the default]" + read -r -p "port:" port + if [[ -z "${port}" ]]; then + port=443 + fi + if [[ "${port}" == "${currentRealityPort}" ]]; then + handleXray stop + fi + + # todo dns api + fi + + if [[ -n "${port}" ]]; then + if ((port >= 1 && port <= 65535)); then + allowPort "${port}" + echoContent yellow "\n ---> Port: ${port}" + if [[ -z "${btDomain}" ]]; then + checkDNSIP "${domain}" + removeNginxDefaultConf + checkPortOpen "${port}" "${domain}" + fi + else + echoContent red " ---> Port input error" + exit 0 + fi + else + echoContent red " ---> Port cannot be empty" + exit 0 + fi + fi } -# 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 +# Check whether the port is occupied +checkPort() { + if [[ -n "$1" ]] && lsof -i "tcp:$1" | grep -q LISTEN; then + echoContent red "\n ---> $1 port is occupied, please close it manually and install\n" + lsof -i "tcp:$1" | grep LISTEN + exit 0 + fi } -# install TLS +# Install TLS installTLS() { - echoContent skyBlue "\nProgress $1/${totalProgress} : Apply for TLS certificate\n" - local tlsDomain=${domain} + echoContent skyBlue "\nProgress$1/${totalProgress}: Apply for TLS certificate\n" + local tlsDomain=${domain} - # 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 - echoContent green " ---> Certificate detected" - # checkTLStatus - renewalTLS + # 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 + echoContent green " ---> Certificate detected" + # checkTLStatus + renewalTLS - 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 + 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 the certificate has not expired or is customized, 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" + 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, need to rely on port 80" + allowPort 80 + if [[ "${installDNSACMEStatus}" != "true" ]]; then + switchSSLType + customSSLEmail + selectAcmeInstallSSL + #else + # echoContent green " ---> A wildcard certificate has been detected and is being automatically generated" + fi + # 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}" --fullchainpath "/etc/v2ray-agent/tls/${tlsDomain}.crt" -- keypath "/etc/v2ray-agent/tls/${tlsDomain}.key" --ecc >/dev/null + # fi + # + # el + if [[ -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 [[ "${installDNSACMEStatus}" != "true" ]]; then - switchSSLType - customSSLEmail - selectAcmeInstallSSL - else - echoContent green " ---> Detected that a wildcard certificate has been installed, automatically generating" - 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 + tail -n 10 /etc/v2ray-agent/tls/acme.log + if [[ ${installTLSCount} == "1" ]]; then + echoContent red " ---> TLS installation failed, please check the acme log" + exit 0 + fi - 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 + installTLSCount=1 + echo - 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 tail -n 10 /etc/v2ray-agent/tls/acme.log | grep -q "Could not validate email address as valid"; then + echoContent red " ---> The email cannot pass SSL vendor verification, please re-enter" + echo + customSSLEmail "validate email" + installTLS "$1" + else + installTLS "$1" + fi + 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 - tail -n 10 /etc/v2ray-agent/tls/acme.log - if [[ ${installTLSCount} == "1" ]]; then - echoContent red " ---> TLS installation failed, please check the acme log" - exit 0 - fi - - installTLSCount=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 generated successfully" - else - echoContent yellow " ---> acme.sh is not installed" - exit 0 - fi -} -# Configure fake blog -initNginxConfig() { - echoContent skyBlue "\nProgress $1/${totalProgress} : configure Nginx" - - cat <${nginxConfigPath}alone.conf -server { - listen 80; - listen [::]:80; - server_name ${domain}; - root /usr/share/nginx/html; - location ~ /.well-known {allow all;} - location /test {return 200 'fjkvymb6len';} -} -EOF + echoContent green " ---> TLS generated successfully" + else + echoContent yellow " ---> acme.sh is not installed" + exit 0 + fi } -# custom/random path +#Initialize random string +initRandomPath() { + local chars="abcdefghijklmnopqrtuxyz" + local initCustomPath= + for i in {1..4}; do + echo "${i}" >/dev/null + initCustomPath+="${chars:RANDOM%${#chars}:1}" + done + customPath=${initCustomPath} +} + +# Custom/random path randomPathFunction() { - echoContent skyBlue "\nProgress $1/${totalProgress} : generate random path" + echoContent skyBlue "\nProgress$1/${totalProgress}: Generate random path" - if [[ -n "${currentPath}" ]]; then - echo - read -r -p "Read the last installation record, do you use the path of the last installation? [y/n]:" historyPathStatus - echo - fi + if [[ -n "${currentPath}" ]]; then + echo + read -r -p "Read the last installation record. Do you want to use the path from the last installation? [y/n]:" historyPathStatus + echo + fi - if [[ "${historyPathStatus}" == "y" ]]; then - customPath=${currentPath} - echoContent green " ---> Use successfully\n" - else - 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 '[:upper:]' '[:lower:]' | head -1) - currentPath=${customPath:0:4} - customPath=${currentPath} - else - currentPath=${customPath} - fi - - fi - echoContent yellow "\n path:${currentPath}" - echoContent skyBlue "\n----------------------------" + if [[ "${historyPathStatus}" == "y" ]]; then + customPath=${currentPath} + echoContent green " ---> Used successfully\n" + else + echoContent yellow "Please enter a custom path [eg: alone], no slash required, [Enter] random path" + read -r -p 'path:' customPath + if [[ -z "${customPath}" ]]; then + initRandomPath + currentPath=${customPath} + else + if [[ "${customPath: -2}" == "ws" ]]; then + echo + echoContent red " ---> The custom path cannot end with ws, otherwise the splitting path cannot be distinguished" + randomPathFunction "$1" + else + currentPath=${customPath} + fi + fi + fi + echoContent yellow "\n path:${currentPath}" + echoContent skyBlue "\n----------------------------" } -# Nginx Camouflage Blog +# Nginx disguise blog nginxBlog() { - 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 "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)) - 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 fake site successfully" - fi - else - 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 fake site successfully" - fi + echoContent skyBlue "\nProgress$1/${totalProgress}: Add fake site" + if [[ -d "${nginxStaticPath}" && -f "${nginxStaticPath}/check" ]]; then + echo + read -r -p "Detected installation of fake site, do you need to reinstall [y/n]:" nginxBlogInstallStatus + if [[ "${nginxBlogInstallStatus}" == "y" ]]; then + rm -rf "${nginxStaticPath}" + randomNum=$((RANDOM % 6 + 1)) + wget -q -P "${nginxStaticPath}" https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${randomNum}.zip >/dev/null + unzip -o "${nginxStaticPath}html${randomNum}.zip" -d "${nginxStaticPath}" >/dev/null + rm -f "${nginxStaticPath}html${randomNum}.zip*" + echoContent green " ---> Added fake site successfully" + fi + else + randomNum=$((RANDOM % 6 + 1)) + rm -rf "${nginxStaticPath}" + wget -q -P "${nginxStaticPath}" https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${randomNum}.zip >/dev/null + unzip -o "${nginxStaticPath}html${randomNum}.zip" -d "${nginxStaticPath}" >/dev/null + rm -f "${nginxStaticPath}html${randomNum}.zip*" + echoContent green " ---> Added fake site successfully" + fi } # Modify http_port_t port updateSELinuxHTTPPortT() { - $(find /usr/bin /usr/sbin | grep -w journalctl) -xe >/etc/v2ray-agent/nginx_error.log 2>&1 + $(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 -q -w semanage && find /usr/bin /usr/sbin | grep -q -w getenforce && grep -E "31300|31302" Check if the 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 + 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 + else + exit 0 + fi } -# Operate Nginx +#Operation Nginx handleNginx() { - if [[ -z $(pgrep -f "nginx") ]] && [[ "$1" == "start" ]]; then - systemctl start nginx 2>/etc/v2ray-agent/nginx_error.log + if [[ -z $(pgrep -f "nginx") ]] && [[ "$1" == "start" ]]; then + systemctl start nginx 2>/etc/v2ray-agent/nginx_error.log - sleep 0.5 + sleep 0.5 - 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 [[ -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 + # exit 0 + else + echoContent green " ---> Nginx started successfully" + fi - 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 + 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 } # Scheduled task to update tls certificate installCronTLS() { - echoContent skyBlue "\nProgress $1/${totalProgress} : Add scheduled maintenance certificate" - crontab -l >/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 the timing maintenance certificate successfully" + if [[ -z "${btDomain}" ]]; then + echoContent skyBlue "\nProgress$1/${totalProgress}: Add scheduled maintenance certificate" + crontab -l >/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 ---> Add scheduled maintenance certificate successfully" + fi +} +# Scheduled tasks update geo files +installCronUpdateGeo() { + if [[ -n "${configPath}" ]]; then + if crontab -l | grep -q "UpdateGeo"; then + echoContent red "\n ---> The automatic update scheduled task has been added, please do not add it repeatedly" + exit 0 + fi + echoContent skyBlue "\nProgress 1/1: Add regularly updated geo files" + crontab -l >/etc/v2ray-agent/backup_crontab.cron + echo "35 1 * * * /bin/bash /etc/v2ray-agent/install.sh UpdateGeo >> /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 scheduled update geo file successfully" + fi } -# update certificate +# Update certificate renewalTLS() { - 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 [[ -n $1 ]]; then + echoContent skyBlue "\nProgress$1/1: Update 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 [[ -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 + if [[ "${installDNSACMEStatus}" == "true" ]]; then + modifyTime=$(stat --format=%z "$HOME/.acme.sh/*.${dnsTLSDomain}_ecc/*.${dnsTLSDomain}.cer") + else + modifyTime=$(stat --format=%z "$HOME/.acme.sh/${domain}_ecc/${domain}.cer") + fi - modifyTime=$(date +%s -d "${modifyTime}") - currentTime=$(date +%s) - ((stampDiff = currentTime - modifyTime)) - ((days = stampDiff / 86400)) - ((remainingDays = sslRenewalDays - days)) + 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 + tlsStatus=${remainingDays} + if [[ ${remainingDays} -le 0 ]]; then + tlsStatus="Expired" + fi - 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 " ---> The certificate will be automatically updated on the last day before the certificate expires.If the update fails, please update it manually" + 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 " ---> Number of days remaining on the certificate: "${tlsStatus} + echoContent skyBlue " ---> The certificate will be automatically updated on the last day before it expires. If the update fails, please update manually" - if [[ ${remainingDays} -le 1 ]]; then - 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 "${domain}" --fullchainpath /etc/v2ray-agent/tls/"${domain}.crt" --keypath /etc/v2ray-agent/tls/"${domain}.key" --ecc - reloadCore - handleNginx start - else - echoContent green " ---> Certificate valid" - fi - else - echoContent red "---> not installed" - fi + if [[ ${remainingDays} -le 1 ]]; then + echoContent yellow " ---> Regenerate certificate" + handleNginx stop + + if [[ "${coreInstallType}" == "1" ]]; then + handleXray stop + elif [[ "${coreInstallType}" == "2" ]]; then + handleV2Ray stop + fi + + sudo "$HOME/.acme.sh/acme.sh" --cron --home "$HOME/.acme.sh" + 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 " ---> The certificate is valid" + fi + else + echoContent red " ---> not installed" + fi } -# View the status of the TLS certificate +# Check the status of TLS certificate checkTLStatus() { - 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 [[ -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}') - modifyTime=$(date +%s -d "${modifyTime}") - currentTime=$(date +%s) - ((stampDiff = currentTime - modifyTime)) - ((days = stampDiff / 86400)) - ((remainingDays = sslRenewalDays - days)) + 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 + 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 + echoContent skyBlue " ---> Certificate generation date: $(date -d "@${modifyTime}" +"%F %H:%M:%S")" + echoContent skyBlue " ---> Certificate generation days: ${days}" + echoContent skyBlue " ---> Number of days remaining on the certificate:${tlsStatus}" + fi } -# Install V2Ray, specify the version +#Install V2Ray, specified version installV2Ray() { - readInstallType - echoContent skyBlue "\nProgress $1/${totalProgress} : Install V2Ray" + readInstallType + echoContent skyBlue "\nProgress$1/${totalProgress}: Install V2Ray" - if [[ "${coreInstallType}" != "2" && "${coreInstallType}" != "3" ]]; then - if [[ "${selectCoreType}" == "2" ]]; then + if [[ "${coreInstallType}" != "2" && "${coreInstallType}" != "3" ]]; then + if [[ "${selectCoreType}" == "2" ]]; then - 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 + version=$(curl -s https://api.github.com/repos/v2fly/v2ray-core/releases?per_page=10 | jq -r '.[]|select (.prerelease==false)|.tag_name' | grep -v 'v5' | head -1) + else + version=${v2rayCoreVersion} + fi - 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 + echoContent green " ---> v2ray-core version:${version}" + # if wget --help | grep -q show-progress; then + wget -c -q "${wgetShowProgressStatus}" -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" - else - if [[ "${selectCoreType}" == "3" ]]; then - 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 "Update, upgrade? [y/n]:" reInstallV2RayStatus - if [[ "${reInstallV2RayStatus}" == "y" ]]; then - rm -f /etc/v2ray-agent/v2ray/v2ray - rm -f /etc/v2ray-agent/v2ray/v2ctl - installV2Ray "$1" - fi - fi - fi + 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 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 "Update or upgrade? [y/n]:" reInstallV2RayStatus + if [[ "${reInstallV2RayStatus}" == "y" ]]; then + rm -f /etc/v2ray-agent/v2ray/v2ray + rm -f /etc/v2ray-agent/v2ray/v2ctl + installV2Ray "$1" + fi + fi + fi } -# install hysteria +# Install hysteria installHysteria() { - readInstallType - echoContent skyBlue "\nProgress $1/${totalProgress} : Install Hysteria" + readInstallType + echoContent skyBlue "\nProgress$1/${totalProgress}: Installing Hysteria" - if [[ -z "${hysteriaConfigPath}" ]]; then + if [[ -z "${hysteriaConfigPath}" ]]; then - version=$(curl -s https://api.github.com/repos/apernet/hysteria/hysteria/releases | jq -r '.[]|select (.prerelease==false)|.tag_name' | head -1) + version=$(curl -s "https://api.github.com/repos/apernet/hysteria/releases?per_page=10" | jq -r ".[]|select (.prerelease==${prereleaseStatus})|.tag_name" | grep -v "app/v2" | head -1) - echoContent green " ---> Hysteria version: ${version}" - if wget --help | grep -q show-progress; then - wget -c -q --show-progress -P /etc/v2ray-agent/hysteria/ "https://github.com/apernet/hysteria/hysteria/releases/download/${version}/${hysteriaCoreCPUVendor}" - else - wget -c -P /etc/v2ray-agent/hysteria/ "https://github.com/apernet/hysteria/hysteria/releases/download/${version}/${hysteriaCoreCPUVendor}" >/dev/null 2>&1 - fi - mv "/etc/v2ray-agent/hysteria/${hysteriaCoreCPUVendor}" /etc/v2ray-agent/hysteria/hysteria - chmod 655 /etc/v2ray-agent/hysteria/hysteria - else - 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 + echoContent green " ---> Hysteria version:${version}" + wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/hysteria/ "https://github.com/apernet/hysteria/releases/download/${version}/${hysteriaCoreCPUVendor}" + mv "/etc/v2ray-agent/hysteria/${hysteriaCoreCPUVendor}" /etc/v2ray-agent/hysteria/hysteria + chmod 655 /etc/v2ray-agent/hysteria/hysteria + else + echoContent green " ---> Hysteria version:$(/etc/v2ray-agent/hysteria/hysteria --version | awk '{print $3}')" + read -r -p "Would you like to update or upgrade? [y/n]:" reInstallHysteriaStatus + if [[ "${reInstallHysteriaStatus}" == "y" ]]; then + rm -f /etc/v2ray-agent/hysteria/hysteria + installHysteria "$1" + fi + fi } -# install xray + +# Install tuic +installTuic() { + readInstallType + echoContent skyBlue "\nProgress$1/${totalProgress}: Install Tuic" + + if [[ -z "${tuicConfigPath}" ]]; then + + version=$(curl -s "https://api.github.com/repos/EAimTY/tuic/releases?per_page=1" | jq -r '.[]|select (.prerelease==false)|.tag_name') + + echoContent green " ---> Tuic version:${version}" + wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/tuic/ "https://github.com/EAimTY/tuic/releases/download/${version}/${version}${tuicCoreCPUVendor}" + mv "/etc/v2ray-agent/tuic/${version}${tuicCoreCPUVendor}" /etc/v2ray-agent/tuic/tuic + chmod 655 /etc/v2ray-agent/tuic/tuic + else + echoContent green " ---> Tuic version:$(/etc/v2ray-agent/tuic/tuic -v)" + read -r -p "Would you like to update or upgrade? [y/n]:" reInstallTuicStatus + if [[ "${reInstallTuicStatus}" == "y" ]]; then + rm -f /etc/v2ray-agent/tuic/tuic + tuicConfigPath= + installTuic "$1" + fi + fi + +} +# Check wget showProgress +checkWgetShowProgress() { + if find /usr/bin /usr/sbin | grep -q -w wget && wget --help | grep -q show-progress; then + wgetShowProgressStatus="--show-progress" + fi +} +# Install xray installXray() { - readInstallType - echoContent skyBlue "\nProgress $1/${totalProgress} : Install Xray" + readInstallType + local prereleaseStatus=false + if [[ "$2" == "true" ]]; then + prereleaseStatus=true + fi - if [[ "${coreInstallType}" != "1" ]]; then + echoContent skyBlue "\nProgress$1/${totalProgress}: Install Xray" - version=$(curl -s https://api.github.com/repos/XTLS/Xray-core/releases | jq -r '.[]|select (.prerelease==false)|.tag_name' | head -1) + if [[ "${coreInstallType}" != "1" ]]; then - 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" - else - wget -c -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip" >/dev/null 2>&1 - fi + version=$(curl -s "https://api.github.com/repos/XTLS/Xray-core/releases?per_page=1" | jq -r ".[].tag_name") - 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 + echoContent green " ---> Xray-core version:${version}" + + wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip" + if [[ ! -f "/etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip" ]]; then + echoContent red " ---> Core download failed, please try installation again" + exit 0 + fi + + unzip -o "/etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip" -d /etc/v2ray-agent/xray >/dev/null + rm -rf "/etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip" + + version=$(curl -s https://api.github.com/repos/Loyalsoldier/v2ray-rules-dat/releases?per_page=1 | jq -r '.[]|.tag_name') + echoContent skyBlue "------------------------Version-------------------------------" + echo "version:${version}" + rm /etc/v2ray-agent/xray/geo* >/dev/null 2>&1 + + wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/xray/ "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/${version}/geosite.dat" + wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/xray/ "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/${version}/geoip.dat" + + 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 "Would you like to update or upgrade? [y/n]:" reInstallXrayStatus + if [[ "${reInstallXrayStatus}" == "y" ]]; then + rm -f /etc/v2ray-agent/xray/xray + installXray "$1" "$2" + fi + fi } # v2ray version management v2rayVersionManageMenu() { - echoContent skyBlue "\nProgress $1/${totalProgress} : V2Ray version management" - if [[ ! -d "/etc/v2ray-agent/v2ray/" ]]; then - 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 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 red "==============================================================" - read -r -p "Please select:" selectV2RayType - if [[ "${selectV2RayType}" == "1" ]]; then - updateV2Ray - elif [[ "${selectV2RayType}" == "2" ]]; 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/v2fly/v2ray-core/releases | jq -r '.[]|select (.prerelease==false)|.tag_name' | grep -v 'v5' | head -5 | awk '{print ""NR""":"$0}' + echoContent skyBlue "\nProgress$1/${totalProgress}: V2Ray version management" + if [[ ! -d "/etc/v2ray-agent/v2ray/" ]]; then + echoContent red " ---> The installation directory is not detected, please execute the script to install the content" + menu + exit 0 + fi + echoContent red "\n================================================ =================" + 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 "6.Update geosite, geoip" + echoContent yellow "7.Set up automatic update of geo files [updated every morning]" + echoContent red "================================================== ===============" + read -r -p "Please select:" selectV2RayType + if [[ "${selectV2RayType}" == "1" ]]; then + updateV2Ray + elif [[ "${selectV2RayType}" == "2" ]]; then + echoContent yellow "\n1.Only the last five versions can be rolled back" + echoContent yellow "2.There is no guarantee that it will be able to be used normally after the rollback" + echoContent yellow "3.If the rolled-back version does not support the current config, it will be unable to connect, so operate with caution" + echoContent skyBlue "------------------------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}' - echoContent skyBlue "--------------------------------------------------------------" - 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}" - else - echoContent red "\n ---> Input error, please re-enter" - v2rayVersionManageMenu 1 - fi - elif [[ "${selectV2RayType}" == "3" ]]; then - handleV2Ray stop - elif [[ "${selectV2RayType}" == "4" ]]; then - handleV2Ray start - elif [[ "${selectV2RayType}" == "5" ]]; then - reloadCore - fi + echoContent skyBlue "------------------------------------------------- ---------------" + 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}" + else + echoContent red "\n ---> Incorrect input, please re-enter" + v2rayVersionManageMenu 1 + fi + elif [[ "${selectV2RayType}" == "3" ]]; then + handleV2Ray stop + elif [[ "${selectV2RayType}" == "4" ]]; then + handleV2Ray start + elif [[ "${selectV2RayType}" == "5" ]]; then + reloadCore + elif [[ "${selectXrayType}" == "6" ]]; then + updateGeoSite + elif [[ "${selectXrayType}" == "7" ]]; then + installCronUpdateGeo + fi } # xray version management xrayVersionManageMenu() { - echoContent skyBlue "\nProgress $1/${totalProgress} : Xray Version Management" - if [[ ! -d "/etc/v2ray-agent/xray/" ]]; then - 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 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 select:" selectXrayType - if [[ "${selectXrayType}" == "1" ]]; then - updateXray - elif [[ "${selectXrayType}" == "2" ]]; then + echoContent skyBlue "\nProgress$1/${totalProgress}: Xray version management" + if [[ ! -d "/etc/v2ray-agent/xray/" ]]; then + echoContent red " ---> The installation directory is not detected, please execute the script to install the content" + menu + exit 0 + fi + echoContent red "\n================================================ =================" + 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 yellow "7.Update geosite, geoip" + echoContent yellow "8.Set up automatic update of geo files [updated every morning]" + echoContent red "================================================== ===============" + read -r -p "Please select:" selectXrayType + if [[ "${selectXrayType}" == "1" ]]; then + updateXray + elif [[ "${selectXrayType}" == "2" ]]; then - prereleaseStatus=true - updateXray + 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 '.[]|select (.prerelease==false)|.tag_name' | head -5 | awk '{print ""NR""":"$0}' - echoContent skyBlue "--------------------------------------------------------------" - 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 ---> Input error, please re-enter" - xrayVersionManageMenu 1 - fi - elif [[ "${selectXrayType}" == "4" ]]; then - handleXray stop - elif [[ "${selectXrayType}" == "5" ]]; then - handleXray start - elif [[ "${selectXrayType}" == "6" ]]; then - reloadCore - fi + elif [[ "${selectXrayType}" == "3" ]]; then + echoContent yellow "\n1.Only the last five versions can be rolled back" + echoContent yellow "2.There is no guarantee that it will be able to be used normally after the rollback" + echoContent yellow "3.If the rolled-back version does not support the current config, it will be unable to connect, so operate with caution" + echoContent skyBlue "------------------------Version-------------------------------" + curl -s "https://api.github.com/repos/XTLS/Xray-core/releases?per_page=5" | jq -r ".[]|select (.prerelease==false)|.tag_name" | awk '{print ""NR""":"$0}' + echoContent skyBlue "------------------------------------------------- ---------------" + read -r -p "Please enter the version you want to roll back:" selectXrayVersionType + version=$(curl -s "https://api.github.com/repos/XTLS/Xray-core/releases?per_page=5" | jq -r ".[]|select (.prerelease==false)|.tag_name" | awk '{print ""NR""":"$0}' | grep "${selectXrayVersionType}:" | awk -F "[:]" '{print $2}') + if [[ -n "${version}" ]]; then + updateXray "${version}" + else + echoContent red "\n ---> Incorrect input, please re-enter" + xrayVersionManageMenu 1 + fi + elif [[ "${selectXrayType}" == "4" ]]; then + handleXray stop + elif [[ "${selectXrayType}" == "5" ]]; then + handleXray start + elif [[ "${selectXrayType}" == "6" ]]; then + reloadCore + elif [[ "${selectXrayType}" == "7" ]]; then + updateGeoSite + elif [[ "${selectXrayType}" == "8" ]]; then + installCronUpdateGeo + fi +} + +# Update geosite +updateGeoSite() { + echoContent yellow "\nSource https://github.com/Loyalsoldier/v2ray-rules-dat" + + version=$(curl -s https://api.github.com/repos/Loyalsoldier/v2ray-rules-dat/releases?per_page=1 | jq -r '.[]|.tag_name') + echoContent skyBlue "------------------------Version-------------------------------" + echo "version:${version}" + rm ${configPath}../geo* >/dev/null + wget -c -q "${wgetShowProgressStatus}" -P ${configPath}../ "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/${version}/geosite.dat" + wget -c -q "${wgetShowProgressStatus}" -P ${configPath}../ "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/${version}/geoip.dat" + reloadCore + echoContent green " ---> Update completed" } # Update V2Ray updateV2Ray() { - readInstallType - if [[ -z "${coreInstallType}" ]]; then + readInstallType + if [[ -z "${coreInstallType}" ]]; then - if [[ -n "$1" ]]; then - version=$1 - else - 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 locked version - if [[ -n "${v2rayCoreVersion}" ]]; then - version=${v2rayCoreVersion} - fi - echoContent green " ---> v2ray-core version: ${version}" + if [[ -n "$1" ]]; then + version=$1 + else + 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 locked version + if [[ -n "${v2rayCoreVersion}" ]]; then + version=${v2rayCoreVersion} + fi + echoContent green " ---> v2ray-core version:${version}" + # if wget --help | grep -q show-progress; then + wget -c -q "${wgetShowProgressStatus}" -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 - 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" + handleV2Ray stop + handleV2Ray start + else + echoContent green " ---> Current v2ray-core version: $(/etc/v2ray-agent/v2ray/v2ray --version | awk '{print $2}' | head -1)" - 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)" + if [[ -n "$1" ]]; then + version=$1 + else + 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 "$1" ]]; then - version=$1 - else - 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 "The rollback version is ${version}, do you want to continue? [y/n]:" rollbackV2RayStatus + if [[ "${rollbackV2RayStatus}" == "y" ]]; then + if [[ "${coreInstallType}" == "2" ]]; then + 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)" + fi - if [[ -n "${v2rayCoreVersion}" ]]; then - version=${v2rayCoreVersion} - fi - if [[ -n "$1" ]]; then - 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)" - elif [[ "${coreInstallType}" == "1" ]]; then - echoContent green " ---> Current Xray-core version: $(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)" - fi + handleV2Ray stop + rm -f /etc/v2ray-agent/v2ray/v2ray + rm -f /etc/v2ray-agent/v2ray/v2ctl + updateV2Ray "${version}" + else + echoContent green " ---> Abandon the rollback 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. 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 " ---> Give up and reinstall" + fi + else + read -r -p "The latest version is: ${version}, do you want to 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 " ---> Abort update" + fi - handleV2Ray stop - rm -f /etc/v2ray-agent/v2ray/v2ray - rm -f /etc/v2ray-agent/v2ray/v2ctl - updateV2Ray "${version}" - else - 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, 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 " ---> Abort reinstallation" - fi - else - 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 " ---> Abort update" - fi - - fi - fi + fi + fi } # 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 ".[]|select (.prerelease==${prereleaseStatus})|.tag_name" | head -1) - fi + readInstallType + if [[ -z "${coreInstallType}" ]]; then + if [[ -n "$1" ]]; then + version=$1 + else + version=$(curl -s "https://api.github.com/repos/XTLS/Xray-core/releases?per_page=1" | jq -r ".[]|select (.prerelease==${prereleaseStatus})|.tag_name") + 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" - else - wget -c -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip" >/dev/null 2>&1 - fi + wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${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)" + 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)" - if [[ -n "$1" ]]; then - version=$1 - else - 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 + version=$1 + else + version=$(curl -s "https://api.github.com/repos/XTLS/Xray-core/releases?per_page=1" | jq -r ".[].tag_name") + fi - if [[ -n "$1" ]]; then - 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)" + if [[ -n "$1" ]]; then + 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)" - handleXray stop - rm -f /etc/v2ray-agent/xray/xray - updateXray "${version}" - else - 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, 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 " ---> Abort reinstallation" - fi - else - 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 " ---> Abort update" - fi + handleXray stop + rm -f /etc/v2ray-agent/xray/xray + updateXray "${version}" + else + echoContent green " ---> Abandon the rollback 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. 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 " ---> Give up and reinstall" + fi + else + read -r -p "The latest version is: ${version}, is it updated? [y/n]:" installXrayStatus + if [[ "${installXrayStatus}" == "y" ]]; then + rm -f /etc/v2ray-agent/xray/xray + updateXray + else + echoContent green " ---> Abort update" + fi - fi - fi + fi + fi } # Verify that the entire service is available checkGFWStatue() { - readInstallType - echoContent skyBlue "\nProgress $1/${totalProgress} : Verify service startup status" - if [[ "${coreInstallType}" == "1" ]] && [[ -n $(pgrep -f xray/xray) ]]; then - echoContent green " ---> Service started successfully" - elif [[ "${coreInstallType}" == "2" || "${coreInstallType}" == "3" ]] && [[ -n $(pgrep -f v2ray/v2ray) ]]; then - echoContent green " ---> Service started successfully" - else - echoContent red " ---> The service failed to start, please check whether the terminal has log printing" - exit 0 - fi + readInstallType + echoContent skyBlue "\nProgress$1/${totalProgress}: Verify service startup status" + if [[ "${coreInstallType}" == "1" ]] && [[ -n $(pgrep -f "xray/xray") ]]; then + echoContent green " ---> Service started successfully" + elif [[ "${coreInstallType}" == "2" ]] && [[ -n $(pgrep -f "v2ray/v2ray") ]]; then + echoContent green " ---> Service started successfully" + else + echoContent red " ---> Service startup failed, please check if there are logs printed in the terminal" + exit 0 + fi } -# V2Ray starts automatically +# V2Ray starts automatically after booting installV2RayService() { - 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 - execStart='/etc/v2ray-agent/v2ray/v2ray -confdir /etc/v2ray-agent/v2ray/conf' - cat </etc/systemd/system/v2ray.service + echoContent skyBlue "\nProgress$1/${totalProgress}: Configure V2Ray to start automatically at boot" + if [[ -n $(find /bin /usr/bin -name "systemctl") ]]; then + rm -rf /etc/systemd/system/v2ray.service + touch /etc/systemd/system/v2ray.service + execStart='/etc/v2ray-agent/v2ray/v2ray -confdir /etc/v2ray-agent/v2ray/conf' + cat </etc/systemd/system/v2ray.service [Unit] Description=V2Ray - A unified platform for anti-censorship Documentation=https://v2ray.com https://guide.v2fly.org @@ -1956,293 +2292,426 @@ LimitNOFILE=1000000 [Install] WantedBy=multi-user.target EOF - systemctl daemon-reload - systemctl enable v2ray.service - echoContent green " ---> Configure V2Ray to start automatically after booting successfully" - fi + systemctl daemon-reload + systemctl enable v2ray.service + echoContent green " ---> Configure V2Ray to start automatically at boot" + fi } -# Install hysteria to start automatically +# Install hysteria to start automatically at boot 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/apernet/hysteria/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 "\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 + echoContent skyBlue "\nProgress$1/${totalProgress}: Configure Hysteria to start automatically at boot" + 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=Xray Service -Documentation=https://github.com/XTLS/Xray-core +Description=Hysteria Service +Documentation=https://github.com/apernet 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 xray.service - echoContent green " ---> Configure Xray to boot successfully" - fi + systemctl daemon-reload + systemctl enable hysteria.service + echoContent green " ---> Configure Hysteria to start automatically at boot" + fi +} +# Install Tuic to start automatically at boot +installTuicService() { + echoContent skyBlue "\nProgress$1/${totalProgress}: Configure Tuic to start automatically at boot" + if [[ -n $(find /bin /usr/bin -name "systemctl") ]]; then + rm -rf /etc/systemd/system/tuic.service + touch /etc/systemd/system/tuic.service + execStart='/etc/v2ray-agent/tuic/tuic -c /etc/v2ray-agent/tuic/conf/config.json' + cat </etc/systemd/system/tuic.service +[Unit] +Description=Tuic Service +Documentation=https://github.com/EAimTY +After=network.target nss-lookup.target +[Service] +User=root +ExecStart=${execStart} +Restart=on-failure +RestartPreventExitStatus=23 +LimitNPROC=10000 +LimitNOFILE=1000000 +[Install] +WantedBy=multi-user.target +EOF + systemctl daemon-reload + systemctl enable tuic.service + echoContent green " ---> Configuring Tuic to start automatically at boot" + fi +} +# Xray starts automatically after booting +installXrayService() { + echoContent skyBlue "\nProgress$1/${totalProgress}: Configure Xray to start automatically at boot" + 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 Service +Documentation=https://github.com/xtls +After=network.target nss-lookup.target +[Service] +User=root +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 " ---> Configure Xray to start automatically at boot" + fi } -# Operate V2Ray +#Operation V2Ray handleV2Ray() { - # shellcheck disable=SC2010 - if find /bin /usr/bin | grep -q systemctl && ls /etc/systemd/system/ | grep -q v2ray.service; then - if [[ -z $(pgrep -f "v2ray/v2ray") ]] && [[ "$1" == "start" ]]; then - systemctl start v2ray.service - elif [[ -n $(pgrep -f "v2ray/v2ray") ]] && [[ "$1" == "stop" ]]; then - systemctl stop v2ray.service - fi - fi - sleep 0.8 + # shellcheck disable=SC2010 + if find /bin /usr/bin | grep -q systemctl && ls /etc/systemd/system/ | grep -q v2ray.service; then + if [[ -z $(pgrep -f "v2ray/v2ray") ]] && [[ "$1" == "start" ]]; then + systemctl start v2ray.service + elif [[ -n $(pgrep -f "v2ray/v2ray") ]] && [[ "$1" == "stop" ]]; then + systemctl stop v2ray.service + fi + fi + sleep 0.8 - if [[ "$1" == "start" ]]; then - if [[ -n $(pgrep -f "v2ray/v2ray") ]]; then - echoContent green " ---> V2Ray started successfully" - else - 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 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 + if [[ "$1" == "start" ]]; then + if [[ -n $(pgrep -f "v2ray/v2ray") ]]; then + echoContent green " ---> V2Ray started successfully" + else + echoContent red "V2Ray failed to start" + echoContent red "Please manually execute [/etc/v2ray-agent/v2ray/v2ray -confdir /etc/v2ray-agent/v2ray/conf] and check the error log" + exit 0 + fi + elif [[ "$1" == "stop" ]]; then + if [[ -z $(pgrep -f "v2ray/v2ray") ]]; then + echoContent green " ---> V2Ray closed successfully" + else + echoContent red "V2Ray failed to close" + echoContent red "Please execute manually [ps -ef|grep -v grep|grep v2ray|awk '{print \$2}'|xargs kill -9]" + exit 0 + fi + fi } -# Operate Hysteria +# Operation 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 + # 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 "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 + if [[ "$1" == "start" ]]; then + if [[ -n $(pgrep -f "hysteria/hysteria") ]]; then + echoContent green " ---> Hysteria started successfully" + else + echoContent red "Hysteria startup failed" + 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 "Hysteria shutdown failed" + echoContent red "Please execute manually [ps -ef|grep -v grep|grep hysteria|awk '{print \$2}'|xargs kill -9]" + exit 0 + fi + fi +} +# Operate Tuic +handleTuic() { + # shellcheck disable=SC2010 + if find /bin /usr/bin | grep -q systemctl && ls /etc/systemd/system/ | grep -q tuic.service; then + if [[ -z $(pgrep -f "tuic/tuic") ]] && [[ "$1" == "start" ]]; then + systemctl start tuic.service + elif [[ -n $(pgrep -f "tuic/tuic") ]] && [[ "$1" == "stop" ]]; then + systemctl stop tuic.service + fi + fi + sleep 0.8 + + if [[ "$1" == "start" ]]; then + if [[ -n $(pgrep -f "tuic/tuic") ]]; then + echoContent green " ---> Tuic started successfully" + else + echoContent red "Tuic startup failed" + echoContent red "Please manually execute [/etc/v2ray-agent/tuic/tuic -c /etc/v2ray-agent/tuic/conf/config.json] and check the error log" + exit 0 + fi + elif [[ "$1" == "stop" ]]; then + if [[ -z $(pgrep -f "tuic/tuic") ]]; then + echoContent green " ---> Tuic closed successfully" + else + echoContent red "Tuic failed to close" + echoContent red "Please execute manually [ps -ef|grep -v grep|grep tuic|awk '{print \$2}'|xargs kill -9]" + exit 0 + fi + fi } # Manipulate xray handleXray() { - 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 - systemctl stop xray.service - fi - fi + 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 + systemctl stop xray.service + fi + fi - sleep 0.8 + sleep 0.8 - if [[ "$1" == "start" ]]; then - if [[ -n $(pgrep -f "xray/xray") ]]; then - echoContent green "---> Xray started successfully" - else - 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 closed successfully" - else - 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 + if [[ "$1" == "start" ]]; then + if [[ -n $(pgrep -f "xray/xray") ]]; then + echoContent green " ---> Xray started successfully" + else + echoContent red "Xray startup failed" + echoContent red "Please manually execute the following command [/etc/v2ray-agent/xray/xray -confdir /etc/v2ray-agent/xray/conf] and feedback the error log" + exit 0 + fi + elif [[ "$1" == "stop" ]]; then + if [[ -z $(pgrep -f "xray/xray") ]]; then + echoContent green " ---> Xray closed successfully" + else + echoContent red "xray failed to close" + echoContent red "Please execute manually [ps -ef|grep -v grep|grep xray|awk '{print \$2}'|xargs kill -9]" + exit 0 + fi + fi +} + +# Read user data and initialize +initXrayClients() { + local type=$1 + local newUUID=$2 + local newEmail=$3 + if [[ -n "${newUUID}" ]]; then + local newUser= + newUser="{\"id\":\"${uuid}\",\"flow\":\"xtls-rprx-vision\",\"email\":\"${newEmail}-VLESS_TCP/ TLS_Vision\"}" + currentClients=$(echo "${currentClients}" | jq -r ". +=[${newUser}]") + fi + local users= + if [[ "${type}" == "9" ]]; then + users={} + else + users=[] + fi + + while read -r user; do + uuid=$(echo "${user}" | jq -r .id) + email=$(echo "${user}" | jq -r .email | awk -F "[-]" '{print $1}') + currentUser= + if echo "${type}" | grep -q "0"; then + currentUser="{\"id\":\"${uuid}\",\"flow\":\"xtls-rprx-vision\",\"email\":\"${email}-VLESS_TCP/TLS_Vision\"}" + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + + #VLESSWS + if echo "${type}" | grep -q "1"; then + currentUser="{\"id\":\"${uuid}\",\"email\":\"${email}-VLESS_WS\"}" + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + #trojan grpc + if echo "${type}" | grep -q "2"; then + currentUser="{\"password\":\"${uuid}\",\"email\":\"${email}-Trojan_gRPC\"}" + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + #VMessWS + if echo "${type}" | grep -q "3"; then + currentUser="{\"id\":\"${uuid}\",\"email\":\"${email}-VMess_WS\",\"alterId\": 0}" + + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + + #trojantcp + if echo "${type}" | grep -q "4"; then + currentUser="{\"password\":\"${uuid}\",\"email\":\"${email}-trojan_tcp\"}" + + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + + # vless grpc + if echo "${type}" | grep -q "5"; then + currentUser="{\"id\":\"${uuid}\",\"email\":\"${email}-vless_grpc\"}" + + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + + # hysteria + if echo "${type}" | grep -q "6"; then + users=$(echo "${users}" | jq -r ". +=[\"${uuid}\"]") + fi + + # vless reality vision + if echo "${type}" | grep -q "7"; then + currentUser="{\"id\":\"${uuid}\",\"email\":\"${email}-vless_reality_vision\",\"flow\":\"xtls-rprx-vision\"}" + + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + + # vless reality grpc + if echo "${type}" | grep -q "8"; then + currentUser="{\"id\":\"${uuid}\",\"email\":\"${email}-vless_reality_grpc\",\"flow\":\"\"}" + + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + # tuic + if echo "${type}" | grep -q "9"; then + users=$(echo "${users}" | jq -r ".\"${uuid}\"=\"${uuid}\"") + fi + + done < <(echo "${currentClients}" | jq -c '.[]') + echo "${users}" } -# Get clients configuration getClients() { - local path=$1 + local path=$1 - 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 + local addClientsStatus=$2 + previousClients= - fi + if [[ ${addClientsStatus} == "true" ]]; then + if [[ ! -f "${path}" ]]; then + echo + local protocol + protocol=$(echo "${path}" | awk -F "[_]" '{print $2 $3}') + echoContent yellow "The configuration file last installed for this protocol [${protocol}] was not read, and the first uuid of the configuration file was used" + else + previousClients=$(jq -r ".inbounds[0].settings.clients" "${path}") + fi + + fi } -# Add client configuration +#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 + + 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 + local path=$1 + local addClientsStatus=$2 - if [[ ${addClientsStatus} == "true" && -n "${previousClients}" ]]; then - local uuids= - uuids=$(echo "${previousClients}" | jq -r [.[].id]) + 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 - config=$(jq -r ".auth.config = ${uuids}" "${path}") - echo "${config}" | jq .>"${path}" - fi + if [[ "${frontingType}" == "02_trojan_TCP_inbounds" ]]; then + uuids=$(echo "${previousClients}" | jq -r [.[].password]) + fi + config=$(jq -r ".auth.config = ${uuids}" "${path}") + echo "${config}" | jq . >"${path}" + fi } -# Initialize the hysteria port +#Initialize 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 - hysteriaPort= - fi - fi + readHysteriaConfig + if [[ -n "${hysteriaPort}" ]]; then + read -r -p "Read the port from the last installation. Do you want to use the port from the last installation? [y/n]:" historyHysteriaPortStatus + if [[ "${historyHysteriaPortStatus}" == "y" ]]; then + echoContent yellow "\n ---> Port: ${hysteriaPort}" + else + 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}" + if [[ -z "${hysteriaPort}" ]]; then + echoContent yellow "Please enter the Hysteria port [enter random 10000-30000], cannot be repeated with other services" + read -r -p "Port:" hysteriaPort + if [[ -z "${hysteriaPort}" ]]; then + hysteriaPort=$((RANDOM % 20001 + 10000)) + fi + fi + if [[ -z ${hysteriaPort} ]]; then + echoContent red " ---> Port cannot be empty" + initHysteriaPort "$2" + elif ((hysteriaPort < 1 || hysteriaPort > 65535)); then + echoContent red " ---> The port is illegal" + initHysteriaPort "$2" + fi + allowPort "${hysteriaPort}" + allowPort "${hysteriaPort}" "udp" } -# Initialize the protocol of hysteria +# Initialize hysteria protocol 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" + echoContent skyBlue "\nPlease select the 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 average delay from local to server, please fill it 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 downstream speed (default: 100, unit: Mbps)" + read -r -p "Download speed:" hysteriaClientDownloadSpeed + if [[ -z "${hysteriaClientDownloadSpeed}" ]]; then + hysteriaClientDownloadSpeed=100 + echoContent yellow "\n --->Download 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 + 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 ---> Upload speed: ${hysteriaClientUploadSpeed}\n" + fi - cat </etc/v2ray-agent/hysteria/conf/client_network.json + cat </etc/v2ray-agent/hysteria/conf/client_network.json { "hysteriaLag":"${hysteriaLag}", "hysteriaClientUploadSpeed":"${hysteriaClientUploadSpeed}", @@ -2251,16 +2720,122 @@ initHysteriaNetwork() { EOF } -# Initialize Hysteria configuration + +# hy port jump +hysteriaPortHopping() { + if [[ -n "${portHoppingStart}" || -n "${portHoppingEnd}" ]]; then + echoContent red " ---> Already added, cannot be added repeatedly, can be deleted and re-added" + exit 0 + fi + + echoContent skyBlue "\nProgress 1/1: Port jump" + echoContent red "\n================================================ =================" + echoContent yellow "# Notes\n" + echoContent yellow "Only supports UDP" + echoContent yellow "The starting position of port jumping is 30000" + echoContent yellow "The end position of port jumping is 60000" + echoContent yellow "You can choose a segment in the range of 30000-60000" + echoContent yellow "Recommend about 1000" + + echoContent yellow "Please enter the port jumping range, for example [30000-31000]" + + read -r -p "Range:" hysteriaPortHoppingRange + if [[ -z "${hysteriaPortHoppingRange}" ]]; then + echoContent red " ---> Range cannot be empty" + hysteriaPort Hopping + elif echo "${hysteriaPortHoppingRange}" | grep -q "-"; then + + local portStart= + local portEnd= + portStart=$(echo "${hysteriaPortHoppingRange}" | awk -F '-' '{print $1}') + portEnd=$(echo "${hysteriaPortHoppingRange}" | awk -F '-' '{print $2}') + + if [[ -z "${portStart}" || -z "${portEnd}" ]]; then + echoContent red " ---> The range is illegal" + hysteriaPort Hopping + elif ((portStart < 30000 || portStart > 60000 || portEnd < 30000 || portEnd > 60000 || portEnd < portStart)); then + echoContent red " ---> The range is illegal" + hysteriaPort Hopping + else + echoContent green "\nPort range: ${hysteriaPortHoppingRange}\n" + # ip -4 addr show | awk '/inet /{print $NF ":" $2}' | awk '{print ""NR""":"$0}' + # read -r -p "Please select the corresponding network card:" selectInterface + # if ! ip -4 addr show | awk '/inet /{print $NF ":" $2}' | awk '{print ""NR""":"$0}' | grep -q "${selectInterface}: "; then + # echoContent red " ---> Wrong selection" + # hysteriaPortHopping + #else + iptables -t nat -A PREROUTING -p udp --dport "${portStart}:${portEnd}" -m comment --comment "mack-a_portHopping" -j DNAT --to-destination :${hysteriaPort} + + if iptables-save | grep -q "mack-a_portHopping"; then + allowPort "${portStart}:${portEnd}" udp + echoContent green " ---> Port hopping added successfully" + else + echoContent red " ---> Failed to add port hopping" + fi + # fi + fi + + fi +} + +# Read port hopping configuration +readHysteriaPortHopping() { + if [[ -n "${hysteriaPort}" ]]; then + # interfaceName=$(ip -4 addr show | awk '/inet /{print $NF ":" $2}' | awk '{print ""NR""":"$0}' | grep "${selectInterface}:" | awk -F "[:]" '{print $2}') + if iptables-save | grep -q "mack-a_portHopping"; then + portHopping= + portHopping=$(iptables-save | grep "mack-a_portHopping" | cut -d " " -f 8) + portHoppingStart=$(echo "${portHopping}" | cut -d ":" -f 1) + portHoppingEnd=$(echo "${portHopping}" | cut -d ":" -f 2) + fi + fi +} + +# Delete hysteria port treaty iptables rules +deleteHysteriaPortHoppingRules() { + iptables -t nat -L PREROUTING --line-numbers | grep "mack-a_portHopping" | awk '{print $1}' | while read -r line; do + iptables -t nat -D PREROUTING 1 + done +} + +hysteriaPortHoppingMenu() { + # Determine whether iptables exists + if ! find /usr/bin /usr/sbin | grep -q -w iptables; then + echoContent red " ---> Unable to recognize iptables tool, unable to use port jump, exit installation" + exit 0 + fi + readHysteriaConfig + readHysteriaPortHopping + echoContent skyBlue "\nProgress 1/1: Port jump" + echoContent red "\n================================================ =================" + echoContent yellow "1.Add port hopping" + echoContent yellow "2.Delete port hopping" + echoContent yellow "3.Check port jumping" + read -r -p "range:" selectPortHoppingStatus + if [[ "${selectPortHoppingStatus}" == "1" ]]; then + hysteriaPort Hopping + elif [[ "${selectPortHoppingStatus}" == "2" ]]; then + if [[ -n "${portHopping}" ]]; then + deleteHysteriaPortHoppingRules + echoContent green " ---> Deletion successful" + fi + elif [[ "${selectPortHoppingStatus}" == "3" ]]; then + echoContent green " ---> The current port hopping range is: ${portHoppingStart}-${portHoppingEnd}" + else + hysteriaPortHoppingMenu + fi +} +#Initialize Hysteria configuration initHysteriaConfig() { - echoContent skyBlue "\nProgress $1/${totalProgress} : Initialize Hysteria configuration" + echoContent skyBlue "\nProgress$1/${totalProgress}: Initializing Hysteria configuration" - initHysteriaPort - initHysteriaProtocol - initHysteriaNetwork - - getClients "${configPath}${frontingType}.json" true - cat </etc/v2ray-agent/hysteria/conf/config.json + initHysteriaPort + initHysteriaProtocol + initHysteriaNetwork + local uuid= + uuid=$(${ctlPath} uuid) + getClients "${configPath}${frontingType}.json" true + cat </etc/v2ray-agent/hysteria/conf/config.json { "listen": ":${hysteriaPort}", "protocol": "${hysteriaProtocol}", @@ -2271,6 +2846,11 @@ initHysteriaConfig() { "mode": "passwords", "config": [] }, + "socks5_outbound":{ + "server":"127.0.0.1:31295", + "user":"hysteria_socks5_outbound", + "password":"${uuid}" + }, "alpn": "h3", "recv_window_conn": 15728640, "recv_window_client": 67108864, @@ -2281,44 +2861,159 @@ initHysteriaConfig() { } EOF - addClientsHysteria "/etc/v2ray-agent/hysteria/conf/config.json" true + addClientsHysteria "/etc/v2ray-agent/hysteria/conf/config.json" true + + # Add socks inbound + cat <${configPath}/02_socks_inbounds_hysteria.json +{ + "inbounds": [ + { + "listen": "127.0.0.1", + "port": 31295, + "protocol": "Socks", + "tag": "socksHysteriaOutbound", + "settings": { + "auth": "password", + "accounts": [ + { + "user": "hysteria_socks5_outbound", + "pass": "${uuid}" + } + ], + "udp": true, + "ip": "127.0.0.1" + } + } + ] +} +EOF } -# Initialize V2Ray configuration file +#Initialize tuic port +initTuicPort() { + readTuicConfig + if [[ -n "${tuicPort}" ]]; then + read -r -p "Read the port from the last installation. Do you want to use the port from the last installation? [y/n]:" historyTuicPortStatus + if [[ "${historyTuicPortStatus}" == "y" ]]; then + echoContent yellow "\n ---> Port: ${tuicPort}" + else + tuicPort= + fi + fi + + if [[ -z "${tuicPort}" ]]; then + echoContent yellow "Please enter the Tuic port [enter random 10000-30000], cannot be repeated with other services" + read -r -p "Port:" tuicPort + if [[ -z "${tuicPort}" ]]; then + tuicPort=$((RANDOM % 20001 + 10000)) + fi + fi + if [[ -z ${tuicPort} ]]; then + echoContent red " ---> Port cannot be empty" + initTuicPort "$2" + elif ((tuicPort < 1 || tuicPort > 65535)); then + echoContent red " ---> The port is illegal" + initTuicPort "$2" + fi + echoContent green "\n ---> Port: ${tuicPort}" + allowPort "${tuicPort}" + allowPort "${tuicPort}" "udp" +} + +# Initialize tuic protocol +initTuicProtocol() { + echoContent skyBlue "\nPlease select the algorithm type" + echoContent red "================================================== ===============" + echoContent yellow "1.bbr(default)" + echoContent yellow "2.cubic" + echoContent yellow "3.new_reno" + echoContent red "================================================== =========== ====" + read -r -p "Please select:" selectTuicAlgorithm + case ${selectTuicAlgorithm} in + 1) + tuicAlgorithm="bbr" + ;; + 2) + tuicAlgorithm="cubic" + ;; + 3) + tuicAlgorithm="new_reno" + ;; + *) + tuicAlgorithm="bbr" + ;; + esac + echoContent yellow "\n ---> Algorithm: ${tuicAlgorithm}\n" +} + +# Initialize tuic configuration +initTuicConfig() { + echoContent skyBlue "\nProgress$1/${totalProgress}: Initializing Tuic configuration" + + initTuicPort + initTuicProtocol + cat </etc/v2ray-agent/tuic/conf/config.json +{ + "server": "[::]:${tuicPort}", + "users": $(initXrayClients 9), + "certificate": "/etc/v2ray-agent/tls/${currentHost}.crt", + "private_key": "/etc/v2ray-agent/tls/${currentHost}.key", + "congestion_control":"${tuicAlgorithm}", + "alpn": ["h3"], + "log_level": "warn" +} +EOF +} + +# Tuic installation +tuicCoreInstall() { + if ! echo "${currentInstallProtocolType}" | grep -q "0" || [[ -z "${coreInstallType}" ]]; then + echoContent red "\n ---> Due to environmental dependencies, if you install Tuic, please install Xray-core's VLESS_TCP_TLS_Vision first" + exit 0 + fi + totalProgress=5 + installTuic 1 + initTuicConfig 2 + installTuicService 3 + reloadCore + showAccounts 4 +} + +#Initialize V2Ray configuration file initV2RayConfig() { - echoContent skyBlue "\nProgress $2/${totalProgress} : Initialize V2Ray configuration" - echo + echoContent skyBlue "\nProgress$2/${totalProgress}: Initializing V2Ray configuration" + echo - read -r -p "Custom UUID? [y/n]:" customUUIDStatus - echo - if [[ "${customUUIDStatus}" == "y" ]]; then - 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 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 - elif [[ -z "${uuid}" ]]; then - uuid=$(/etc/v2ray-agent/v2ray/v2ctl uuid) - fi + read -r -p "Do you want to customize the UUID? [y/n]:" customUUIDStatus + echo + if [[ "${customUUIDStatus}" == "y" ]]; then + 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 the last installation record. Do you want to use the UUID from the last installation? [y/n]:" historyUUIDStatus + if [[ "${historyUUIDStatus}" == "y" ]]; then + uuid=${currentUUID} + addClientsStatus=true + else + uuid=$(/etc/v2ray-agent/v2ray/v2ctl uuid) + fi + elif [[ -z "${uuid}" ]]; then + uuid=$(/etc/v2ray-agent/v2ray/v2ctl uuid) + fi - if [[ -z "${uuid}" ]]; then - addClientsStatus= - echoContent red "\n ---> uuid read error, regenerate" - uuid=$(/etc/v2ray-agent/v2ray/v2ctl uuid) - fi + if [[ -z "${uuid}" ]]; then + addClientsStatus= + echoContent red "\n ---> uuid reading error, regenerate" + uuid=$(/etc/v2ray-agent/v2ray/v2ctl uuid) + fi - movePreviousConfig - # log - cat </etc/v2ray-agent/v2ray/conf/00_log.json + movePreviousConfig + # log + cat </etc/v2ray-agent/v2ray/conf/00_log.json { "log": { "error": "/etc/v2ray-agent/v2ray/error.log", @@ -2326,9 +3021,9 @@ initV2RayConfig() { } } EOF - # outbounds - if [[ -n "${pingIPv6}" ]]; then - cat </etc/v2ray-agent/v2ray/conf/10_ipv6_outbounds.json + # outbounds + if [[ -n "${pingIPv6}" ]]; then + cat </etc/v2ray-agent/v2ray/conf/10_ipv6_outbounds.json { "outbounds": [ { @@ -2340,8 +3035,8 @@ EOF } EOF - else - cat </etc/v2ray-agent/v2ray/conf/10_ipv4_outbounds.json + else + cat </etc/v2ray-agent/v2ray/conf/10_ipv4_outbounds.json { "outbounds":[ { @@ -2365,10 +3060,10 @@ EOF ] } EOF - fi + fi - # dns - cat </etc/v2ray-agent/v2ray/conf/11_dns.json + # dns + cat </etc/v2ray-agent/v2ray/conf/11_dns.json { "dns": { "servers": [ @@ -2378,17 +3073,17 @@ EOF } EOF - # VLESS_TCP_TLS - # fall back to nginx - local fallbacksList='{"dest":31300,"xver":0},{"alpn":"h2","dest":31302,"xver":0}' + # VLESS_TCP_TLS + # Fall back nginx + local fallbacksList='{"dest":31300,"xver":0},{"alpn":"h2","dest":31302,"xver":0}' - # trojan - if echo "${selectCustomInstallType}" | grep -q 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}' + fallbacksList='{"dest":31296,"xver":1},{"alpn":"h2","dest":31302,"xver":0}' - getClients "${configPath}../tmp/04_trojan_TCP_inbounds.json" "${addClientsStatus}" - 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":[ { @@ -2400,7 +3095,7 @@ EOF "clients": [ { "password": "${uuid}", - "email": "${domain}_${uuid}" + "email": "default_Trojan_TCP" } ], "fallbacks":[ @@ -2413,19 +3108,19 @@ EOF "tcpSettings": { "acceptProxyProtocol": true } - } + } } ] } EOF - addClients "/etc/v2ray-agent/v2ray/conf/04_trojan_TCP_inbounds.json" "${addClientsStatus}" - fi + 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 + # 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":[ { @@ -2437,7 +3132,7 @@ EOF "clients": [ { "id": "${uuid}", - "email": "${domain}_${uuid}" + "email": "default_VLESS_WS" } ], "decryption": "none" @@ -2454,16 +3149,16 @@ EOF ] } EOF - addClients "/etc/v2ray-agent/v2ray/conf/03_VLESS_WS_inbounds.json" "${addClientsStatus}" - fi + 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 + # 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": [ { @@ -2475,7 +3170,7 @@ EOF "clients": [ { "password": "${uuid}", - "email": "${domain}_${uuid}" + "email": "default_Trojan_gRPC" } ], "fallbacks": [ @@ -2494,16 +3189,16 @@ EOF ] } EOF - addClients "/etc/v2ray-agent/v2ray/conf/04_trojan_gRPC_inbounds.json" "${addClientsStatus}" - fi + 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}' + # 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}" + getClients "${configPath}../tmp/05_VMess_WS_inbounds.json" "${addClientsStatus}" - cat </etc/v2ray-agent/v2ray/conf/05_VMess_WS_inbounds.json + cat </etc/v2ray-agent/v2ray/conf/05_VMess_WS_inbounds.json { "inbounds":[ { @@ -2517,7 +3212,7 @@ EOF "id": "${uuid}", "alterId": 0, "add": "${add}", - "email": "${domain}_${uuid}" + "email": "default_VMess_WS" } ] }, @@ -2533,12 +3228,12 @@ EOF ] } EOF - addClients "/etc/v2ray-agent/v2ray/conf/05_VMess_WS_inbounds.json" "${addClientsStatus}" - fi + addClients "/etc/v2ray-agent/v2ray/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/v2ray/conf/06_VLESS_gRPC_inbounds.json + 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":[ { @@ -2551,7 +3246,7 @@ EOF { "id": "${uuid}", "add": "${add}", - "email": "${domain}_${uuid}" + "email": "default_VLESS_gRPC" } ], "decryption": "none" @@ -2566,17 +3261,17 @@ EOF ] } EOF - addClients "/etc/v2ray-agent/v2ray/conf/06_VLESS_gRPC_inbounds.json" "${addClientsStatus}" - fi + addClients "/etc/v2ray-agent/v2ray/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 + # 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/v2ray/conf/02_VLESS_TCP_inbounds.json + cat </etc/v2ray-agent/v2ray/conf/02_VLESS_TCP_inbounds.json { "inbounds":[ { @@ -2588,7 +3283,7 @@ EOF { "id": "${uuid}", "add":"${add}", - "email": "${domain}_VLESS_TLS-direct_TCP" + "email": "default_VLESS_TCP" } ], "decryption": "none", @@ -2619,119 +3314,130 @@ EOF ] } EOF - addClients "/etc/v2ray-agent/v2ray/conf/02_VLESS_TCP_inbounds.json" "${addClientsStatus}" + addClients "/etc/v2ray-agent/v2ray/conf/02_VLESS_TCP_inbounds.json" "${addClientsStatus}" } # Initialize Xray Trojan XTLS configuration file initXrayFrontingConfig() { - if [[ -z "${configPath}" ]]; then - echoContent red " ---> Not installed, please use script to install" - menu - exit 0 - fi - if [[ "${coreInstallType}" != "1" ]]; then - echoContent red " ---> Available types are not installed" - fi - local xtlsType= - if echo ${currentInstallProtocolType} | grep -q trojan; then - xtlsType=VLESS - else - xtlsType=Trojan + echoContent red " ---> Trojan does not currently support xtls-rprx-vision" + exit 0 + if [[ -z "${configPath}" ]]; then + echoContent red " ---> Not installed, please use script to install" + menu + exit 0 + fi + if [[ "${coreInstallType}" != "1" ]]; then + echoContent red " ---> Available types are not installed" + fi + local xtlsType= + if echo ${currentInstallProtocolType} | grep -q trojan; then + xtlsType=VLESS + else + xtlsType=Trojan - fi + fi - echoContent skyBlue "\nFunction 1/${totalProgress} : switch to ${xtlsType}" - echoContent red "\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 skyBlue "\nFunction 1/${totalProgress}: Switch to ${xtlsType}" + echoContent red "\n================================================ =================" + echoContent yellow "# Notes\n" + echoContent yellow "will replace the prefix with ${xtlsType}" + echoContent yellow "If the prefix is Trojan, two Trojan protocol nodes will appear when viewing the account, and one of them is unavailable xtls" + echoContent yellow "Execute again to switch to the last prefix\n" - echoContent yellow "1.Switch to ${xtlsType}" - echoContent red "==============================================================" - read -r -p "Please select:" selectType - if [[ "${selectType}" == "1" ]]; then + echoContent yellow "1.Switch to ${xtlsType}" + echoContent red "================================================== ===============" + read -r -p "Please select:" selectType + if [[ "${selectType}" == "1" ]]; then - if [[ "${xtlsType}" == "Trojan" ]]; then + if [[ "${xtlsType}" == "Trojan" ]]; then - 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"} + 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 - elif [[ "${xtlsType}" == "VLESS" ]]; then + echo "${VLESSConfig}" | jq . >${configPath}02_trojan_TCP_inbounds.json + rm ${configPath}${frontingType}.json + elif [[ "${xtlsType}" == "VLESS" ]]; then - 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"} + 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 - rm ${configPath}02_trojan_TCP_inbounds.json - fi - reloadCore - fi + 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 + if [[ -n "${configPath}" ]]; then + if [[ -z "${realityStatus}" ]]; then + rm -rf "${configPath}../tmp/*" 2>/dev/null + mv ${configPath}[0][2-6]* ${configPath}../tmp/ 2>/dev/null + else + rm -rf "${configPath}../tmp/*" + mv ${configPath}[0][7-8]* ${configPath}../tmp/ 2>/dev/null + mv ${configPath}[0][2]* ${configPath}../tmp/ 2>/dev/null + fi + + fi } -# Initialize Xray configuration file +#Initialize Xray configuration file initXrayConfig() { - echoContent skyBlue "\nProgress $2/${totalProgress} : Initialize Xray configuration" - echo - local uuid= - local addClientsStatus= - if [[ -n "${currentUUID}" ]]; then - 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 ---> Successfully used" - fi - fi + echoContent skyBlue "\nProgress$2/${totalProgress}: Initializing Xray configuration" + echo + local uuid= + local addClientsStatus= + if [[ -n "${currentUUID}" ]]; then + read -r -p "Read the last user configuration. Do you want to use the last installed configuration? [y/n]:" historyUUIDStatus + if [[ "${historyUUIDStatus}" == "y" ]]; then + addClientsStatus=true + echoContent green "\n ---> Used successfully" + fi + fi - if [[ -z "${uuid}" ]]; then - echoContent yellow "Please enter a custom UUID [must be legal], [enter] random UUID" - read -r -p 'UUID:' customUUID + if [[ -z "${addClientsStatus}" ]]; then + echoContent yellow "Please enter custom UUID [need to be legal], [Enter] random UUID" + read -r -p 'UUID:' customUUID - if [[ -n ${customUUID} ]]; then - uuid=${customUUID} - else - uuid=$(/etc/v2ray-agent/xray/xray uuid) - fi + if [[ -n ${customUUID} ]]; then + uuid=${customUUID} + else + uuid=$(/etc/v2ray-agent/xray/xray uuid) + fi - fi + fi - if [[ -z "${uuid}" ]]; then - addClientsStatus= - echoContent red "\n ---> uuid read error, regenerate" - uuid=$(/etc/v2ray-agent/xray/xray uuid) - fi + if [[ -z "${addClientsStatus}" && -z "${uuid}" ]]; then + addClientsStatus= + echoContent red "\n ---> uuid reading error, randomly generated" + uuid=$(/etc/v2ray-agent/xray/xray uuid) + fi - echoContent yellow "\n ${uuid}" + if [[ -n "${uuid}" ]]; then + currentClients='[{"id":"'${uuid}'","add":"'${add}'","flow":"xtls-rprx-vision","email":"'${uuid}'-VLESS_TCP/TLS_Vision"}]' + echoContent yellow "\n ${uuid}" + fi - movePreviousConfig + #log + if [[ ! -f "/etc/v2ray-agent/xray/conf/00_log.json" ]]; then - # log - cat </etc/v2ray-agent/xray/conf/00_log.json + cat </etc/v2ray-agent/xray/conf/00_log.json { "log": { "error": "/etc/v2ray-agent/xray/error.log", @@ -2739,10 +3445,28 @@ initXrayConfig() { } } EOF + fi - # outbounds - if [[ -n "${pingIPv6}" ]]; then - cat </etc/v2ray-agent/xray/conf/10_ipv6_outbounds.json + if [[ ! -f "/etc/v2ray-agent/xray/conf/12_policy.json" ]]; then + + cat </etc/v2ray-agent/xray/conf/12_policy.json +{ + "policy": { + "levels": { + "0": { + "handshake": $((1 + RANDOM % 4)), + "connIdle": $((250 + RANDOM % 51)) + } + } + } +} +EOF + fi + + # outbounds + if [[ ! -f "/etc/v2ray-agent/xray/conf/10_ipv6_outbounds.json" ]]; then + if [[ -n "${pingIPv6}" ]]; then + cat </etc/v2ray-agent/xray/conf/10_ipv6_outbounds.json { "outbounds": [ { @@ -2754,8 +3478,8 @@ EOF } EOF - else - cat </etc/v2ray-agent/xray/conf/10_ipv4_outbounds.json + else + cat </etc/v2ray-agent/xray/conf/10_ipv4_outbounds.json { "outbounds":[ { @@ -2772,6 +3496,11 @@ EOF }, "tag":"IPv6-out" }, + { + "protocol":"freedom", + "settings": {}, + "tag":"direct" + }, { "protocol":"blackhole", "tag":"blackhole-out" @@ -2779,10 +3508,12 @@ EOF ] } EOF - fi + fi + fi - # dns - cat </etc/v2ray-agent/xray/conf/11_dns.json + # dns + if [[ ! -f "/etc/v2ray-agent/xray/conf/11_dns.json" ]]; then + cat </etc/v2ray-agent/xray/conf/11_dns.json { "dns": { "servers": [ @@ -2791,17 +3522,34 @@ EOF } } EOF + fi + # routing + if [[ ! -f "/etc/v2ray-agent/xray/conf/09_routing.json" ]]; then + cat </etc/v2ray-agent/xray/conf/09_routing.json +{ + "routing": { + "rules": [ + { + "type": "field", + "domain": [ + "domain:gstatic.com", + "domain:googleapis.com" + ], + "outboundTag": "direct" + } + ] + } +} +EOF + fi + # VLESS_TCP_TLS_Vision + # Fall back nginx + local fallbacksList='{"dest":31300,"xver":0},{"alpn":"h2","dest":31302,"xver":0}' - # VLESS_TCP_TLS/XTLS - # fall back to nginx - local fallbacksList='{"dest":31300,"xver":0},{"alpn":"h2","dest":31302,"xver":0}' - - # trojan - 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 + # 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/xray/conf/04_trojan_TCP_inbounds.json { "inbounds":[ { @@ -2810,12 +3558,7 @@ EOF "protocol": "trojan", "tag":"trojanTCP", "settings": { - "clients": [ - { - "password": "${uuid}", - "email": "${domain}_${uuid}" - } - ], + "clients": $(initXrayClients 4), "fallbacks":[ {"dest":"31300"} ] @@ -2826,19 +3569,19 @@ EOF "tcpSettings": { "acceptProxyProtocol": true } - } + } } ] } EOF - addClients "/etc/v2ray-agent/xray/conf/04_trojan_TCP_inbounds.json" "${addClientsStatus}" - fi + else + rm /etc/v2ray-agent/xray/conf/04_trojan_TCP_inbounds.json >/dev/null 2>&1 + 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 + # VLESS_WS_TLS + if echo "${selectCustomInstallType}" | grep -q 1 || [[ "$1" == "all" ]]; then + fallbacksList=${fallbacksList}',{"path":"/'${customPath}'ws","dest":31297,"xver":1}' + cat </etc/v2ray-agent/xray/conf/03_VLESS_WS_inbounds.json { "inbounds":[ { @@ -2847,12 +3590,7 @@ EOF "protocol": "vless", "tag":"VLESSWS", "settings": { - "clients": [ - { - "id": "${uuid}", - "email": "${domain}_${uuid}" - } - ], + "clients": $(initXrayClients 1), "decryption": "none" }, "streamSettings": { @@ -2867,16 +3605,16 @@ EOF ] } EOF - addClients "/etc/v2ray-agent/xray/conf/03_VLESS_WS_inbounds.json" "${addClientsStatus}" - fi + else + rm /etc/v2ray-agent/xray/conf/03_VLESS_WS_inbounds.json >/dev/null 2>&1 + 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/xray/conf/04_trojan_gRPC_inbounds.json + # 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 + cat </etc/v2ray-agent/xray/conf/04_trojan_gRPC_inbounds.json { "inbounds": [ { @@ -2885,12 +3623,7 @@ EOF "protocol": "trojan", "tag": "trojangRPCTCP", "settings": { - "clients": [ - { - "password": "${uuid}", - "email": "${domain}_${uuid}" - } - ], + "clients": $(initXrayClients 2), "fallbacks": [ { "dest": "31300" @@ -2907,14 +3640,14 @@ EOF ] } EOF - addClients "/etc/v2ray-agent/xray/conf/04_trojan_gRPC_inbounds.json" "${addClientsStatus}" - fi + else + rm /etc/v2ray-agent/xray/conf/04_trojan_gRPC_inbounds.json >/dev/null 2>&1 + 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 + # VMess_WS + if echo "${selectCustomInstallType}" | grep -q 3 || [[ "$1" == "all" ]]; then + fallbacksList=${fallbacksList}',{"path":"/'${customPath}'vws","dest":31299,"xver":1}' + cat </etc/v2ray-agent/xray/conf/05_VMess_WS_inbounds.json { "inbounds":[ { @@ -2923,14 +3656,7 @@ EOF "protocol": "vmess", "tag":"VMessWS", "settings": { - "clients": [ - { - "id": "${uuid}", - "alterId": 0, - "add": "${add}", - "email": "${domain}_${uuid}" - } - ] + "clients": $(initXrayClients 3) }, "streamSettings": { "network": "ws", @@ -2944,12 +3670,12 @@ EOF ] } EOF - addClients "/etc/v2ray-agent/xray/conf/05_VMess_WS_inbounds.json" "${addClientsStatus}" - fi + else + rm /etc/v2ray-agent/xray/conf/05_VMess_WS_inbounds.json >/dev/null 2>&1 + 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 + if echo "${selectCustomInstallType}" | grep -q 5 || [[ "$1" == "all" ]]; then + cat </etc/v2ray-agent/xray/conf/06_VLESS_gRPC_inbounds.json { "inbounds":[ { @@ -2958,13 +3684,7 @@ EOF "protocol": "vless", "tag":"VLESSGRPC", "settings": { - "clients": [ - { - "id": "${uuid}", - "add": "${add}", - "email": "${domain}_${uuid}" - } - ], + "clients": $(initXrayClients 5), "decryption": "none" }, "streamSettings": { @@ -2977,615 +3697,961 @@ EOF ] } EOF - addClients "/etc/v2ray-agent/xray/conf/06_VLESS_gRPC_inbounds.json" "${addClientsStatus}" - fi + else + rm /etc/v2ray-agent/xray/conf/06_VLESS_gRPC_inbounds.json >/dev/null 2>&1 + fi + # VLESS Vision + if echo "${selectCustomInstallType}" | grep -q 0 || [[ "$1" == "all" ]]; then - # 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 + cat </etc/v2ray-agent/xray/conf/02_VLESS_TCP_inbounds.json { -"inbounds":[ -{ - "port": ${defaultPort}, - "protocol": "vless", - "tag":"VLESSTCP", - "settings": { - "clients": [ - { - "id": "${uuid}", - "add":"${add}", - "flow":"xtls-rprx-direct", - "email": "${domain}_${uuid}" - } - ], - "decryption": "none", - "fallbacks": [ - ${fallbacksList} - ] - }, - "streamSettings": { - "network": "tcp", - "security": "xtls", - "xtlsSettings": { - "minVersion": "1.2", - "alpn": [ - "http/1.1", - "h2" - ], - "certificates": [ + "inbounds":[ { - "certificateFile": "/etc/v2ray-agent/tls/${domain}.crt", - "keyFile": "/etc/v2ray-agent/tls/${domain}.key", - "ocspStapling": 3600, - "usage":"encipherment" + "port": ${port}, + "protocol": "vless", + "tag":"VLESSTCP", + "settings": { + "clients":$(initXrayClients 0), + "decryption": "none", + "fallbacks": [ + ${fallbacksList} + ] + }, + "add": "${add}", + "streamSettings": { + "network": "tcp", + "security": "tls", + "tlsSettings": { + "minVersion": "1.2", + "alpn": [ + "http/1.1", + "h2" + ], + "certificates": [ + { + "certificateFile": "/etc/v2ray-agent/tls/${domain}.crt", + "keyFile": "/etc/v2ray-agent/tls/${domain}.key", + "ocspStapling": 3600, + "usage":"encipherment" + } + ] + } + } } - ] - } - } -} -] + ] } EOF - addClients "/etc/v2ray-agent/xray/conf/02_VLESS_TCP_inbounds.json" "${addClientsStatus}" -} + else + rm /etc/v2ray-agent/xray/conf/02_VLESS_TCP_inbounds.json >/dev/null 2>&1 + fi -# Initialize Trojan-Go configuration -initTrojanGoConfig() { + # VLESS_TCP/reality + if echo "${selectCustomInstallType}" | grep -q 7 || [[ "$1" == "all" ]]; then + echoContent skyBlue "\n===================== Configure VLESS+Reality ==================== =\n" + initRealityPort + initRealityDest + initRealityClientServersName + initRealityKey - echoContent skyBlue "\nProgress $1/${totalProgress} : Initialize Trojan configuration" - cat </etc/v2ray-agent/trojan/config_full.json + cat </etc/v2ray-agent/xray/conf/07_VLESS_vision_reality_inbounds.json { - "run_type": "server", - "local_addr": "127.0.0.1", - "local_port": 31296, - "remote_addr": "127.0.0.1", - "remote_port": 31300, - "disable_http_check":true, - "log_level":3, - "log_file":"/etc/v2ray-agent/trojan/trojan.log", - "password": [ - "${uuid}" - ], - "dns":[ - "localhost" - ], - "transport_plugin":{ - "enabled":true, - "type":"plaintext" - }, - "websocket": { - "enabled": true, - "path": "/${customPath}tws", - "host": "${domain}", - "add":"${add}" - }, - "router": { - "enabled": false + "inbounds": [ + { + "port": ${realityPort}, + "protocol": "vless", + "tag": "VLESSReality", + "settings": { + "clients": $(initXrayClients 7), + "decryption": "none", + "fallbacks":[ + { + "dest": "31305", + "xver": 1 + } + ] + }, + "streamSettings": { + "network": "tcp", + "security": "reality", + "realitySettings": { + "show": false, + "dest": "${realityDestDomain}", + "xver": 0, + "serverNames": [ + ${realityServerNames} + ], + "privateKey": "${realityPrivateKey}", + "publicKey": "${realityPublicKey}", + "maxTimeDiff": 70000, + "shortIds": [ + "6ba85179e30d4fc2" + ] + } + } } + ] } EOF -} + cat </etc/v2ray-agent/xray/conf/08_VLESS_reality_fallback_grpc_inbounds.json +{ + "inbounds": [ + { + "port": 31305, + "listen": "127.0.0.1", + "protocol": "vless", + "tag": "VLESSRealityGRPC", + "settings": { + "clients": $(initXrayClients 8), + "decryption": "none" + }, + "streamSettings": { + "network": "grpc", + "grpcSettings": { + "serviceName": "grpc", + "multiMode": true + }, + "sockopt": { + "acceptProxyProtocol": true + } + } + } + ] +} +EOF + + else + rm /etc/v2ray-agent/xray/conf/07_VLESS_vision_reality_inbounds.json >/dev/null 2>&1 + rm /etc/v2ray-agent/xray/conf/08_VLESS_reality_fallback_grpc_inbounds.json >/dev/null 2>&1 + fi + installSniffing +} +#Initialize Xray Reality configuration # Custom CDN IP customCDNIP() { - echoContent skyBlue "\nProgress $1/${totalProgress} : add cloudflare custom CNAME" - echoContent red "\n==============================================================" - echoContent yellow "# Notes" - echoContent yellow "\nTutorial address:" - echoContent skyBlue "https://github.com/mack-a/v2ray-agent/blob/master/documents/optimize_V2Ray.md" - 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 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 ---> not used" - ;; - esac + echoContent skyBlue "\nProgress$1/${totalProgress}: Add cloudflare custom CNAME" + echoContent red "\n================================================ =================" + echoContent yellow "# Notes" + echoContent yellow "\nTutorial address:" + echoContent skyBlue "https://www.v2ray-agent.com/archives/cloudflarezi-xuan-ip" + echoContent red "\nIf you don't understand Cloudflare optimization, please do not use it" + echoContent yellow "\n1.CNAME www.digitalocean.com" + echoContent yellow "2.CNAME who.int" + echoContent yellow "3.CNAME blog.hostmonit.com" + + echoContent skyBlue "----------------------------" + read -r -p "Please select [Enter is not used]:" selectCloudflareType + case ${selectCloudflareType} in + 1) + add="www.digitalocean.com" + ;; + 2) + add="who.int" + ;; + 3) + add="blog.hostmonit.com" + ;; + *) + add="${domain}" + echoContent yellow "\n ---> Not used" + ;; + esac } -# generic +# General defaultBase64Code() { - local type=$1 - local email=$2 - local id=$3 + local type=$1 + local email=$2 + local id=$3 + local add=$4 + local user= + user=$(echo "${email}" | awk -F "[-]" '{print $1}') + port=${currentDefaultPort} - port=${currentDefaultPort} + if [[ "${type}" == "vlesstcp" ]]; then - 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 " ---> Universal format (VLESS+TCP+TLS_Vision)" + echoContent green " vless://${id}@${currentHost}:${currentDefaultPort}?encryption=none&security=tls&fp=chrome&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx- vision#${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 " ---> 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}@${currentHost}:${currentDefaultPort}?encryption=none&security=xtls&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx-direct#${email} + echoContent yellow " ---> Formatted plain text (VLESS+TCP+TLS_Vision)" + echoContent green "Protocol type: VLESS, address: ${currentHost}, port: ${currentDefaultPort}, user ID: ${id}, security: tls, client-fingerprint: chrome, transmission method: tcp, flow: xtls-rprx -vision, account name:${email}\n" + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" +vless://${id}@${currentHost}:${currentDefaultPort}?encryption=none&security=tls&type=tcp&host=${currentHost}&fp=chrome&headerType=none&sni=${currentHost}&flow=xtls-rprx-vision#${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${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}@${currentHost}:${currentDefaultPort}?encryption=none&security=xtls&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx-splice#${email/direct/splice}\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}@${currentHost}:${currentDefaultPort}?encryption=none&security=xtls&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx-splice#${email/direct/splice} + cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" + - name: "${email}" + type: vless + server: ${currentHost} + port: ${currentDefaultPort} + uuid: ${id} + network: tcp + tls: true + udp: true + flow: xtls-rprx-vision + client-fingerprint: chrome 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${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" + echoContent yellow " ---> QR code VLESS(VLESS+TCP+TLS_Vision)" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${currentHost}%3A${currentDefaultPort}%3Fencryption%3Dnone%26fp%3Dchrome%26security%3Dtls%26type%3Dtcp%26${currentHost}%3D${currentHost}%26headerType%3Dnone%26sni%3D${currentHost}%26flow%3Dxtls-rprx-vision%23${email}\n" + elif [[ "${coreInstallType}" == 2 ]]; then + echoContent yellow " ---> Universal format (VLESS+TCP+TLS)" + echoContent green " vless://${id}@${currentHost}:${currentDefaultPort}?security=tls&encryption=none&host=${currentHost}&fp=chrome&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 " ---> Formatted plain text (VLESS+TCP+TLS)" + echoContent green "Protocol type: VLESS, address: ${currentHost}, port: ${currentDefaultPort}, user ID: ${id}, security: tls, client-fingerprint: chrome, transmission method: 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}@${currentHost}:${currentDefaultPort}?security=tls&encryption=none&host=${currentHost}&headerType=none&type=tcp#${email} + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" +vless://${id}@${currentHost}:${currentDefaultPort}?security=tls&encryption=none&host=${currentHost}&fp=chrome&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${currentHost}%3a${currentDefaultPort}%3fsecurity%3dtls%26encryption%3dnone%26host%3d${currentHost}%26headerType%3dnone%26type%3dtcp%23${email}\n" - fi + 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${currentHost}%3a${currentDefaultPort}%3fsecurity%3dtls%26encryption%3dnone%26fp%3Dchrome%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}@${currentHost}:${currentDefaultPort}?encryption=none&security=xtls&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx-direct#${email}\n" + elif [[ "${type}" == "trojanTCPXTLS" ]]; then + echoContent yellow " ---> Common format (Trojan+TCP+TLS_Vision)" + echoContent green " trojan://${id}@${currentHost}:${currentDefaultPort}?encryption=none&security=xtls&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx-vision#${email}\n" - 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} + echoContent yellow " ---> Formatted plain text (Trojan+TCP+TLS_Vision)" + echoContent green "Protocol type: Trojan, address: ${currentHost}, port: ${currentDefaultPort}, user ID: ${id}, security: xtls, transmission method: tcp, flow: xtls-rprx-vision, account name: ${email}\n" + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" +trojan://${id}@${currentHost}:${currentDefaultPort}?encryption=none&security=xtls&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx-vision#${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${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 yellow " ---> QR code Trojan(Trojan+TCP+TLS_Vision)" + 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-vision%23${email}\n" - echoContent skyBlue "----------------------------------------------------------------------------------" + 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\":\"${add}\",\"allowInsecure\":0,\"method\":\"none\",\"peer\":\"${currentHost}\",\"sni\":\"${currentHost}\"}" | base64 -w 0) + qrCodeBase64Default="${qrCodeBase64Default// /}" - 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 " ---> Universal 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\":\"${add}\",\"allowInsecure\":0,\"method\":\"none\",\"peer\":\"${currentHost}\",\"sni\":\"${currentHost}\"}\n" + echoContent yellow " ---> Universal vmess (VMess+WS+TLS) link" + echoContent green " vmess://${qrCodeBase64Default}\n" + echoContent yellow " ---> QR code vmess(VMess+WS+TLS)" - 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${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// /}" - - 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)" - - cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" vmess://${qrCodeBase64Default} EOF - echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vmess://${qrCodeBase64Default}\n" + cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" + - name: "${email}" + type: vmess + server: ${add} + port: ${currentDefaultPort} + uuid: ${id} + alterId: 0 + cipher: none + udp: true + tls: true + client-fingerprint: chrome + servername: ${currentHost} + network: ws + ws-opts: + path: /${currentPath}vws + headers: + Host: ${currentHost} +EOF + 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 - elif [[ "${type}" == "vlessws" ]]; then + echoContent yellow " ---> Universal format (VLESS+WS+TLS)" + echoContent green " vless://${id}@${add}:${currentDefaultPort}?encryption=none&security=tls&type=ws&host=${currentHost}&sni=${currentHost}&fp=chrome&path=/${currentPath}ws #${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 " ---> Formatted plain text (VLESS+WS+TLS)" + echoContent green "Protocol type: VLESS, address: ${add}, disguised domain name/SNI: ${currentHost}, port: ${currentDefaultPort}, client-fingerprint: chrome, user ID: ${id}, security: tls, Transmission method: ws, path: /${currentPath}ws, 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}@${currentAdd}:${currentDefaultPort}?encryption=none&security=tls&type=ws&host=${currentHost}&sni=${currentHost}&path=/${currentPath}ws#${email} + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" +vless://${id}@${add}:${currentDefaultPort}?encryption=none&security=tls&type=ws&host=${currentHost}&sni=${currentHost}&fp=chrome&path=/${currentPath}ws#${email} +EOF + cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" + - name: "${email}" + type: vless + server: ${add} + port: ${currentDefaultPort} + uuid: ${id} + udp: true + tls: true + network: ws + client-fingerprint: chrome + servername: ${currentHost} + ws-opts: + path: /${currentPath}ws + headers: + Host: ${currentHost} EOF - 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}" + 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${add}%3A${currentDefaultPort}%3Fencryption%3Dnone%26security%3Dtls%26type%3Dws%26host%3D${currentHost}%26fp%3Dchrome%26sni%3D${currentHost}%26path%3D%252f${currentPath}ws%23${email}" - elif [[ "${type}" == "vlessgrpc" ]]; then + elif [[ "${type}" == "vlessgrpc" ]]; then - 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 " ---> Universal format (VLESS+gRPC+TLS)" + echoContent green " vless://${id}@${add}:${currentDefaultPort}?encryption=none&security=tls&type=grpc&host=${currentHost}&path=${currentPath}grpc&fp=chrome&serviceName=${currentPath}grpc&alpn=h2&sni=${currentHost}#${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" + echoContent yellow " ---> Formatted plain text (VLESS+gRPC+TLS)" + echoContent green "Protocol type: VLESS, address: ${add}, disguised domain name/SNI: ${currentHost}, port: ${currentDefaultPort}, user ID: ${id}, security: tls, transmission method: gRPC, alpn :h2, client-fingerprint: chrome, serviceName: ${currentPath}grpc, account name: ${email}\n" - cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" -vless://${id}@${currentAdd}:${currentDefaultPort}?encryption=none&security=tls&type=grpc&host=${currentHost}&path=${currentPath}grpc&serviceName=${currentPath}grpc&alpn=h2&sni=${currentHost}#${email} + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" +vless://${id}@${add}:${currentDefaultPort}?encryption=none&security=tls&type=grpc&host=${currentHost}&path=${currentPath}grpc&serviceName=${currentPath}grpc&fp=chrome&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${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}@${currentHost}:${currentDefaultPort}?peer=${currentHost}&sni=${currentHost}&alpn=http/1.1#${currentHost}_Trojan\n" - - cat <>"/etc/v2ray-agent/subscribe_tmp/${subAccount}" -trojan://${id}@${currentHost}:${currentDefaultPort}?peer=${currentHost}&sni=${currentHost}&alpn=http/1.1#${email}_Trojan + cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" + - name: "${email}" + type: vless + server: ${add} + port: ${currentDefaultPort} + uuid: ${id} + udp: true + tls: true + network: grpc + client-fingerprint: chrome + servername: ${currentHost} + grpc-opts: + grpc-service-name: ${currentPath}grpc 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${currentHost}%3a${port}%3fpeer%3d${currentHost}%26sni%3d${currentHost}%26alpn%3Dhttp/1.1%23${email}\n" + 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${currentDefaultPort}%3Fencryption%3Dnone%26security%3Dtls%26type%3Dgrpc%26host%3D${currentHost}%26serviceName%3D${currentPath}grpc%26fp%3Dchrome%26path%3D${currentPath}grpc%26sni%3D${currentHost}%26alpn%3Dh2%23${email}" - elif [[ "${type}" == "trojangrpc" ]]; then - # URLEncode + elif [[ "${type}" == "trojan" ]]; then + # URLEncode + echoContent yellow " ---> Trojan(TLS)" + echoContent green " trojan://${id}@${currentHost}:${currentDefaultPort}?peer=${currentHost}&fp=chrome&sni=${currentHost}&alpn=http/1.1#${currentHost}_Trojan\n" - echoContent yellow " ---> Trojan gRPC(TLS)" - 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}@${currentAdd}:${currentDefaultPort}?encryption=none&peer=${currentHost}&security=tls&type=grpc&sni=${currentHost}&alpn=h2&path=${currentPath}trojangrpc&serviceName=${currentPath}trojangrpc#${email} + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" +trojan://${id}@${currentHost}:${currentDefaultPort}?peer=${currentHost}&fp=chrome&sni=${currentHost}&alpn=http/1.1#${email}_Trojan 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${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}" -hysteria://${currentHost}:${hysteriaPort}?protocol=${hysteriaProtocol}&auth=${id}&peer=${currentHost}&insecure=0&alpn=h3&upmbps=${hysteriaClientUploadSpeed}&downmbps=${hysteriaClientDownloadSpeed}#${email} + cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" + - name: "${email}" + type: trojan + server: ${currentHost} + port: ${currentDefaultPort} + password: ${id} + client-fingerprint: chrome + udp: true + sni: ${currentHost} EOF - 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 + 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${currentHost}%3a${port}%3fpeer%3d${currentHost}%26fp%3Dchrome%26sni%3d${currentHost}%26alpn%3Dhttp/1.1%23${email}\n" + + elif [[ "${type}" == "trojangrpc" ]]; then + # URLEncode + + echoContent yellow " ---> Trojan gRPC(TLS)" + echoContent green " trojan://${id}@${add}:${currentDefaultPort}?encryption=none&peer=${currentHost}&fp=chrome&security=tls&type=grpc&sni=${currentHost}&alpn=h2&path=${currentPath}trojangrpc&serviceName=${currentPath}trojangrpc#${email}\n" + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" +trojan://${id}@${add}:${currentDefaultPort}?encryption=none&peer=${currentHost}&security=tls&type=grpc&fp=chrome&sni=${currentHost}&alpn=h2&path=${currentPath}trojangrpc&serviceName=${currentPath}trojangrpc#${email} +EOF + cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" + - name: "${email}" + server: ${add} + port: ${currentDefaultPort} + type: trojan + password: ${id} + network: grpc + sni: ${currentHost} + udp: true + grpc-opts: + grpc-service-name: ${currentPath}trojangrpc +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${add}%3a${currentDefaultPort}%3Fencryption%3Dnone%26fp%3Dchrome%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 + local hysteriaEmail= + hysteriaEmail=$(echo "${email}" | awk -F "[-]" '{print $1}')_hysteria + echoContent yellow " ---> Hysteria(TLS)" + local clashMetaPortTmp="port: ${hysteriaPort}" + local v2rayNPortHopping= + local mport= + if [[ -n "${portHoppingStart}" ]]; then + mport="mport=${portHoppingStart}-${portHoppingEnd}&" + clashMetaPortTmp="ports: ${portHoppingStart}-${portHoppingEnd}" + v2rayNPortHopping=",${portHoppingStart}-${portHoppingEnd}" + fi + echoContent green " hysteria://${currentHost}:${hysteriaPort}?${mport}protocol=${hysteriaProtocol}&auth=${id}&peer=${currentHost}&insecure=0&alpn=h3&upmbps=${hysteriaClientUploadSpeed}&downmbps=${hysteriaClientDownloadSpeed}#${hysteriaEmail}\n" + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" +hysteria://${currentHost}:${hysteriaPort}?${mport}protocol=${hysteriaProtocol}&auth=${id}&peer=${currentHost}&insecure=0&alpn=h3&upmbps=${hysteriaClientUploadSpeed}&downmbps=${hysteriaClientDownloadSpeed}#${hysteriaEmail} +EOF + echoContent yellow " ---> v2rayN(hysteria+TLS)" + cat <"/etc/v2ray-agent/hysteria/conf/client.json" +{ + "server": "${currentHost}:${hysteriaPort}${v2rayNPortHopping}", + "protocol": "${hysteriaProtocol}", + "up_mbps": ${hysteriaClientUploadSpeed}, + "down_mbps": ${hysteriaClientDownloadSpeed}, + "http": { "listen": "127.0.0.1:10809", "timeout": 300, "disable_udp": false }, + "socks5": { "listen": "127.0.0.1:10808", "timeout": 300, "disable_udp": false }, + "obfs": "", + "auth_str":"${id}", + "alpn": "h3", + "acl": "acl/routes.acl", + "mmdb": "acl/Country.mmdb", + "server_name": "${currentHost}", + "insecure": false, + "recv_window_conn": 5767168, + "recv_window": 23068672, + "disable_mtu_discovery": true, + "resolver": "https://223.5.5.5/dns-query", + "retry": 3, + "retry_interval": 3, + "quit_on_disconnect": false, + "handshake_timeout": 15, + "idle_timeout": 30, + "fast_open": true, + "hop_interval": 120 +} +EOF + local v2rayNConf= + v2rayNConf="$(cat /etc/v2ray-agent/hysteria/conf/client.json)" + echoContent green "${v2rayNConf}\n" + + cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" + - name: "${hysteriaEmail}" + type: hysteria + server: ${currentHost} + ${clashMetaPortTmp} + auth_str: ${id} + alpn: + - h3 + protocol: ${hysteriaProtocol} + up: "${hysteriaClientUploadSpeed}" + down: "${hysteriaClientDownloadSpeed}" + sni: ${currentHost} +EOF + echoContent yellow " ---> QR code Hysteria(TLS)" + if [[ -n "${mport}" ]]; then + mport="mport%3D${portHoppingStart}-${portHoppingEnd}%26" + fi + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=hysteria%3A%2F%2F${currentHost}%3A${hysteriaPort}%3F${mport}protocol%3D${hysteriaProtocol}%26auth%3D${id}%26peer%3D${currentHost}%26insecure%3D0%26alpn%3Dh3%26upmbps%3D${hysteriaClientUploadSpeed}%26downmbps%3D${hysteriaClientDownloadSpeed}%23${hysteriaEmail}\n" + elif [[ "${type}" == "vlessReality" ]]; then + echoContent yellow " ---> Universal format (VLESS+reality+uTLS+Vision)" + echoContent green " vless://${id}@$(getPublicIP):${currentRealityPort}?encryption=none&security=reality&type=tcp&sni=${currentRealityServerNames}&fp=chrome&pbk=${currentRealityPublicKey}&sid=6ba85179e30d4fc2&flow=xtls-rprx-vision#${email}\n" + + echoContent yellow " ---> Formatted plain text (VLESS+reality+uTLS+Vision)" + echoContent green "Protocol type: VLESS reality, address: $(getPublicIP), publicKey: ${currentRealityPublicKey}, shortId: 6ba85179e30d4fc2, serverNames: ${currentRealityServerNames}, port: ${currentRealityPort}, user ID: ${id}, transmission Method: tcp, account name: ${email}\n" + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" +vless://${id}@$(getPublicIP):${currentRealityPort}?encryption=none&security=reality&type=tcp&sni=${currentRealityServerNames}&fp=chrome&pbk=${currentRealityPublicKey}&sid=6ba85179e30d4fc2&flow=xtls-rprx-vision#${email} +EOF + cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" + - name: "${email}" + type: vless + server: $(getPublicIP) + port: ${currentRealityPort} + uuid: ${id} + network: tcp + tls: true + udp: true + flow: xtls-rprx-vision + servername: ${currentRealityServerNames} + reality-opts: + public-key: ${currentRealityPublicKey} + short-id: 6ba85179e30d4fc2 + client-fingerprint: chrome +EOF + echoContent yellow " ---> QR code VLESS(VLESS+reality+uTLS+Vision)" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40$(getPublicIP)%3A${currentRealityPort}%3Fencryption%3Dnone%26security%3Dreality%26type%3Dtcp%26sni%3D${currentRealityServerNames}%26fp%3Dchrome%26pbk%3D${currentRealityPublicKey}%26pbk%3D6ba85179e30d4fc2%26flow%3Dxtls-rprx-vision%23${email}\n" + + elif [[ "${type}" == "vlessRealityGRPC" ]]; then + echoContent yellow " ---> Universal format (VLESS+reality+uTLS+gRPC)" + echoContent green " vless://${id}@$(getPublicIP):${currentRealityPort}?encryption=none&security=reality&type=grpc&sni=${currentRealityServerNames}&fp=chrome&pbk=${currentRealityPublicKey}&sid=6ba85179e30d4fc2&path=grpc&serviceName=grpc#${email}\n" + + echoContent yellow " ---> Formatted plain text (VLESS+reality+uTLS+gRPC)" + echoContent green "Protocol type: VLESS reality, serviceName: grpc, address: $(getPublicIP), publicKey: ${currentRealityPublicKey}, shortId: 6ba85179e30d4fc2, serverNames: ${currentRealityServerNames}, port: ${currentRealityPort}, user ID: ${id}, transmission method: gRPC, client-fingerprint: chrome, account name: ${email}\n" + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" +vless://${id}@$(getPublicIP):${currentRealityPort}?encryption=none&security=reality&type=grpc&sni=${currentRealityServerNames}&fp=chrome&pbk=${currentRealityPublicKey}&sid=6ba85179e30d4fc2&path=grpc&serviceName=grpc#${email} +EOF + cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" + - name: "${email}" + type: vless + server: $(getPublicIP) + port: ${currentRealityPort} + uuid: ${id} + network: grpc + tls: true + udp: true + servername: ${currentRealityServerNames} + reality-opts: + public-key: ${currentRealityPublicKey} + short-id: 6ba85179e30d4fc2 + grpc-opts: + grpc-service-name: "grpc" + client-fingerprint: chrome +EOF + echoContent yellow " ---> QR code VLESS(VLESS+reality+uTLS+gRPC)" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40$(getPublicIP)%3A${currentRealityPort}%3Fencryption%3Dnone%26security%3Dreality%26type%3Dgrpc%26sni%3D${currentRealityServerNames}%26fp%3Dchrome%26pbk%3D${currentRealityPublicKey}%26pbk%3D6ba85179e30d4fc2%26path%3Dgrpc%26serviceName%3Dgrpc%23${email}\n" + elif [[ "${type}" == "tuic" ]]; then + + if [[ -z "${email}" ]]; then + echoContent red " ---> Failed to read configuration, please reinstall" + exit 0 + fi + + echoContent yellow " ---> Formatted plain text (Tuic+TLS)" + echoContent green "Protocol type: Tuic, address: ${currentHost}, port: ${tuicPort}, uuid: ${id}, password: ${id}, congestion-controller:${tuicAlgorithm}, alpn: h3, account Name:${email}_tuic\n" + + echoContent yellow " ---> v2rayN(Tuic+TLS)" + cat <"/etc/v2ray-agent/tuic/conf/v2rayN.json" +{ + "relay": { + "server": "${currentHost}:${tuicPort}", + "uuid": "${id}", + "password": "${id}", + "ip": "$(getPublicIP)", + "congestion_control": "${tuicAlgorithm}", + "alpn": ["h3"] + }, + "local": { + "server": "127.0.0.1:7798" + }, + "log_level": "warn" +} +EOF + local v2rayNConf= + v2rayNConf="$(cat /etc/v2ray-agent/tuic/conf/v2rayN.json)" + echoContent green "${v2rayNConf}" + + cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${email}" + - name: "${email}_tuic" + server: ${currentHost} + type: tuic + port: ${tuicPort} + uuid: ${id} + password: ${id} + alpn: + - h3 + congestion-controller: ${tuicAlgorithm} + disable-sni: true + reduce-rtt: true + fast-open: true + heartbeat-interval: 8000 + request-timeout: 8000 + max-udp-relay-packet-size: 1500 + max-open-streams: 100 + ip-version: dual + smux: + enabled: false +EOF + fi } # account showAccounts() { - readInstallType - readInstallProtocolType - readConfigHostPathUUID - readHysteriaConfig - echoContent skyBlue "\nProgress $1/${totalProgress} : Account" - local show - # VLESS TCP - if [[ -n "${configPath}" ]]; then - show=1 - if echo "${currentInstallProtocolType}" | grep -q trojan; then - echoContent skyBlue "===================== Trojan TCP TLS/XTLS-direct/XTLS-splice ======================\n" - jq .inbounds[0].settings.clients ${configPath}02_trojan_TCP_inbounds.json | jq -c '.[]' | while read -r user; do - local email= - email=$(echo "${user}" | jq -r .email) - echoContent skyBlue "\n ---> Account:${email}" - defaultBase64Code trojanTCPXTLS "${email}" "$(echo "${user}" | jq -r .password)" - done + readInstallType + readInstallProtocolType + readConfigHostPathUUID + readHysteriaConfig + readXrayCoreRealityConfig + readHysteriaPortHopping + readTuicConfig + echo + echoContent skyBlue "\nProgress$1/${totalProgress}: account" + local show + # VLESS TCP + if echo "${currentInstallProtocolType}" | grep -q trojan; then + echoContent skyBlue "===================== Trojan TCP TLS_Vision ======================\n" + jq .inbounds[0].settings.clients ${configPath}02_trojan_TCP_inbounds.json | jq -c '.[]' | while read -r user; do + 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" - jq .inbounds[0].settings.clients ${configPath}02_VLESS_TCP_inbounds.json | jq -c '.[]' | while read -r user; do - local email= - email=$(echo "${user}" | jq -r .email) + elif echo ${currentInstallProtocolType} | grep -q 0; then + show=1 + echoContent skyBlue "============================= VLESS TCP TLS_Vision ==============================\n" + jq .inbounds[0].settings.clients ${configPath}02_VLESS_TCP_inbounds.json | jq -c '.[]' | while read -r user; do + local email= + email=$(echo "${user}" | jq -r .email) - echoContent skyBlue "\n ---> Account:${email}" - echo - defaultBase64Code vlesstcp "${email}" "$(echo "${user}" | jq -r .id)" - done - fi + echoContent skyBlue "\n --->Account:${email}" + echo + 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" + # VLESS WS + if echo ${currentInstallProtocolType} | grep -q 1; then + echoContent skyBlue "\n================================ VLESS WS TLS CDN ================================\n" - jq .inbounds[0].settings.clients ${configPath}03_VLESS_WS_inbounds.json | jq -c '.[]' | while read -r user; do - local email= - email=$(echo "${user}" | jq -r .email) + jq .inbounds[0].settings.clients ${configPath}03_VLESS_WS_inbounds.json | jq -c '.[]' | while read -r user; do + local email= + email=$(echo "${user}" | jq -r .email) - echoContent skyBlue "\n ---> Account:${email}" - echo - local path="${currentPath}ws" - # 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 + echoContent skyBlue "\n --->Account:${email}" + echo + local path="${currentPath}ws" + local count= + while read -r line; do + if [[ -n "${line}" ]]; then + defaultBase64Code vlessws "${email}${count}" "$(echo "${user}" | jq -r .id)" "${line}" + count=$((count + 1)) + fi + done < <(echo "${currentAdd}" | tr ',' '\n') - # VMess WS - if echo ${currentInstallProtocolType} | grep -q 3; then - echoContent skyBlue "\n================================ VMess WS TLS CDN ================================\n" - local path="${currentPath}vws" - if [[ ${coreInstallType} == "1" ]]; then - path="${currentPath}vws" - fi - jq .inbounds[0].settings.clients ${configPath}05_VMess_WS_inbounds.json | jq -c '.[]' | while read -r user; do - local email= - email=$(echo "${user}" | jq -r .email) + done + fi - echoContent skyBlue "\n ---> Account:${email}" - echo - 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" + jq .inbounds[0].settings.clients ${configPath}06_VLESS_gRPC_inbounds.json | jq -c '.[]' | while read -r user; do - # VLESS grpc - if echo ${currentInstallProtocolType} | grep -q 5; then - echoContent skyBlue "\n=============================== VLESS gRPC TLS CDN ===============================\n" - 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 + local email= + email=$(echo "${user}" | jq -r .email) - local email= - email=$(echo "${user}" | jq -r .email) + echoContent skyBlue "\n --->Account:${email}" + echo + local count= + while read -r line; do + if [[ -n "${line}" ]]; then + defaultBase64Code vlessgrpc "${email}${count}" "$(echo "${user}" | jq -r .id)" "${line}" + count=$((count + 1)) + fi + done < <(echo "${currentAdd}" | tr ',' '\n') - echoContent skyBlue "\n ---> Account:${email}" - echo - defaultBase64Code vlessgrpc "${email}" "$(echo "${user}" | jq -r .id)" - done - fi - fi + done + fi - # trojan tcp - 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 - local email= - email=$(echo "${user}" | jq -r .email) - echoContent skyBlue "\n ---> Account:${email}" + # VMess WS + if echo ${currentInstallProtocolType} | grep -q 3; then + echoContent skyBlue "\n================================ VMess WS TLS CDN ================================\n" + local path="${currentPath}vws" + if [[ ${coreInstallType} == "1" ]]; then + path="${currentPath}vws" + fi + jq .inbounds[0].settings.clients ${configPath}05_VMess_WS_inbounds.json | jq -c '.[]' | while read -r user; do + local email= + email=$(echo "${user}" | jq -r .email) - defaultBase64Code trojan "${email}" "$(echo "${user}" | jq -r .password)" - done - fi + echoContent skyBlue "\n --->Account:${email}" + echo + local count= + while read -r line; do + if [[ -n "${line}" ]]; then + defaultBase64Code vmessws "${email}${count}" "$(echo "${user}" | jq -r .id)" "${line}" + count=$((count + 1)) + fi + done < <(echo "${currentAdd}" | tr ',' '\n') + done + fi - if echo ${currentInstallProtocolType} | grep -q 2; then - echoContent skyBlue "\n================================ Trojan gRPC TLS ================================\n" - 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 - local email= - email=$(echo "${user}" | jq -r .email) + #trojantcp + 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 + local email= + email=$(echo "${user}" | jq -r .email) + echoContent skyBlue "\n --->Account:${email}" - echoContent skyBlue "\n ---> Account:${email}" - echo - 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" + defaultBase64Code trojan "${email}" "$(echo "${user}" | jq -r .password)" + done + fi - jq .auth.config ${hysteriaConfigPath}config.json | jq -r '.[]' | while read -r user; do - local defaultUser= - local uuidType= - uuidType=".id" + if echo ${currentInstallProtocolType} | grep -q 2; then + echoContent skyBlue "\n================================ Trojan gRPC TLS ================================\n" + jq .inbounds[0].settings.clients ${configPath}04_trojan_gRPC_inbounds.json | jq -c '.[]' | while read -r user; do + local email= + email=$(echo "${user}" | jq -r .email) - if [[ "${frontingType}" == "02_trojan_TCP_inbounds" ]]; then - uuidType=".password" - fi + echoContent skyBlue "\n --->Account:${email}" + echo + local count= + while read -r line; do + if [[ -n "${line}" ]]; then + defaultBase64Code trojangrpc "${email}${count}" "$(echo "${user}" | jq -r .password)" "${line}" + count=$((count + 1)) + fi + done < <(echo "${currentAdd}" | tr ',' '\n') - defaultUser=$(jq '.inbounds[0].settings.clients[]|select('${uuidType}'=="'"${user}"'")' ${configPath}${frontingType}.json) - local email= - email=$(echo "${defaultUser}" | jq -r .email) + done + fi + if echo ${currentInstallProtocolType} | grep -q 6; then + echoContent skyBlue "\n================================ Hysteria TLS ================================\n" + echoContent red "\n --->Hysteria speed 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" - if [[ -n ${defaultUser} ]]; then - echoContent skyBlue "\n ---> Account:${email}" - echo - defaultBase64Code hysteria "${email}" "${user}" - fi + jq .auth.config ${hysteriaConfigPath}config.json | jq -r '.[]' | while read -r user; do + local defaultUser= + local uuidType= + uuidType=".id" - done + if [[ "${frontingType}" == "02_trojan_TCP_inbounds" ]]; then + uuidType=".password" + fi - fi + defaultUser=$(jq '.inbounds[0].settings.clients[]|select('${uuidType}'=="'"${user}"'")' ${configPath}${frontingType}.json) + local email= + email=$(echo "${defaultUser}" | jq -r .email) + local hysteriaEmail= + hysteriaEmail=$(echo "${email}" | awk -F "[_]" '{print $1}')_hysteria - if [[ -z ${show} ]]; then - echoContent red "---> not installed" - fi + if [[ -n ${defaultUser} ]]; then + echoContent skyBlue "\n ---> Account:$(echo "${hysteriaEmail}" | awk -F "[-]" '{print $1"_hysteria"}')" + echo + defaultBase64Code hysteria "${hysteriaEmail}" "${user}" + fi + + done + + fi + + # VLESS reality vision + if echo ${currentInstallProtocolType} | grep -q 7; then + show=1 + echoContent skyBlue "============================= VLESS reality_vision ==============================\n" + jq .inbounds[0].settings.clients ${configPath}07_VLESS_vision_reality_inbounds.json | jq -c '.[]' | while read -r user; do + local email= + email=$(echo "${user}" | jq -r .email) + + echoContent skyBlue "\n --->Account:${email}" + echo + defaultBase64Code vlessReality "${email}" "$(echo "${user}" | jq -r .id)" + done + fi + + # VLESS reality + if echo ${currentInstallProtocolType} | grep -q 8; then + show=1 + echoContent skyBlue "============================== VLESS reality_gRPC ===============================\n" + jq .inbounds[0].settings.clients ${configPath}08_VLESS_reality_fallback_grpc_inbounds.json | jq -c '.[]' | while read -r user; do + local email= + email=$(echo "${user}" | jq -r .email) + + echoContent skyBlue "\n --->Account:${email}" + echo + defaultBase64Code vlessRealityGRPC "${email}" "$(echo "${user}" | jq -r .id)" + done + fi + #tuic + if echo ${currentInstallProtocolType} | grep -q 9; then + echoContent skyBlue "\n================================ Tuic TLS ================================\n" + echoContent yellow "\n --->Tuic will be warmer and may have a smoother user experience than Hysteria." + + jq -r .users[] "${tuicConfigPath}config.json" | while read -r id; do + local tuicEmail= + tuicEmail=$(jq -r '.inbounds[0].settings.clients[]|select(.id=="'"${id}"'")|.email' ${configPath}${frontingType}. json | awk -F "[-]" '{print $1}') + + if [[ -n ${tuicEmail} ]]; then + echoContent skyBlue "\n --->Account:${tuicEmail}_tuic" + echo + defaultBase64Code tuic "${tuicEmail}" "${id}" + fi + + done + + fi + + if [[ -z ${show} ]]; then + 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 + local count= + grep -n "return 302" <"${nginxConfigPath}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 + if ! echo "${line}" | grep -q "request_uri"; then + local removeIndex= + removeIndex=$(echo "${line}" | awk -F "[:]" '{print $1}') + removeIndex=$((removeIndex + count)) + sed -i "${removeIndex}d" ${nginxConfigPath}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 + local domain302Status= + domain302Status=$(curl -s "https://${currentHost}:${currentPort}") + if echo "${domain302Status}" | grep -q "302"; then + local domain302Result= + domain302Result=$(curl -L -s "https://${currentHost}:${currentPort}") + if [[ -n "${domain302Result}" ]]; then + echoContent green " ---> 302 redirection set up successfully" + exit 0 + fi + fi + echoContent red " ---> 302 redirection setting failed, please double check whether 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" == "backup" ]]; then + cp ${nginxConfigPath}alone.conf /etc/v2ray-agent/alone_backup.conf + echoContent green " ---> nginx configuration file backup successful" + 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 + if [[ "$1" == "restoreBackup" ]] && [[ -f "/etc/v2ray-agent/alone_backup.conf" ]]; then + cp /etc/v2ray-agent/alone_backup.conf ${nginxConfigPath}alone.conf + echoContent green " ---> nginx configuration file restoration backup successful" + 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 + # local line302Result= + # line302Result=$(| tail -n 1) + local count=1 + grep -n "Strict-Transport-Security" <"${nginxConfigPath}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';" ${nginxConfigPath}alone.conf >${nginxConfigPath}tmpfile && mv ${nginxConfigPath}tmpfile ${nginxConfigPath}alone.conf + count=$((count + 1)) + else + echoContent red " ---> 302 Add failed" + backupNginxConfig restoreBackup + fi - done + done } # Update camouflage station updateNginxBlog() { - echoContent skyBlue "\nProgress $1/${totalProgress} : Change fake site" - echoContent red "==============================================================" - 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 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 Automatically jump to baidu" - echoContent yellow "10.302 redirect site" - echoContent red "==============================================================" - read -r -p "Please select:" selectInstallNginxBlogType + echoContent skyBlue "\nProgress$1/${totalProgress}: Change disguise site" - 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 ! echo "${currentInstallProtocolType}" | grep -q "0" || [[ -z "${coreInstallType}" ]]; then + echoContent red "\n ---> Due to environmental dependencies, please install Xray-core's VLESS_TCP_TLS_Vision first" + exit 0 + fi + echoContent red "================================================== =========== ====" + echoContent yellow "# If you need to customize, please manually copy the template file to ${nginxStaticPath} \n" + echoContent yellow "1.Newbie guide" + echoContent yellow "2.Game website" + echoContent yellow "3.Personal blog 01" + echoContent yellow "4.Enterprise Station" + echoContent yellow "5.Unlock 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 automatically jumps to baidu" + echoContent yellow "10.302 redirect website" + echoContent red "================================================== ===============" + read -r -p "Please select:" selectInstallNginxBlogType - 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/* - 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 - else - wget -c -P /usr/share/nginx "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${selectInstallNginxBlogType}.zip" >/dev/null - fi + if [[ "${selectInstallNginxBlogType}" == "10" ]]; then + echoContent red "\n================================================ =================" + echoContent yellow "Redirect has a higher priority. If you change the camouflage site after configuring 302, the camouflage site under the root route will not work." + echoContent yellow "If you want to disguise the site to achieve the function, 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 - 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 fake station successfully" - else - echoContent red " ---> Selection error, please select again" - updateNginxBlog - fi + if [[ "${redirectStatus}" == "1" ]]; then + backupNginxConfig backup + read -r -p "Please enter the domain name to be redirected, for example 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 " ---> Removed 302 redirect successfully" + exit 0 + fi + fi + if [[ "${selectInstallNginxBlogType}" =~ ^[1-9]$ ]]; then + rm -rf "${nginxStaticPath}" + + wget -q -P "${nginxStaticPath}" "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${selectInstallNginxBlogType}.zip" >/dev/null + + unzip -o "${nginxStaticPath}html${selectInstallNginxBlogType}.zip" -d "${nginxStaticPath}" >/dev/null + rm -f "${nginxStaticPath}html${selectInstallNginxBlogType}.zip*" + echoContent green " ---> Pseudo site replaced successfully" + else + echoContent red " ---> Wrong selection, please select again" + updateNginxBlog + fi } -# add new port +#Add new port addCorePort() { - echoContent skyBlue "\nFunction 1/${totalProgress} : add new port" - echoContent red "\n==============================================================" - 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" + readHysteriaConfig + echoContent skyBlue "\nFunction 1/${totalProgress}: Add new port" + echoContent red "\n================================================ =================" + echoContent yellow "# Notes\n" + echoContent yellow "Support batch addition" + echoContent yellow "Does not affect the use of the default port" + echoContent yellow "When viewing accounts, only accounts with default ports will be displayed" + echoContent yellow "No special characters allowed, pay attention to the comma format" + echoContent yellow "If hysteria is already installed, a new hysteria port will be installed at the same time" + echoContent yellow "Input example:2053,2083,2087\n" - echoContent yellow "1.Add port" - echoContent yellow "2.Delete port" - echoContent red "==============================================================" - 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 + echoContent yellow "1.Check the added port" + echoContent yellow "2.Add port" + echoContent yellow "3.Delete port" + echoContent red "================================================== ===============" + read -r -p "Please select:" selectNewPortType + if [[ "${selectNewPortType}" == "1" ]]; then + find ${configPath} -name "*dokodemodoor*" | grep -v "hysteria" | awk -F "[c][o][n][f][/]" '{print $2}' | awk -F "[_]" '{print $4}' | awk -F "[.]" '{print ""NR""":"$1}' + exit 0 + elif [[ "${selectNewPortType}" == "2" ]]; 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 "${defaultPort}" ]]; then + rm -rf "$(find ${configPath}* | grep "default")" + fi - if [[ -n "${newPort}" ]]; then + if [[ -n "${newPort}" ]]; then - while read -r port; do - rm -rf "$(find ${configPath}* | grep "${port}")" + while read -r port; do + 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 + local fileName= + local hysteriaFileName= + 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}" + if [[ -n ${hysteriaPort} ]]; then + hysteriaFileName="${configPath}02_dokodemodoor_inbounds_hysteria_${port}.json" + fi - local settingsPort=443 - if [[ -n "${customPort}" ]]; then - settingsPort=${customPort} - fi + # open port + allowPort "${port}" + allowPort "${port}" "udp" - cat <"${fileName}" + local settingsPort=443 + if [[ -n "${customPort}" ]]; then + settingsPort=${customPort} + fi + + if [[ -n ${hysteriaFileName} ]]; then + cat <"${hysteriaFileName}" +{ + "inbounds": [ + { + "listen": "0.0.0.0", + "port": ${port}, + "protocol": "dokodemo-door", + "settings": { + "address": "127.0.0.1", + "port": ${hysteriaPort}, + "network": "udp", + "followRedirect": false + }, + "tag": "dokodemo-door-newPort-hysteria-${port}" + } + ] +} +EOF + fi + cat <"${fileName}" { "inbounds": [ { @@ -3603,462 +4669,621 @@ addCorePort() { ] } EOF - done < <(echo "${newPort}" | tr ',' '\n') + done < <(echo "${newPort}" | tr ',' '\n') - echoContent green " ---> Add successfully" - reloadCore - fi - elif [[ "${selectNewPortType}" == "2" ]]; then + echoContent green " ---> Added successfully" + reloadCore + addCorePort + fi + elif [[ "${selectNewPortType}" == "3" ]]; then + find ${configPath} -name "*dokodemodoor*" | grep -v "hysteria" | awk -F "[c][o][n][f][/]" '{print $2}' | awk -F "[_]" '{print $4}' | awk -F "[.]" '{print ""NR""":"$1}' + read -r -p "Please enter the port number to be deleted:" portIndex + local dokoConfig + dokoConfig=$(find ${configPath} -name "*dokodemodoor*" | grep -v "hysteria" | awk -F "[c][o][n][f][/]" '{print $2}' | awk -F "[_]" '{print $4}' | awk -F "[.]" '{print ""NR""":"$1}' | grep "${portIndex}:") + if [[ -n "${dokoConfig}" ]]; then + rm "${configPath}02_dokodemodoor_inbounds_$(echo "${dokoConfig}" | awk -F "[:]" '{print $2}').json" + local hysteriaDokodemodoorFilePath= - 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}')" - reloadCore - else - echoContent yellow "\n ---> The input number is wrong, please select again" - addCorePort - fi - fi + hysteriaDokodemodoorFilePath="${configPath}02_dokodemodoor_inbounds_hysteria_$(echo "${dokoConfig}" | awk -F "[:]" '{print $2}').json" + if [[ -f "${hysteriaDokodemodoorFilePath}" ]]; then + rm "${hysteriaDokodemodoorFilePath}" + fi + + reloadCore + addCorePort + else + echoContent yellow "\n ---> The number entered is wrong, please choose again" + addCorePort + fi + fi } -# uninstall script +# Uninstall script unInstall() { - read -r -p "Are you sure to uninstall the installation content? [y/n]:" unInstallStatus - if [[ "${unInstallStatus}" != "y" ]]; then - echoContent green " ---> Abort uninstall" - menu - exit 0 - fi + read -r -p "Are you sure you want to uninstall the installation content? [y/n]:" unInstallStatus + if [[ "${unInstallStatus}" != "y" ]]; then + echoContent green " ---> Give up uninstalling" + menu + exit 0 + fi + echoContent yellow " ---> The script will not delete acme related configurations. To delete, please execute manually [rm -rf /root/.acme.sh]" + handleNginx stop + if [[ -z $(pgrep -f "nginx") ]]; then + echoContent green " ---> Stop Nginx successfully" + fi - handleNginx stop - if [[ -z $(pgrep -f "nginx") ]]; then - echoContent green "---> stop Nginx successfully" - fi + if [[ "${coreInstallType}" == "1" ]]; then + handleXray stop + rm -rf /etc/systemd/system/xray.service + echoContent green " ---> Delete Xray and it will start automatically after booting" - 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 - elif [[ "${coreInstallType}" == "2" ]]; then + handleV2Ray stop + rm -rf /etc/systemd/system/v2ray.service + echoContent green " ---> Delete V2Ray and it will start automatically after booting" - handleV2Ray stop - rm -rf /etc/systemd/system/v2ray.service - echoContent green " ---> Delete V2Ray boot auto-start complete" + fi - fi + if [[ -z "${hysteriaConfigPath}" ]]; then + handleHysteria stop + rm -rf /etc/systemd/system/hysteria.service + echoContent green " ---> Delete Hysteria and it will start automatically after booting" + fi - if [[ -z "${hysteriaConfigPath}" ]]; then - handleHysteria stop - rm -rf /etc/systemd/system/hysteria.service - echoContent green " ---> Delete Hysteria boot auto-start complete" - fi + if [[ -z "${tuicConfigPath}" ]]; then + handleTuic stop + rm -rf /etc/systemd/system/tuic.service + echoContent green " ---> Delete Tuic and start automatically after booting" + fi - if [[ -f "/root/.acme.sh/acme.sh.env" ]] && grep -q 'acme.sh.env' delete acme.sh complete" + # if [[ -f "/root/.acme.sh/acme.sh.env" ]] && grep -q 'acme.sh.env' The backup certificate is successful, please keep it.[/tmp/v2ray-agent-tls]" - fi - fi + #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 " ---> Backup certificate successful, please save it. [/tmp/v2ray-agent-tls]" + #fi + #fi - rm -rf /etc/v2ray-agent - rm -rf ${nginxConfigPath}alone.conf + rm -rf /etc/v2ray-agent + 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 + if [[ -d "${nginxStaticPath}" && -f "${nginxStaticPath}/check" ]]; then + rm -rf "${nginxStaticPath}" + echoContent green " ---> Deletion of fake website completed" + fi - rm -rf /usr/bin/vasma - rm -rf /usr/sbin/vasma - echoContent green " ---> Uninstall shortcut completed" - echoContent green "---> Uninstall v2ray-agent script completed" + rm -rf /usr/bin/vasma + rm -rf /usr/sbin/vasma + echoContent green " ---> Uninstallation of shortcut completed" + echoContent green " ---> Uninstall v2ray-agent script completed" } -#updateGeoSite - # Modify V2Ray CDN node updateV2RayCDN() { - # todo refactor this method - echoContent skyBlue "\nProgress $1/${totalProgress} : Modify CDN node" + echoContent skyBlue "\nProgress$1/${totalProgress}: Modify CDN node" - 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 select:" selectCDNType - case ${selectCDNType} in - 1) - setDomain="www.digitalocean.com" - ;; - 2) - setDomain="www.cloudflare.com" - ;; - 3) - setDomain="hostmonit.com" - ;; - 4) - read -r -p "Please enter the CDN IP or domain name you want to customize:" setDomain - ;; - esac + if [[ -n "${currentAdd}" ]]; then + echoContent red "================================================== ===============" + echoContent yellow "1.CNAME www.digitalocean.com" + echoContent yellow "2.CNAME who.int" + echoContent yellow "3.CNAME blog.hostmonit.com" + echoContent yellow "4.Manual input [can enter multiple, such as:1.1.1.1,1.1.2.2, cloudflare.com separated by commas]" + echoContent yellow "5.Remove CDN node" + echoContent red "================================================== ===============" + read -r -p "Please select:" selectCDNType + case ${selectCDNType} in + 1) + setDomain="www.digitalocean.com" + ;; + 2) + setDomain="who.int" + ;; + 3) + setDomain="blog.hostmonit.com" + ;; + 4) + read -r -p "Please enter the CDN IP or domain name you want to customize:" setDomain + ;; + 5) + setDomain=${currentHost} + ;; + esac - if [[ -n ${setDomain} ]]; then - 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 modified successfully" - reloadCore - else - echoContent red " ---> Failed to modify CDN" - fi - fi - else - echoContent red " ---> Available types are not installed" - fi + if [[ -n "${setDomain}" ]]; then + local cdnAddressResult= + cdnAddressResult=$(jq -r ".inbounds[0].add = \"${setDomain}\" " ${configPath}${frontingType}.json) + echo "${cdnAddressResult}" | jq . >${configPath}${frontingType}.json + + echoContent green " ---> CDN modified successfully" + fi + else + echoContent red " ---> Available types are not installed" + fi } -# manageUser user management +# manageUser User management manageUser() { - echoContent skyBlue "\nProgress $1/${totalProgress} : multi-user management" - echoContent skyBlue "-----------------------------------------------------" - echoContent yellow "1.Add user" - echoContent yellow "2.Delete user" - echoContent skyBlue "-----------------------------------------------------" - read -r -p "Please select:" manageUserType - if [[ "${manageUserType}" == "1" ]]; then - addUser - elif [[ "${manageUserType}" == "2" ]]; then - removeUser - else - echoContent red " ---> Selection error" - fi + echoContent skyBlue "\nProgress$1/${totalProgress}: Multi-user management" + echoContent skyBlue "------------------------------------------------- ------" + echoContent yellow "1.Add user" + echoContent yellow "2.Delete user" + echoContent skyBlue "------------------------------------------------- ------" + read -r -p "Please select:" manageUserType + if [[ "${manageUserType}" == "1" ]]; then + addUser + elif [[ "${manageUserType}" == "2" ]]; then + removeUser + else + echoContent red " ---> Wrong selection" + fi } -# custom uuid +# Custom uuid customUUID() { - # 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 [[ -z "${currentCustomUUID}" ]]; then - # echoContent red " ---> UUID cannot be empty" - currentCustomUUID=$(${ctlPath} uuid) - echoContent yellow "uuid:${currentCustomUUID}\n" + read -r -p "Please enter a legal UUID, [Enter] random UUID:" currentCustomUUID + echo + if [[ -z "${currentCustomUUID}" ]]; then + 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 + 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 } -# custom email +# Custom email customUserEmail() { - # 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 [[ -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 + read -r -p "Please enter a valid email, [Enter] random email:" currentCustomEmail + echo + if [[ -z "${currentCustomEmail}" ]]; then + currentCustomEmail="${currentCustomUUID}" + echoContent yellow "email: ${currentCustomEmail}\n" + else + local defaultConfig=${frontingType} + + if echo "${currentInstallProtocolType}" | grep -q "7" && [[ -z "${frontingType}" ]]; then + defaultConfig="07_VLESS_vision_reality_inbounds" + fi + + jq -r -c '.inbounds[0].settings.clients[].email' ${configPath}${defaultConfig}.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 +addUserXray() { + readConfigHostPathUUID + read -r -p "Please enter the number of users to add:" userNum + echo + if [[ -z ${userNum} || ${userNum} -le 0 ]]; then + echoContent red " ---> Incorrect input, please re-enter" + exit 0 + fi + # 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 + local email= + if [[ -z "${currentCustomEmail}" ]]; then + email=${uuid} + else + email=${currentCustomEmail} + fi + + # VLESS TCP + if echo "${currentInstallProtocolType}" | grep -q "0"; then + local clients= + clients=$(initXrayClients 0 "${uuid}" "${email}") + clients=$(jq -r ".inbounds[0].settings.clients = ${clients}" ${configPath}${frontingType}.json) + echo "${clients}" | jq . >${configPath}${frontingType}.json + fi + + # VLESS WS + if echo "${currentInstallProtocolType}" | grep -q "1"; then + local clients= + clients=$(initXrayClients 1 "${uuid}" "${email}") + clients=$(jq -r ".inbounds[0].settings.clients = ${clients}" ${configPath}03_VLESS_WS_inbounds.json) + echo "${clients}" | jq . >${configPath}03_VLESS_WS_inbounds.json + fi + + # trojan grpc + if echo "${currentInstallProtocolType}" | grep -q "2"; then + local clients= + clients=$(initXrayClients 2 "${uuid}" "${email}") + clients=$(jq -r ".inbounds[0].settings.clients = ${clients}" ${configPath}04_trojan_gRPC_inbounds.json) + echo "${clients}" | jq . >${configPath}04_trojan_gRPC_inbounds.json + fi + # VMess WS + if echo "${currentInstallProtocolType}" | grep -q "3"; then + local clients= + clients=$(initXrayClients 3 "${uuid}" "${email}") + clients=$(jq -r ".inbounds[0].settings.clients = ${clients}" ${configPath}05_VMess_WS_inbounds.json) + echo "${clients}" | jq . >${configPath}05_VMess_WS_inbounds.json + fi + + # trojan tcp + if echo "${currentInstallProtocolType}" | grep -q "4"; then + local clients= + clients=$(initXrayClients 4 "${uuid}" "${email}") + clients=$(jq -r ".inbounds[0].settings.clients = ${clients}" ${configPath}04_trojan_TCP_inbounds.json) + echo "${clients}" | jq . >${configPath}04_trojan_TCP_inbounds.json + fi + + # vless grpc + if echo "${currentInstallProtocolType}" | grep -q "5"; then + local clients= + clients=$(initXrayClients 5 "${uuid}" "${email}") + clients=$(jq -r ".inbounds[0].settings.clients = ${clients}" ${configPath}06_VLESS_gRPC_inbounds.json) + echo "${clients}" | jq . >${configPath}06_VLESS_gRPC_inbounds.json + fi + + # vless reality vision + if echo "${currentInstallProtocolType}" | grep -q "7"; then + local clients= + clients=$(initXrayClients 7 "${uuid}" "${email}") + clients=$(jq -r ".inbounds[0].settings.clients = ${clients}" ${configPath}07_VLESS_vision_reality_inbounds.json) + echo "${clients}" | jq . >${configPath}07_VLESS_vision_reality_inbounds.json + fi + + # vless reality grpc + if echo "${currentInstallProtocolType}" | grep -q "8"; then + local clients= + clients=$(initXrayClients 8 "${uuid}" "${email}") + clients=$(jq -r ".inbounds[0].settings.clients = ${clients}" ${configPath}08_VLESS_reality_fallback_grpc_inbounds.json) + echo "${clients}" | jq . >${configPath}08_VLESS_reality_fallback_grpc_inbounds.json + fi + + # hysteria + if echo "${currentInstallProtocolType}" | grep -q "6"; then + local clients= + clients=$(initXrayClients 6 "${uuid}" "${email}") + + clients=$(jq -r ".auth.config = ${clients}" ${hysteriaConfigPath}config.json) + echo "${clients}" | jq . >${hysteriaConfigPath}config.json + fi + + if echo ${currentInstallProtocolType} | grep -q 9; then + local tuicResult + + tuicResult=$(jq -r ".users.\"${uuid}\" += \"${uuid}\"" "${tuicConfigPath}config.json") + echo "${tuicResult}" | jq . >"${tuicConfigPath}config.json" + fi + done + + reloadCore + echoContent green " ---> Adding completed" + manageAccount 1 +} # Add user addUser() { - 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 " ---> Input error, please re-enter" - exit 0 - fi + echoContent yellow "After adding a new user, you need to check 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 " ---> Incorrect input, please re-enter" + exit 0 + fi - # generate user - if [[ "${userNum}" == "1" ]]; then - customUUID - customUserEmail - fi + # 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 + 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 [[ -n "${currentCustomEmail}" ]]; then + email=${currentCustomEmail}_${uuid} + else + email=${currentHost}_${uuid} + fi - # Compatible with v2ray-core - users="{\"id\":\"${uuid}\",\"flow\":\"xtls-rprx-direct\",\"email\":\"${email}\",\"alterId\":0}" + #Compatible with v2ray-core + users="{\"id\":\"${uuid}\",\"flow\":\"xtls-rprx-vision\",\"email\":\"${email}\",\"alterId\":0}" - if [[ "${coreInstallType}" == "2" ]]; then - users="{\"id\":\"${uuid}\",\"email\":\"${email}\",\"alterId\":0}" - fi + if [[ "${coreInstallType}" == "2" ]]; then + users="{\"id\":\"${uuid}\",\"email\":\"${email}\",\"alterId\":0}" + fi - if echo ${currentInstallProtocolType} | grep -q 0; then - local vlessUsers="${users//\,\"alterId\":0/}" + if echo ${currentInstallProtocolType} | grep -q 0; then + local vlessUsers="${users//\,\"alterId\":0/}" + vlessUsers="${users//${email}/${email}_VLESS_TCP}" + local vlessTcpResult + vlessTcpResult=$(jq -r ".inbounds[0].settings.clients += [${vlessUsers}]" ${configPath}${frontingType}.json) + echo "${vlessTcpResult}" | 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 + if echo ${currentInstallProtocolType} | grep -q trojan; then + local trojanXTLSUsers="${users//\,\"alterId\":0/}" + trojanXTLSUsers="${trojanXTLSUsers//${email}/${email}_Trojan_TCP}" + trojanXTLSUsers=${trojanXTLSUsers//"id"/"password"} - if echo ${currentInstallProtocolType} | grep -q trojan; then - local trojanXTLSUsers="${users//\,\"alterId\":0/}" - trojanXTLSUsers=${trojanXTLSUsers//"id"/"password"} + local trojanXTLSResult + trojanXTLSResult=$(jq -r ".inbounds[0].settings.clients += [${trojanXTLSUsers}]" ${configPath}${frontingType}.json) + echo "${trojanXTLSResult}" | jq . >${configPath}${frontingType}.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 1; then + local vlessUsers="${users//\,\"alterId\":0/}" + vlessUsers="${vlessUsers//${email}/${email}_VLESS_TCP}" + vlessUsers="${vlessUsers//\"flow\":\"xtls-rprx-vision\"\,/}" + 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 - 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 + if echo ${currentInstallProtocolType} | grep -q 2; then + local trojangRPCUsers="${users//\"flow\":\"xtls-rprx-vision\"\,/}" + trojangRPCUsers="${trojangRPCUsers//${email}/${email}_Trojan_gRPC}" + trojangRPCUsers="${trojangRPCUsers//\,\"alterId\":0/}" + trojangRPCUsers=${trojangRPCUsers//"id"/"password"} - if echo ${currentInstallProtocolType} | grep -q 2; then - local trojangRPCUsers="${users//\"flow\":\"xtls-rprx-direct\"\,/}" - trojangRPCUsers="${trojangRPCUsers//\,\"alterId\":0/}" - trojangRPCUsers=${trojangRPCUsers//"id"/"password"} + 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 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 3; then + local vmessUsers="${users//\"flow\":\"xtls-rprx-vision\"\,/}" + vmessUsers="${vmessUsers//${email}/${email}_VMess_TCP}" + 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-vision\"\,/}" + vlessGRPCUsers="${vlessGRPCUsers//\,\"alterId\":0/}" + vlessGRPCUsers="${vlessGRPCUsers//${email}/${email}_VLESS_gRPC}" + 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 - 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 4; then + local trojanUsers="${users//\"flow\":\"xtls-rprx-vision\"\,/}" + trojanUsers="${trojanUsers//id/password}" + trojanUsers="${trojanUsers//\,\"alterId\":0/}" + trojanUsers="${trojanUsers//${email}/${email}_Trojan_TCP}" - if echo ${currentInstallProtocolType} | grep -q 5; then - local vlessGRPCUsers="${users//\"flow\":\"xtls-rprx-direct\"\,/}" - vlessGRPCUsers="${vlessGRPCUsers//\,\"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 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 6; then + local hysteriaResult + hysteriaResult=$(jq -r ".auth.config += [\"${uuid}\"]" ${hysteriaConfigPath}config.json) + echo "${hysteriaResult}" | jq . >${hysteriaConfigPath}config.json + fi + done - 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 - - 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 complete" - manageAccount 1 + reloadCore + echoContent green " ---> Adding completed" + manageAccount 1 } -# remove user +# Remove user removeUser() { + local uuid= + 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 to delete [only supports single deletion]:" delUserIndex + if [[ $(jq -r '.inbounds[0].settings.clients|length' ${configPath}${frontingType}.json) -lt ${delUserIndex} ]]; then + echoContent red " ---> Wrong selection" + else + delUserIndex=$((delUserIndex - 1)) + local vlessTcpResult + uuid=$(jq -r ".inbounds[0].settings.clients[${delUserIndex}].id" ${configPath}${frontingType}.json) + vlessTcpResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}${frontingType}.json) + echo "${vlessTcpResult}" | jq . >${configPath}${frontingType}.json + fi + elif [[ -n "${realityStatus}" ]]; then + jq -r -c .inbounds[0].settings.clients[].email ${configPath}07_VLESS_vision_reality_inbounds.json | awk '{print NR""":"$0}' + read -r -p "Please select the user number to delete [only supports single deletion]:" delUserIndex + if [[ $(jq -r '.inbounds[0].settings.clients|length' ${configPath}07_VLESS_vision_reality_inbounds.json) -lt ${delUserIndex} ]]; then + echoContent red " ---> Wrong selection" + else + delUserIndex=$((delUserIndex - 1)) + local vlessRealityResult + uuid=$(jq -r ".inbounds[0].settings.clients[${delUserIndex}].id" ${configPath}${frontingType}.json) + vlessRealityResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}07_VLESS_vision_reality_inbounds.json) + echo "${vlessRealityResult}" | jq . >${configPath}07_VLESS_vision_reality_inbounds.json + fi + fi - 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 to delete [only single delete is supported]:" delUserIndex - if [[ $(jq -r '.inbounds[0].settings.clients|length' ${configPath}${frontingType}.json) -lt ${delUserIndex} ]]; then - echoContent red " ---> Selection error" - else - delUserIndex=$((delUserIndex - 1)) - local vlessTcpResult - vlessTcpResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${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 - 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 + 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 - 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 + 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 - 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 + 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 - 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 + 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 - 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 + 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 + 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 + if echo ${currentInstallProtocolType} | grep -q 7; then + local vlessRealityResult + vlessRealityResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}07_VLESS_vision_reality_inbounds.json) + echo "${vlessRealityResult}" | jq . >${configPath}07_VLESS_vision_reality_inbounds.json + fi + if echo ${currentInstallProtocolType} | grep -q 8; then + local vlessRealityGRPCResult + vlessRealityGRPCResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}08_VLESS_reality_fallback_grpc_inbounds.json) + echo "${vlessRealityGRPCResult}" | jq . >${configPath}08_VLESS_reality_fallback_grpc_inbounds.json + fi + + if echo ${currentInstallProtocolType} | grep -q 9; then + local tuicResult + tuicResult=$(jq -r "del(.users.\"${uuid}\")" "${tuicConfigPath}config.json") + echo "${tuicResult}" | jq . >"${tuicConfigPath}config.json" + fi + reloadCore + fi + manageAccount 1 } -# Updated script +# update script updateV2RayAgent() { - 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" - else - wget -c -q -P /etc/v2ray-agent/ -N --no-check-certificate "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/install.sh" - fi + 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 "${wgetShowProgressStatus}" -P /etc/v2ray-agent/ -N --no-check-certificate "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/install.sh" + #else + # wget -c -q -P /etc/v2ray-agent/ -N --no-check-certificate "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/install.sh" + #fi - sudo chmod 700 /etc/v2ray-agent/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}') + sudo chmod 700 /etc/v2ray-agent/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 + 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 fails, 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 +# firewall 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 closed successfully" + 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 closed successfully" - fi + fi - 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 closed successfully" - fi + 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 closed successfully" + fi } -# install BBR +# Install BBR bbrInstall() { - echoContent red "\n==============================================================" - 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 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 - menu - fi + echoContent red "\n================================================ =================" + echoContent green "The mature works of [ylx2016] used for BBR and DD scripts, the address [https://github.com/ylx2016/Linux-NetSpeed], please be familiar with it" + echoContent yellow "1.Installation script [recommended original BBR+FQ]" + echoContent yellow "2.Return to the home directory" + echoContent red "================================================== ===============" + 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 + menu + fi } # View and check logs checkLog() { - if [[ -z ${configPath} ]]; then - echoContent red " ---> No installation directory detected, please execute the script to install the content" - fi - local logStatus=false - if grep -q "access" ${configPath}00_log.json; then - logStatus=true - fi + if [[ -z "${configPath}" && -z "${realityStatus}" ]]; then + echoContent red " ---> The installation directory is not detected, please execute the script to install the content" + exit 0 + fi + local realityLogShow= + local logStatus=false + if grep -q "access" ${configPath}00_log.json; then + logStatus=true + fi - echoContent skyBlue "\nFunction $1/${totalProgress} : View log" - echoContent red "\n==============================================================" - echoContent yellow "# It is recommended to open access log only when debugging\n" + echoContent skyBlue "\nFunction$1/${totalProgress}: View log" + echoContent red "\n================================================ =================" + echoContent yellow "# It is recommended to only open the access log during debugging\n" - if [[ "${logStatus}" == "false" ]]; then - echoContent yellow "1.Open access log" - else - echoContent yellow "1.Close the access log" - fi + if [[ "${logStatus}" == "false" ]]; then + echoContent yellow "1.Open access log" + else + echoContent yellow "1.Close access log" + fi - 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.Clear the log" - echoContent red "==============================================================" + echoContent yellow "2.Monitor access log" + echoContent yellow "3.Monitor error log" + echoContent yellow "4.View certificate scheduled task log" + echoContent yellow "5.View certificate installation log" + echoContent yellow "6.Clear the log" + echoContent red "================================================== ===============" - read -r -p "Please select:" selectAccessLogType - local configPathLog=${configPath//conf\//} + read -r -p "Please select:" selectAccessLogType + local configPathLog=${configPath//conf\//} - case ${selectAccessLogType} in - 1) - if [[ "${logStatus}" == "false" ]]; then - cat <${configPath}00_log.json + case ${selectAccessLogType} in + 1) + if [[ "${logStatus}" == "false" ]]; then + realityLogShow=true + cat <${configPath}00_log.json { "log": { "access":"${configPathLog}access.log", @@ -4067,8 +5292,9 @@ checkLog() { } } EOF - elif [[ "${logStatus}" == "true" ]]; then - cat <${configPath}00_log.json + elif [[ "${logStatus}" == "true" ]]; then + realityLogShow=false + cat <${configPath}00_log.json { "log": { "error": "${configPathLog}error.log", @@ -4076,178 +5302,195 @@ EOF } } EOF - fi - reloadCore - checkLog 1 - ;; - 2) - tail -f ${configPathLog}access.log - ;; - 3) - tail -f ${configPathLog}error.log - ;; - 4) - tail -n 100 /etc/v2ray-agent/crontab_tls.log - ;; - 5) - tail -n 100 /etc/v2ray-agent/tls/acme.log - ;; - 6) - echo >${configPathLog}access.log - echo >${configPathLog}error.log - ;; - esac + fi + + if [[ -n ${realityStatus} ]]; then + local vlessVisionRealityInbounds + vlessVisionRealityInbounds=$(jq -r ".inbounds[0].streamSettings.realitySettings.show=${realityLogShow}" ${configPath}07_VLESS_vision_reality_inbounds.json) + echo "${vlessVisionRealityInbounds}" | jq . >${configPath}07_VLESS_vision_reality_inbounds.json + fi + reloadCore + checkLog 1 + ;; + 2) + tail -f ${configPathLog}access.log + ;; + 3) + tail -f ${configPathLog}error.log + ;; + 4) + if [[ ! -f "/etc/v2ray-agent/crontab_tls.log" ]]; then + touch /etc/v2ray-agent/crontab_tls.log + fi + tail -n 100 /etc/v2ray-agent/crontab_tls.log + ;; + 5) + tail -n 100 /etc/v2ray-agent/tls/acme.log + ;; + 6) + echo >${configPathLog}access.log + echo >${configPathLog}error.log + ;; + esac } # Script shortcut aliasInstall() { - 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 - ln -s /etc/v2ray-agent/install.sh /usr/bin/vasma - chmod 700 /usr/bin/vasma - vasmaType=true - fi + 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 + 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 - 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 "Shortcut created successfully, executable [vasma] to reopen the script" - fi - fi + rm -rf "$HOME/install.sh" + 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 "The shortcut is created successfully, you can execute [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 -n '1p' | sed 's/.*(//g;s/).*//g') + currentIPv6IP=$(curl -s -6 http://www.cloudflare.com/cdn-cgi/trace | grep "ip" | cut -d "=" -f 2) - if [[ -z "${pingIPv6}" ]]; then - echoContent red " ---> ipv6 is not supported" - exit 0 - fi + if [[ -z "${currentIPv6IP}" ]]; then + echoContent red " ---> does not support ipv6" + exit 0 + fi } # ipv6 offload ipv6Routing() { - if [[ -z "${configPath}" ]]; then - echoContent red " ---> Not installed, please use script to install" - menu - exit 0 - fi + if [[ -z "${configPath}" ]]; then + echoContent red " ---> Not installed, please use script to install" + menu + exit 0 + fi - checkIPv6 - echoContent skyBlue "\nFunction 1/${totalProgress} : IPv6 offload" - echoContent red "\n==============================================================" - echoContent yellow "1.Add domain name" - echoContent yellow "2.Uninstall IPv6 offload" - echoContent red "==============================================================" - read -r -p "Please select:" ipv6Status - if [[ "${ipv6Status}" == "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.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 + checkIPv6 + echoContent skyBlue "\nFunction 1/${totalProgress}: IPv6 offload" + echoContent red "\n================================================ ============ =====" + echoContent yellow "1.View the diverted domain name" + echoContent yellow "2.Add domain name" + echoContent yellow "3.Set IPv6 global" + echoContent yellow "4.Uninstall IPv6 offloading" + echoContent red "================================================== ===============" + read -r -p "Please select:" ipv6Status + if [[ "${ipv6Status}" == "1" ]]; then - if [[ -f "${configPath}09_routing.json" ]]; then + jq -r -c '.routing.rules[]|select (.outboundTag=="IPv6-out")|.domain' ${configPath}09_routing.json | jq -r + exit 0 + elif [[ "${ipv6Status}" == "2" ]]; then + echoContent red "================================================== ===============" + echoContent yellow "# Notes\n" + echoContent yellow "# Notes" + echoContent yellow "# Tutorial: https://www.v2ray-agent.com/archives/ba-he-yi-jiao-ben-yu-ming-fen-liu-jiao-cheng \n" - unInstallRouting IPv6-out outboundTag + read -r -p "Please enter the domain name according to the above example:" domainList + addInstallRouting IPv6-out outboundTag "${domainList}" - routing=$(jq -r ".routing.rules += [{\"type\":\"field\",\"domain\":[\"geosite:${domainList//,/\",\"geosite:}\"],\"outboundTag\":\"IPv6-out\"}]" ${configPath}09_routing.json) + unInstallOutbounds IPv6-out - echo "${routing}" | jq .>${configPath}09_routing.json + outbounds=$(jq -r '.outbounds += [{"protocol":"freedom","settings":{"domainStrategy":"UseIPv6"},"tag":"IPv6-out"}]' ${configPath}10_ipv4_outbounds.json) - else - cat <"${configPath}09_routing.json" -{ - "routing":{ - "domainStrategy": "IPOnDemand", - "rules": [ - { - "type": "field", - "domain": [ - "geosite:${domainList//,/\",\"geosite:}" - ], - "outboundTag": "IPv6-out" - } - ] - } -} + echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json + + echoContent green " ---> Added successfully" + + elif [[ "${ipv6Status}" == "3" ]]; then + echoContent red "================================================== ===============" + echoContent yellow "# Notes\n" + echoContent yellow "1.All diversion rules set will be deleted" + echoContent yellow "2.All outbound rules except IPv6 will be deleted" + read -r -p "Confirm settings? [y/n]:" IPv6OutStatus + + if [[ "${IPv6OutStatus}" == "y" ]]; then + cat <${configPath}10_ipv4_outbounds.json + { + "outbounds":[ + { + "protocol":"freedom", + "settings":{ + "domainStrategy":"UseIPv6" + }, + "tag":"IPv6-out" + } + ] + } EOF - fi + rm ${configPath}09_routing.json >/dev/null 2>&1 + echoContent green " ---> IPv6 global outbound setting successful" + else + echoContent green " ---> Abandon settings" + exit 0 + fi - unInstallOutbounds IPv6-out + elif [[ "${ipv6Status}" == "4" ]]; then - outbounds=$(jq -r '.outbounds += [{"protocol":"freedom","settings":{"domainStrategy":"UseIPv6"},"tag":"IPv6-out"}]' ${configPath}10_ipv4_outbounds.json) + unInstallRouting IPv6-out outboundTag - echo "${outbounds}" | jq .>${configPath}10_ipv4_outbounds.json + unInstallOutbounds IPv6-out - echoContent green " ---> Add successfully" + if ! grep -q "IPv4-out" <"${configPath}10_ipv4_outbounds.json"; then + outbounds=$(jq -r '.outbounds += [{"protocol":"freedom","settings": {"domainStrategy": "UseIPv4"},"tag":"IPv4-out"}]' ${configPath}10_ipv4_outbounds.json) - elif [[ "${ipv6Status}" == "2" ]]; then + echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json + fi + echoContent green " ---> IPv6 offload uninstall successful" + else + echoContent red " ---> Wrong selection" + exit 0 + fi - unInstallRouting IPv6-out outboundTag - - unInstallOutbounds IPv6-out - - echoContent green "---> IPv6 offloading succeeded" - else - echoContent red " ---> Selection error" - exit 0 - fi - - reloadCore + reloadCore } # bt download management btTools() { - if [[ -z "${configPath}" ]]; then - echoContent red " ---> Not installed, please use script to install" - menu - exit 0 - fi + if [[ -z "${configPath}" ]]; then + echoContent red " ---> Not installed, please use script to install" + menu + exit 0 + fi - echoContent skyBlue "\nFunction 1/${totalProgress} : bt download management" - echoContent red "\n==============================================================" + 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" - else - echoContent yellow "Current status: not disabled" - fi + 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 - echoContent yellow "1.Disable" - echoContent yellow "2.Open" - echoContent red "==============================================================" - read -r -p "Please select:" btStatus - if [[ "${btStatus}" == "1" ]]; then + echoContent yellow "1.Disable" + echoContent yellow "2.Open" + echoContent red "================================================== ===============" + 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 outboundTag + unInstallRouting blackhole-out outboundTag - routing=$(jq -r '.routing.rules += [{"type":"field","outboundTag":"blackhole-out","protocol":["bittorrent"]}]' ${configPath}09_routing.json) + 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 + else + cat <${configPath}09_routing.json { "routing":{ "domainStrategy": "IPOnDemand", @@ -4261,497 +5504,712 @@ btTools() { } } EOF - fi + fi - installSniffing + installSniffing - unInstallOutbounds blackhole-out + unInstallOutbounds blackhole-out - outbounds=$(jq -r '.outbounds += [{"protocol":"blackhole","tag":"blackhole-out"}]' ${configPath}10_ipv4_outbounds.json) + 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 successfully" + echoContent green " ---> BT download disabled successfully" - elif [[ "${btStatus}" == "2" ]]; then + elif [[ "${btStatus}" == "2" ]]; then - unInstallSniffing + unInstallSniffing - unInstallRouting blackhole-out outboundTag bittorrent + unInstallRouting blackhole-out outboundTag bittorrent - # unInstallOutbounds blackhole-out + # unInstallOutbounds blackhole-out - echoContent green " ---> BT download successfully opened" - else - echoContent red " ---> Selection error" - exit 0 - fi + echoContent green " ---> BT download opened successfully" + else + echoContent red " ---> Wrong selection" + exit 0 + fi - reloadCore + reloadCore } -# Domain blacklist +# Domain name blacklist blacklist() { - if [[ -z "${configPath}" ]]; then - echoContent red " ---> Not installed, please use script to install" - menu - exit 0 - fi + 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 + echoContent skyBlue "\nProgress$1/${totalProgress}: Domain name blacklist" + echoContent red "\n================================================ =================" + echoContent yellow "1.View blocked domain names" + echoContent yellow "2.Add domain name" + echoContent yellow "3.Block domestic domain names" + echoContent yellow "4.Delete blacklist" + echoContent red "================================================== ===============" - if [[ -f "${configPath}09_routing.json" ]]; then - unInstallRouting blackhole-out outboundTag + read -r -p "Please select:" blacklistStatus + if [[ "${blacklistStatus}" == "1" ]]; then + jq -r -c '.routing.rules[]|select (.outboundTag=="blackhole-out")|.domain' ${configPath}09_routing.json | jq -r + exit 0 + elif [[ "${blacklistStatus}" == "2" ]]; then + echoContent red "================================================== ===============" + echoContent yellow "# Notes\n" + echoContent yellow "1.Rules support predefined domain name list [https://github.com/v2fly/domain-list-community]" + echoContent yellow "2.Rules support custom domain names" + echoContent yellow "3.Input example: speedtest, facebook, cn, example.com" + echoContent yellow "4.If the domain name exists in the predefined domain name list, use geosite:xx. If it does not exist, the entered domain name will be used by default." + echoContent yellow "5.Add rules as incremental configuration and will not delete previously set content\n" + read -r -p "Please enter the domain name according to the above example:" domainList - routing=$(jq -r ".routing.rules += [{\"type\":\"field\",\"domain\":[\"geosite:${domainList//,/\",\"geosite:}\"],\"outboundTag\":\"blackhole-out\"}]" ${configPath}09_routing.json) + if [[ -f "${configPath}09_routing.json" ]]; then + addInstallRouting blackhole-out outboundTag "${domainList}" + fi + unInstallOutbounds blackhole-out - echo "${routing}" | jq .>${configPath}09_routing.json + outbounds=$(jq -r '.outbounds += [{"protocol":"blackhole","tag":"blackhole-out"}]' ${configPath}10_ipv4_outbounds.json) - else - cat <${configPath}09_routing.json + echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json + + echoContent green " ---> Added successfully" + + elif [[ "${blacklistStatus}" == "3" ]]; then + addInstallRouting blackhole-out outboundTag "cn" + + unInstallOutbounds blackhole-out + + outbounds=$(jq -r '.outbounds += [{"protocol":"blackhole","tag":"blackhole-out"}]' ${configPath}10_ipv4_outbounds.json) + + echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json + + echoContent green " ---> Domestic domain name blocked successfully" + + elif [[ "${blacklistStatus}" == "4" ]]; then + + unInstallRouting blackhole-out outboundTag + + echoContent green " ---> Domain name blacklist deleted successfully" + else + echoContent red " ---> Wrong selection" + exit 0 + fi + reloadCore +} +#Add routing configuration +addInstallRouting() { + + local tag=$1 # warp-socks + local type=$2 # outboundTag/inboundTag + local domain=$3 # Domain name + + if [[ -z "${tag}" || -z "${type}" || -z "${domain}" ]]; then + echoContent red " ---> Parameter error" + exit 0 + fi + + local routingRule= + if [[ ! -f "${configPath}09_routing.json" ]]; then + cat <${configPath}09_routing.json { "routing":{ - "domainStrategy": "IPOnDemand", + "type": "field", "rules": [ - { - "type": "field", - "domain": [ - "geosite:${domainList//,/\",\"geosite:}" - ], - "outboundTag": "blackhole-out" + { + "type": "field", + "domain": [ + ], + "outboundTag": "${tag}" } ] } } EOF - fi + fi + local routingRule= + routingRule=$(jq -r '.routing.rules[]|select(.outboundTag=="'"${tag}"'")' ${configPath}09_routing.json) + if [[ -z "${routingRule}" ]]; then + if [[ "${tag}" == "dokodemoDoor-80" ]]; then + routingRule="{\"type\": \"field\",\"port\": 80,\"domain\": [],\"outboundTag\": \"${tag}\"}" + elif [[ "${tag}" == "dokodemoDoor-443" ]]; then + routingRule="{\"type\": \"field\",\"port\": 443,\"domain\": [],\"outboundTag\": \"${tag}\"}" + else + routingRule="{\"type\": \"field\",\"domain\": [],\"outboundTag\": \"${tag}\"}" + fi + fi - echoContent green " ---> Add successfully" + while read -r line; do + if echo "${routingRule}" | grep -q "${line}"; then + echoContent yellow " ---> ${line} already exists, skip" + else + local geositeStatus + geositeStatus=$(curl -s "https://api.github.com/repos/v2fly/domain-list-community/contents/data/${line}" | jq .message) - elif [[ "${blacklistStatus}" == "2" ]]; then + if [[ "${geositeStatus}" == "null" ]]; then + routingRule=$(echo "${routingRule}" | jq -r '.domain += ["geosite:'"${line}"'"]') + else + routingRule=$(echo "${routingRule}" | jq -r '.domain += ["domain:'"${line}"'"]') + fi + fi + done < <(echo "${domain}" | tr ',' '\n') - unInstallRouting blackhole-out outboundTag + unInstallRouting "${tag}" "${type}" + if ! grep -q "gstatic.com" ${configPath}09_routing.json && [[ "${tag}" == "blackhole-out" ]]; then + local routing= + routing=$(jq -r ".routing.rules += [{\"type\": \"field\",\"domain\": [\"gstatic.com\"],\"outboundTag\": \"direct\"}]" ${configPath}09_routing.json) + echo "${routing}" | jq . >${configPath}09_routing.json + fi - echoContent green " ---> Domain name blacklist deleted successfully" - else - echoContent red " ---> Selection error" - exit 0 - fi - reloadCore + routing=$(jq -r ".routing.rules += [${routingRule}]" ${configPath}09_routing.json) + echo "${routing}" | jq . >${configPath}09_routing.json } - -# Uninstall Routing according to tag +# Uninstall Routing based on tag unInstallRouting() { - local tag=$1 - local type=$2 - local protocol=$3 + 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 + 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 + 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 + delStatus=1 + elif [[ "${type}" == "inboundTag" ]] && echo "${line}" | jq .inboundTag | grep -q "${tag}"; then + delStatus=1 + 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 [[ -n ${protocol} ]] && echo "${line}" | jq .protocol | grep -q "${protocol}"; then + delStatus=1 + elif [[ -z ${protocol} ]] && [[ $(echo "${line}" | jq .protocol) != "null" ]]; then + delStatus=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 + 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 } -# Uninstall outbound according to tag +# Uninstall outbound based on tag unInstallOutbounds() { - local tag=$1 + local tag=$1 - 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 + 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 sniffing +# 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 + find ${configPath} -name "*inbounds.json*" | awk -F "[c][o][n][f][/]" '{print $2}' | while read -r inbound; do + if grep -q "destOverride" <"${configPath}${inbound}"; then + sniffing=$(jq -r 'del(.inbounds[0].sniffing)' "${configPath}${inbound}") + echo "${sniffing}" | jq . >"${configPath}${inbound}" + fi + done + } -# install sniff +# Install sniffing 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 + readInstallType + find ${configPath} -name "*inbounds.json*" | awk -F "[c][o][n][f][/]" '{print $2}' | while read -r inbound; do + if ! grep -q "destOverride" <"${configPath}${inbound}"; then + sniffing=$(jq -r '.inbounds[0].sniffing = {"enabled":true,"destOverride":["http","tls"]}' "${configPath}${inbound}") + echo "${sniffing}" | jq . >"${configPath}${inbound}" + fi + done } -# warp triage +# warp diversion warpRouting() { - echoContent skyBlue "\nProgress $1/${totalProgress} : WARP diversion" - echoContent red "==============================================================" - # 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 is not installed, is it installed? [y/n]:" installCloudflareWarpStatus - if [[ "${installCloudflareWarpStatus}" == "y" ]]; then - installWarp - else - echoContent yellow " ---> Abort installation" - exit 0 - fi - fi + echoContent skyBlue "\nProgress$1/${totalProgress}: WARP offload" + echoContent red "==============================================================" + if [[ -z $(which warp-cli) ]]; then + echo + read -r -p "WARP is not installed. Do you want to install it? [y/n]:" installCloudflareWarpStatus + if [[ "${installCloudflareWarpStatus}" == "y" ]]; then + installWarp + else + echoContent yellow " ---> Abort installation" + exit 0 + fi + fi - echoContent red "\n==============================================================" - echoContent yellow "1.Add domain name" - echoContent yellow "2.Uninstall WARP offload" - echoContent red "==============================================================" - read -r -p "Please select:" warpStatus - if [[ "${warpStatus}" == "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.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 + echoContent red "\n================================================ =================" + echoContent yellow "1.View the diverted domain name" + echoContent yellow "2.Add domain name" + echoContent yellow "3.Set WARP global" + echoContent yellow "4.Uninstall WARP distribution" + echoContent red "================================================== ===============" + read -r -p "Please select:" warpStatus + if [[ "${warpStatus}" == "1" ]]; then + jq -r -c '.routing.rules[]|select (.outboundTag=="warp-socks-out")|.domain' ${configPath}09_routing.json | jq -r + exit 0 + elif [[ "${warpStatus}" == "2" ]]; then + echoContent yellow "# Notes" + echoContent yellow "# Tutorial: https://www.v2ray-agent.com/archives/ba-he-yi-jiao-ben-yu-ming-fen-liu-jiao-cheng \n" - if [[ -f "${configPath}09_routing.json" ]]; then - unInstallRouting warp-socks-out outboundTag + read -r -p "Please enter the domain name according to the above example:" domainList - routing=$(jq -r ".routing.rules += [{\"type\":\"field\",\"domain\":[\"geosite:${domainList//,/\",\"geosite:}\"],\"outboundTag\":\"warp-socks-out\"}]" ${configPath}09_routing.json) + addInstallRouting warp-socks-out outboundTag "${domainList}" - echo "${routing}" | jq .>${configPath}09_routing.json + unInstallOutbounds warp-socks-out - else - cat <${configPath}09_routing.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 + + echoContent green " ---> Added successfully" + + elif [[ "${warpStatus}" == "3" ]]; then + + echoContent red "================================================== ===============" + echoContent yellow "# Notes\n" + echoContent yellow "1.All diversion rules set will be deleted" + echoContent yellow "2.All outbound rules except WARP will be deleted" + read -r -p "Confirm settings? [y/n]:" warpOutStatus + + if [[ "${warpOutStatus}" == "y" ]]; then + cat <${configPath}10_ipv4_outbounds.json { - "routing":{ - "domainStrategy": "IPOnDemand", - "rules": [ - { - "type": "field", - "domain": [ - "geosite:${domainList//,/\",\"geosite:}" - ], - "outboundTag": "warp-socks-out" - } - ] - } +"outbounds":[ +{ +"protocol": "socks", +"settings": { +"servers": [ +{ +"address": "127.0.0.1", +"port": 31303 +} +] +}, +"tag": "warp-socks-out" +} +] } EOF - fi - unInstallOutbounds warp-socks-out + rm ${configPath}09_routing.json >/dev/null 2>&1 + echoContent green " ---> WARP global outbound setting successful" + else + echoContent green " ---> Abandon settings" + exit 0 + fi - 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) + elif [[ "${warpStatus}" == "4" ]]; then - echo "${outbounds}" | jq .>${configPath}10_ipv4_outbounds.json + ${removeType} cloudflare-warp >/dev/null 2>&1 - echoContent green " ---> Add successfully" + unInstallRouting warp-socks-out outboundTag - elif [[ "${warpStatus}" == "2" ]]; then + unInstallOutbounds warp-socks-out - ${removeType} cloudflare-warp >/dev/null 2>&1 + if ! grep -q "IPv4-out" <"${configPath}10_ipv4_outbounds.json"; then + outbounds=$(jq -r '.outbounds += [{"protocol":"freedom","settings": {"domainStrategy": "UseIPv4"},"tag":"IPv4-out"}]' ${configPath}10_ipv4_outbounds.json) - unInstallRouting warp-socks-out outboundTag + echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json + fi - unInstallOutbounds warp-socks-out - - echoContent green " ---> WARP offloading uninstalled successfully" - else - echoContent red " ---> Selection error" - exit 0 - fi - reloadCore + echoContent green " ---> WARP offload uninstall successful" + else + echoContent red " ---> Wrong selection" + exit 0 + fi + reloadCore } -# Streaming Toolbox + +# Read third-party warp configuration +readConfigWarpReg() { + if [[ ! -f "/etc/v2ray-agent/warp/config" ]]; then + /etc/v2ray-agent/warp/warp-reg >/etc/v2ray-agent/warp/config + fi + + secretKeyWarpReg=$(grep <"/etc/v2ray-agent/warp/config" private_key | awk '{print $2}') + + addressWarpReg=$(grep <"/etc/v2ray-agent/warp/config" v6 | awk '{print $2}') + + publicKeyWarpReg=$(grep <"/etc/v2ray-agent/warp/config" public_key | awk '{print $2}') + + reservedWarpReg=$(grep <"/etc/v2ray-agent/warp/config" reserved | awk -F "[:]" '{print $2}') + +} +# warp offload-third-party IPv4 +warpRoutingReg() { + local type=$2 + echoContent skyBlue "\nProgress$1/${totalProgress}: WARP offload [third party]" + echoContent red "================================================== ===============" + if [[ ! -f "/etc/v2ray-agent/warp/warp-reg" ]]; then + echo + echoContent yellow "# Notes" + echoContent yellow "# relies on third-party programs, please be aware of the risks" + echoContent yellow "# Project address: https://github.com/badafans/warp-reg \n" + + read -r -p "warp-reg is not installed, do you want to install it? [y/n]:" installWarpRegStatus + + if [[ "${installWarpRegStatus}" == "y" ]]; then + + curl -sLo /etc/v2ray-agent/warp/warp-reg "https://github.com/badafans/warp-reg/releases/download/v1.0/${warpRegCoreCPUVendor}" + chmod 655 /etc/v2ray-agent/warp/warp-reg + + else + echoContent yellow " ---> Abort installation" + exit 0 + fi + fi + echoContent red "\n================================================ =================" + echoContent yellow "1.View the diverted domain name" + echoContent yellow "2.Add domain name" + echoContent yellow "3.Set WARP global" + echoContent yellow "4.Uninstall WARP distribution" + echoContent red "================================================== ===============" + read -r -p "Please select:" warpStatus + + readConfigWarpReg + local address= + if [[ ${type} == "IPv4" ]]; then + address="172.16.0.2/32" + elif [[ ${type} == "IPv6" ]]; then + address="${addressWarpReg}/128" + else + echoContent red " ---> IP acquisition failed, exit installation" + fi + + if [[ "${warpStatus}" == "1" ]]; then + jq -r -c '.routing.rules[]|select (.outboundTag=="wireguard-out-'"${type}"'")|.domain' ${configPath}09_routing.json | jq -r + exit 0 + elif [[ "${warpStatus}" == "2" ]]; then + echoContent yellow "# Notes" + echoContent yellow "# Tutorial: https://www.v2ray-agent.com/archives/ba-he-yi-jiao-ben-yu-ming-fen-liu-jiao-cheng \n" + + read -r -p "Please enter the domain name according to the above example:" domainList + + addInstallRouting wireguard-out-"${type}" outboundTag "${domainList}" + + unInstallOutbounds wireguard-out-"${type}" + + local outbounds + outbounds=$(jq -r '.outbounds += [{"protocol":"wireguard","settings":{"secretKey":"'"${secretKeyWarpReg}"'","address":["'"${address}"'"],"peers":[{"publicKey":"'"${publicKeyWarpReg}"'","allowedIPs":["0.0.0.0/0","::/0"],"endpoint":"162.159.192.1:2408"}],"reserved":'"${reservedWarpReg}"',"mtu":1280},"tag":"wireguard-out-'"${type}"'"}]' ${configPath}10_ipv4_outbounds.json) + + echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json + + echoContent green " ---> Added successfully" + + elif [[ "${warpStatus}" == "3" ]]; then + + echoContent red "================================================== ===============" + echoContent yellow "# Notes\n" + echoContent yellow "1.All diversion rules set will be deleted" + echoContent yellow "2.All outbound rules except WARP [third party] will be deleted" + read -r -p "Confirm the settings? [y/n]:" warpOutStatus + + if [[ "${warpOutStatus}" == "y" ]]; then + readConfigWarpReg + + cat <${configPath}10_ipv4_outbounds.json +{ + "outbounds":[ + { + "protocol": "wireguard", + "settings": { + "secretKey": "${secretKeyWarpReg}", + "address": [ + "${address}" + ], + "peers": [ + { + "publicKey": "${publicKeyWarpReg}", + "allowedIPs": [ + "0.0.0.0/0", + "::/0" + ], + "endpoint": "162.159.192.1:2408" + } + ], + "reserved": ${reservedWarpReg}, + "mtu": 1280 + }, + "tag": "wireguard-out-${type}" + } + ] +} +EOF + rm ${configPath}09_routing.json >/dev/null 2>&1 + echoContent green " ---> WARP global outbound setting successful" + else + echoContent green " ---> Abandon settings" + exit 0 + fi + + elif [[ "${warpStatus}" == "4" ]]; then + + unInstallRouting wireguard-out-"${type}" outboundTag + + unInstallOutbounds wireguard-out-"${type}" + if [[ "${type}" == "IPv4" ]]; then + if ! grep -q "wireguard-out-IPv6" <${configPath}10_ipv4_outbounds.json; then + rm -rf /etc/v2ray-agent/warp/config >/dev/null 2>&1 + fi + elif [[ "${type}" == "IPv6" ]]; then + if ! grep -q "wireguard-out-IPv4" <${configPath}10_ipv4_outbounds.json; then + rm -rf /etc/v2ray-agent/warp/config >/dev/null 2>&1 + fi + fi + + if ! grep -q "IPv4-out" <"${configPath}10_ipv4_outbounds.json"; then + + cat <${configPath}10_ipv4_outbounds.json + { + "outbounds":[ + { + "protocol":"freedom", + "settings":{ + "domainStrategy":"UseIPv4" + }, + "tag":"IPv4-out" + }, + { + "protocol":"freedom", + "settings":{ + "domainStrategy":"UseIPv6" + }, + "tag":"IPv6-out" + }, + { + "protocol":"blackhole", + "tag":"blackhole-out" + } + ] + } +EOF + fi + + echoContent green " ---> WARP offload uninstall successful" + else + echoContent red " ---> Wrong selection" + exit 0 + fi + reloadCore +} + +# Diversion tool +routingToolsMenu() { + echoContent skyBlue "\nFunction 1/${totalProgress}: Diversion tool" + echoContent red "\n================================================ =================" + echoContent yellow "1.WARP diversion [Third-party IPv4]" + echoContent yellow "2.WARP diversion [Third-party IPv6]" + echoContent yellow "3.IPv6 offload" + echoContent yellow "4.Any door diversion" + echoContent yellow "5.DNS divert" + echoContent yellow "6.VMess+WS+TLS offload" + echoContent yellow "7.SNI reverse proxy offload" + + read -r -p "Please select:" selectType + + case ${selectType} in + 1) + warpRoutingReg 1 IPv4 + ;; + 2) + warpRoutingReg 1 IPv6 + ;; + 3) + ipv6Routing 1 + ;; + 4) + dokodemoDoorRouting 1 + ;; + 5) + dnsRouting 1 + ;; + 6) + vmessWSRouting 1 + ;; + 7) + sniRouting 1 + ;; + esac + +} +#Streaming Toolbox streamingToolbox() { - echoContent skyBlue "\nFunction 1/${totalProgress} : Streaming Toolbox" - echoContent red "\n==============================================================" - # 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 + echoContent skyBlue "\nFunction 1/${totalProgress}: Streaming Media Toolbox" + echoContent red "\n================================================ ============ =====" + echoContent yellow "1.Any door floor machine unlocks streaming media" + echoContent yellow "2.DNS unlock streaming media" + echoContent yellow "3.VMess+WS+TLS to unlock streaming media" + read -r -p "Please select:" selectType - case ${selectType} in - 1) - dokodemoDoorUnblockStreamingMedia - ;; - 2) - dnsUnlockNetflix - ;; - 3) - unblockVMessWSTLSStreamingMedia - ;; - esac + case ${selectType} in + 1) + dokodemoDoorRouting + ;; + 2) + dnsRouting + ;; + 3) + vmessWSRouting + ;; + esac } -# Arbitrary door unlock streaming -dokodemoDoorUnblockStreamingMedia() { - echoContent skyBlue "\nFunction 1/${totalProgress} : Unlock streaming media with any door landing machine" - echoContent red "\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" +#Any door unlock streaming +dokodemoDoorRouting() { + echoContent skyBlue "\nFunction 1/${totalProgress}: any door diversion" + echoContent red "\n================================================ =================" + echoContent yellow "# Notes" + echoContent yellow "# Tutorial: https://www.v2ray-agent.com/archives/ba-he-yi-jiao-ben-yu-ming-fen-liu-jiao-cheng \n" - echoContent yellow "1.Add outbound" - echoContent yellow "2.Add inbound" - echoContent yellow "3.Uninstall" - read -r -p "Please select:" selectType + echoContent yellow "1.Add outbound" + echoContent yellow "2.Add inbound" + echoContent yellow "3.Uninstall" + read -r -p "Please select:" selectType - case ${selectType} in - 1) - setDokodemoDoorUnblockStreamingMediaOutbounds - ;; - 2) - setDokodemoDoorUnblockStreamingMediaInbounds - ;; - 3) - removeDokodemoDoorUnblockStreamingMedia - ;; - esac + case ${selectType} in + 1) + setDokodemoDoorRoutingOutbounds + ;; + 2) + setDokodemoDoorRoutingInbounds + ;; + 3) + removeDokodemoDoorRouting + ;; + esac } -# 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" +# VMess+WS+TLS offload +vmessWSRouting() { + echoContent skyBlue "\nFunction 1/${totalProgress}: VMess+WS+TLS offload" + echoContent red "\n================================================ =================" + echoContent yellow "# Notes" + echoContent yellow "# Tutorial: https://www.v2ray-agent.com/archives/ba-he-yi-jiao-ben-yu-ming-fen-liu-jiao-cheng \n" - echoContent yellow "1.Add outbound" - echoContent yellow "2.Uninstall" - read -r -p "Please select:" selectType + echoContent yellow "1.Add outbound" + echoContent yellow "2.Uninstall" + read -r -p "Please select:" selectType - case ${selectType} in - 1) - setVMessWSTLSUnblockStreamingMediaOutbounds - ;; - 2) - removeVMessWSTLSUnblockStreamingMedia - ;; - esac + case ${selectType} in + 1) + setVMessWSRoutingOutbounds + ;; + 2) + removeVMessWSRouting + ;; + 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 +# Set VMess+WS+TLS [outbound only] +setVMessWSRoutingOutbounds() { + read -r -p "Please enter the address of VMess+WS+TLS:" setVMessWSTLSAddress + echoContent red "================================================== ===============" + echoContent yellow "Input example:netflix,openai\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 [[ -z ${domainList} ]]; then + echoContent red " ---> Domain name cannot be empty" + setVMessWSRoutingOutbounds + fi - if [[ -n "${setVMessWSTLSAddress}" ]]; then + if [[ -n "${setVMessWSTLSAddress}" ]]; then - unInstallOutbounds VMess-out + unInstallOutboundsVMess-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 + 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 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 + read -r -p "Please enter the Path of VMess+WS+TLS:" setVMessWSTLSPath + echo + if [[ -z "${setVMessWSTLSPath}" ]]; then + echoContent red " ---> The path cannot be empty" + elif ! echo "${setVMessWSTLSPath}" | grep -q "/"; then + setVMessWSTLSPath="/${setVMessWSTLSPath}" + 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) + 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 + 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 + addInstallRouting VMess-out outboundTag "${domainList}" + reloadCore + echoContent green " ---> Added shunt successfully" + exit 0 + fi + echoContent red " ---> The address cannot be empty" + setVMessWSRoutingOutbounds } -# 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 +# Set any door diversion [outbound] +setDokodemoDoorRoutingOutbounds() { + read -r -p "Please enter the IP of the target vps:" setIP + echoContent red "==============================================================" + echoContent yellow "Input example:netflix,openai\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 [[ -z ${domainList} ]]; then + echoContent red " ---> Domain name cannot be empty" + setDokodemoDoorRoutingOutbounds + fi - if [[ -n "${setIP}" ]]; then + if [[ -n "${setIP}" ]]; then - unInstallOutbounds streamingMedia-80 - unInstallOutbounds streamingMedia-443 + unInstallOutbounds dokodemoDoor-80 + unInstallOutbounds dokodemoDoor-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) + addInstallRouting dokodemoDoor-80 outboundTag "${domainList}" + addInstallRouting dokodemoDoor-443 outboundTag "${domainList}" - echo "${outbounds}" | jq .>${configPath}10_ipv4_outbounds.json + outbounds=$(jq -r ".outbounds += [{\"tag\":\"dokodemoDoor-80\",\"protocol\":\"freedom\",\"settings\":{\"domainStrategy\":\"AsIs\",\"redirect\":\"${setIP}:22387\"}},{\"tag\":\"dokodemoDoor-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 - - 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) - - echo "${routing}" | jq .>${configPath}09_routing.json - else - cat <${configPath}09_routing.json -{ - "routing": { - "domainStrategy": "AsIs", - "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" - } - ] - } -} -EOF - fi - reloadCore - echoContent green " ---> Add outbound unlock success" - exit 0 - fi - echoContent red " ---> ip cannot be empty" + reloadCore + echoContent green " ---> Add any door to divert successfully" + exit 0 + fi + echoContent red " ---> ip cannot be empty" } -# Set any door to unlock Netflix [inbound] -setDokodemoDoorUnblockStreamingMediaInbounds() { +# Set any door diversion [inbound] +setDokodemoDoorRoutingInbounds() { - echoContent skyBlue "\nFunction 1/${totalProgress} : add inbound to any door" - echoContent red "\n==============================================================" - 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 + echoContent skyBlue "\nFunction 1/${totalProgress}: Add inbound at any door" + echoContent red "\n================================================ =================" + echoContent yellow "ip entry example:1.1.1.1,1.1.1.2" + echoContent yellow "The domain name below must be consistent with the outbound vps" + echoContent yellow "Example of domain name entry: netflix,openai\n" + read -r -p "Please enter the IP allowed to access the 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 + cat <${configPath}01_dokodemoDoor_inbounds.json { "inbounds": [ { @@ -4770,7 +6228,7 @@ setDokodemoDoorUnblockStreamingMediaInbounds() { "http" ] }, - "tag": "streamingMedia-80" + "tag": "dokodemoDoor-80" }, { "listen": "0.0.0.0", @@ -4788,231 +6246,284 @@ setDokodemoDoorUnblockStreamingMediaInbounds() { "tls" ] }, - "tag": "streamingMedia-443" + "tag": "dokodemoDoor-443" } ] } EOF + local domains= + domains=[] + while read -r line; do + local geositeStatus + geositeStatus=$(curl -s "https://api.github.com/repos/v2fly/domain-list-community/contents/data/${line}" | jq .message) - cat <${configPath}10_ipv4_outbounds.json + if [[ "${geositeStatus}" == "null" ]]; then + domains=$(echo "${domains}" | jq -r '. += ["geosite:'"${line}"'"]') + else + domains=$(echo "${domains}" | jq -r '. += ["domain:'"${line}"'"]') + fi + done < <(echo "${domainList}" | tr ',' '\n') + + if [[ -f "${configPath}09_routing.json" ]]; then + unInstallRouting dokodemoDoor-80 inboundTag + unInstallRouting dokodemoDoor-443 inboundTag + + local routing + routing=$(jq -r ".routing.rules += [{\"source\":[\"${setIPs//,/\",\"}\"],\"domains\":${domains},\"type\":\"field\",\"inboundTag\":[\"dokodemoDoor-80\",\"dokodemoDoor-443\"],\"outboundTag\":\"direct\"},{\"type\":\"field\",\"inboundTag\":[\"dokodemoDoor-80\",\"dokodemoDoor-443\"],\"outboundTag\":\"blackhole-out\"}]" ${configPath}09_routing.json) + echo "${routing}" | jq . >${configPath}09_routing.json + else + + cat <${configPath}09_routing.json { - "outbounds":[ - { - "protocol":"freedom", - "settings":{ - "domainStrategy":"UseIPv4" - }, - "tag":"IPv4-out" - }, - { - "protocol":"freedom", - "settings":{ - "domainStrategy":"UseIPv6" - }, - "tag":"IPv6-out" - }, - { - "protocol":"blackhole", - "tag":"blackhole-out" - } + "routing": { + "rules": [ + { + "source": [ + "${setIPs//,/\",\"}" + ], + "domains":${domains}, + "type": "field", + "inboundTag": [ + "dokodemoDoor-80", + "dokodemoDoor-443" + ], + "outboundTag": "direct" + }, + { + "type": "field", + "inboundTag": [ + "dokodemoDoor-80", + "dokodemoDoor-443" + ], + "outboundTag": "blackhole-out" + } ] + } } EOF - if [[ -f "${configPath}09_routing.json" ]]; then - unInstallRouting streamingMedia-80 inboundTag - unInstallRouting streamingMedia-443 inboundTag + fi - 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 - - fi - - reloadCore - echoContent green " ---> Add landing machine inbound unlock successfully" - exit 0 - fi - echoContent red " ---> ip cannot be empty" + reloadCore + echoContent green " ---> Added landing machine inbound traffic successfully" + exit 0 + fi + echoContent red " ---> ip cannot be empty" } -# Remove any door to unlock Netflix -removeDokodemoDoorUnblockStreamingMedia() { +# Remove any door shunt +removeDokodemoDoorRouting() { - unInstallOutbounds streamingMedia-80 - unInstallOutbounds streamingMedia-443 + unInstallOutbounds dokodemoDoor-80 + unInstallOutbounds dokodemoDoor-443 - unInstallRouting streamingMedia-80 inboundTag - unInstallRouting streamingMedia-443 inboundTag + unInstallRouting dokodemoDoor-80 inboundTag + unInstallRouting dokodemoDoor-443 inboundTag - unInstallRouting streamingMedia-80 outboundTag - unInstallRouting streamingMedia-443 outboundTag + unInstallRouting dokodemoDoor-80 outboundTag + unInstallRouting dokodemoDoor-443 outboundTag - rm -rf ${configPath}01_netflix_inbounds.json + rm -rf ${configPath}01_dokodemoDoor_inbounds.json - reloadCore - echoContent green " ---> Uninstall successful" + reloadCore + echoContent green " ---> Uninstall successful" } -# Remove VMess+WS+TLS to unlock streaming -removeVMessWSTLSUnblockStreamingMedia() { +# Remove VMess+WS+TLS shunt +removeVMessWSRouting() { - unInstallOutbounds VMess-out + unInstallOutbounds VMess-out - unInstallRouting VMess-out outboundTag + unInstallRouting VMess-out outboundTag - reloadCore - echoContent green " ---> Uninstall successful" + reloadCore + echoContent green " ---> Uninstall successful" } -# restart the core +# Restart core reloadCore() { - if [[ "${coreInstallType}" == "1" ]]; then - handleXray stop - handleXray start - elif [[ "${coreInstallType}" == "2" || "${coreInstallType}" == "3" ]]; then - handleV2Ray stop - handleV2Ray start - fi + readInstallType - if [[ -n "${hysteriaConfigPath}" ]]; then - handleHysteria stop - handleHysteria start - fi + if [[ "${coreInstallType}" == "1" ]]; then + handleXray stop + handleXray start + elif [[ "${coreInstallType}" == "2" ]]; then + handleV2Ray stop + handleV2Ray start + fi + + if [[ -n "${hysteriaConfigPath}" ]]; then + handleHysteria stop + handleHysteria start + fi + + if [[ -n "${tuicConfigPath}" ]]; then + handleTuic stop + handleTuic start + fi } -# dns unblock Netflix -dnsUnlockNetflix() { - 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" - echoContent yellow "2.Uninstall" - read -r -p "Please select:" selectType +# dns divert +dnsRouting() { - case ${selectType} in - 1) - setUnlockDNS - ;; - 2) - removeUnlockDNS - ;; - esac + if [[ -z "${configPath}" ]]; then + echoContent red " ---> Not installed, please use script to install" + menu + exit 0 + fi + echoContent skyBlue "\nFunction 1/${totalProgress}: DNS offloading" + echoContent red "\n================================================ =================" + echoContent yellow "# Notes" + echoContent yellow "# Tutorial: https://www.v2ray-agent.com/archives/ba-he-yi-jiao-ben-yu-ming-fen-liu-jiao-cheng \n" + + echoContent yellow "1.Add" + echoContent yellow "2.Uninstall" + read -r -p "Please select:" selectType + + case ${selectType} in + 1) + setUnlockDNS + ;; + 2) + removeUnlockDNS + ;; + esac } -# set dns +# SNI reverse proxy offload +sniRouting() { + + if [[ -z "${configPath}" ]]; then + echoContent red " ---> Not installed, please use script to install" + menu + exit 0 + fi + echoContent skyBlue "\nFunction 1/${totalProgress}: SNI reverse proxy offload" + echoContent red "\n================================================ =================" + echoContent yellow "# Notes" + echoContent yellow "# Tutorial: https://www.v2ray-agent.com/archives/ba-he-yi-jiao-ben-yu-ming-fen-liu-jiao-cheng \n" + + echoContent yellow "1.Add" + echoContent yellow "2.Uninstall" + read -r -p "Please select:" selectType + + case ${selectType} in + 1) + setUnlockSNI + ;; + 2) + removeUnlockSNI + ;; + esac +} +# Set up SNI offloading +setUnlockSNI() { + read -r -p "Please enter the SNI IP of the offload:" setSNIP + if [[ -n ${setSNIP} ]]; then + echoContent red "================================================== ===============" + echoContent yellow "Input example: netflix, disney, hulu" + read -r -p "Please enter the domain name according to the above example:" domainList + + if [[ -n "${domainList}" ]]; then + local hosts={} + while read -r domain; do + hosts=$(echo "${hosts}" | jq -r ".\"geosite:${domain}\"=\"${setSNIP}\"") + done < <(echo "${domainList}" | tr ',' '\n') + cat <${configPath}11_dns.json +{ + "dns": { + "hosts":${hosts}, + "servers": [ + "8.8.8.8", + "1.1.1.1" + ] + } +} +EOF + echoContent red " ---> SNI reverse proxy distribution successful" + reloadCore + else + echoContent red " ---> Domain name cannot be empty" + fi + + else + + echoContent red " ---> SNI IP cannot be empty" + fi + exit 0 +} +# Set dns setUnlockDNS() { - read -r -p "Please enter Unblock Streaming DNS:" setDNS - if [[ -n ${setDNS} ]]; 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: 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 + read -r -p "Please enter the diverted DNS:" setDNS + if [[ -n ${setDNS} ]]; then + echoContent red "================================================== ===============" + echoContent yellow "Input example: netflix, disney, hulu" + echoContent yellow "Please enter 1 for the default scheme. The default scheme includes the following content" + 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": [ { - "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" - ] - } - } + "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" - ] - } - } + elif [[ -n "${domainList}" ]]; then + cat <${configPath}11_dns.json +{ + "dns": { + "servers": [ + { + "address": "${setDNS}", + "port": 53, + "domains": [ + "geosite:${domainList//,/\",\"geosite:}" + ] + }, + "localhost" + ] + } +} EOF - fi + fi - reloadCore + reloadCore - 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" - fi - exit 0 + echoContent yellow "\n ---> If you still can't watch, you can try the following two solutions" + echoContent yellow "1.Restart vps" + echoContent yellow "2.After uninstalling dns unlocking, modify the local [/etc/resolv.conf] DNS settings and restart vps\n" + else + echoContent red " ---> dns cannot be empty" + fi + exit 0 } -# remove Netflix unblock +# Remove DNS offloading removeUnlockDNS() { - cat <${configPath}11_dns.json + cat <${configPath}11_dns.json { "dns": { "servers": [ @@ -5021,527 +6532,1480 @@ removeUnlockDNS() { } } EOF - reloadCore + reloadCore - echoContent green " ---> Uninstall successful" + echoContent green " ---> Uninstall successful" - exit 0 + exit 0 +} + +# Remove SNI shunt +removeUnlockSNI() { + cat <${configPath}11_dns.json +{ + "dns": { + "servers": [ + "localhost" + ] + } +} +EOF + reloadCore + + echoContent green " ---> Uninstall successful" + + exit 0 } # v2ray-core personalized installation customV2RayInstall() { - 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" - echoContent yellow "5.VLESS+TLS+gRPC[CDN]" - read -r -p "Please select [multiple choices], [eg: 123]:" selectCustomInstallType - echoContent skyBlue "--------------------------------------------------------------" - if [[ -z ${selectCustomInstallType} ]]; then - selectCustomInstallType=0 - fi - if [[ "${selectCustomInstallType}" =~ ^[0-5]+$ ]]; then - cleanUp xrayClean - totalProgress=17 - installTools 1 - # 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 - fi - nginxBlog 7 - updateRedirectNginxConf - handleNginx start + echoContent skyBlue "\n========================Personalized installation================== ==========" + echoContent yellow "VLESS is prefixed and 0 is installed by default. If you only need to install 0, just select 0" + echoContent yellow "0.VLESS+TLS_Vision+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+TLS" + echoContent yellow "5.VLESS+TLS+gRPC[CDN]" + read -r -p "Please select [multiple selection], [for example: 123]:" selectCustomInstallType + echoContent skyBlue "------------------------------------------------- ---------------" + if [[ -z ${selectCustomInstallType} ]]; then + selectCustomInstallType=0 + fi + if [[ "${selectCustomInstallType}" =~ ^[0-5]+$ ]]; then + cleanUp xrayClean + checkBTPanel + totalProgress=17 + installTools 1 + # 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 + fi + nginxBlog 7 + updateRedirectNginxConf + handleNginx start - # Install V2Ray - installV2Ray 8 - installV2RayService 9 - initV2RayConfig custom 10 - cleanUp xrayDel - installCronTLS 14 - handleV2Ray stop - handleV2Ray start - # generate account - checkGFWStatue 15 - showAccounts 16 - else - echoContent red " ---> Invalid input" - customV2RayInstall - fi + # Install V2Ray + installV2Ray 8 + installV2RayService 9 + initV2RayConfig custom 10 + cleanUp xrayDel + installCronTLS 14 + handleV2Ray stop + handleV2Ray start + # Generate account + checkGFWStatue 15 + showAccounts 16 + else + echoContent red " ---> Input is illegal" + customV2RayInstall + fi } # Xray-core personalized installation customXrayInstall() { - 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" - echoContent yellow "5.VLESS+TLS+gRPC[CDN]" - read -r -p "Please select [multiple choices], [eg: 123]:" selectCustomInstallType - echoContent skyBlue "--------------------------------------------------------------" - if [[ -z ${selectCustomInstallType} ]]; then - echoContent red " ---> cannot be empty" - customXrayInstall - elif [[ "${selectCustomInstallType}" =~ ^[0-5]+$ ]]; then - cleanUp v2rayClean - totalProgress=17 - installTools 1 - # apply for tls - initTLSNginxConfig 2 - handleXray stop - handleNginx start - checkIP + echoContent skyBlue "\n========================Personalized installation================== ==========" + echoContent yellow "VLESS is prefixed and 0 is installed by default. If you only need to install 0, just select 0" + echoContent yellow "0.VLESS+TLS_Vision+TCP[recommended]" + 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+TLS" + echoContent yellow "5.VLESS+TLS+gRPC[CDN]" + echoContent yellow "7.VLESS+Reality+uTLS+Vision[recommended]" + # echoContent yellow "8.VLESS+Reality+gRPC" + read -r -p "Please select [multiple selection], [for example: 123]:" selectCustomInstallType + echoContent skyBlue "------------------------------------------------- --------- ------" + if [[ -z ${selectCustomInstallType} ]]; then + echoContent red " ---> cannot be empty" + customXrayInstall + elif [[ "${selectCustomInstallType}" =~ ^[0-7]+$ ]]; then - 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 - fi - nginxBlog 7 - updateRedirectNginxConf - handleNginx start + if ! echo "${selectCustomInstallType}" | grep -q "0"; then + selectCustomInstallType="0${selectCustomInstallType}" + fi + cleanUp v2rayClean + checkBTPanel + totalProgress=12 + installTools 1 + if [[ -n "${btDomain}" ]]; then + echoContent skyBlue "\nProgress 3/${totalProgress}: Pagoda panel detected, skip applying for TLS" + handleXray stop + customPortFunction + else + # Apply for tls + initTLSNginxConfig 2 + handleXray stop + # handleNginx start + installTLS 3 + fi - # Install V2Ray - installXray 8 - installXrayService 9 - initXrayConfig custom 10 - cleanUp v2rayDel + 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 4 + customCDNIP 5 + fi + if [[ -n "${btDomain}" ]]; then + echoContent skyBlue "\nProgress 6/${totalProgress}: Pagoda panel detected, skipping disguised website" + # echoContent red "============================================== ================" + # echoContent yellow "# Notes" + # echoContent yellow "The static directory under the currently installed website will be cleared. If it has been customized, please select [n]\n" + # read -r -p "Please select [y/n]:" nginxBlogBTStatus + # if [[ "${nginxBlogBTStatus}" == "y" ]]; then + #nginxBlog 6 + #fi + else + nginxBlog 6 + fi + updateRedirectNginxConf + handleNginx start - installCronTLS 14 - handleXray stop - handleXray start - # generate account - checkGFWStatue 15 - showAccounts 16 - else - echoContent red " ---> Invalid input" - customXrayInstall - fi + # Install Xray + installXray 7 false + installXrayService 8 + initXrayConfig custom 9 + cleanUp v2rayDel + + installCronTLS 10 + handleXray stop + handleXray start + # Generate account + checkGFWStatue 11 + showAccounts 12 + else + echoContent red " ---> Input is illegal" + customXrayInstall + fi } # Select core installation---v2ray-core, xray-core selectCoreInstall() { - 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 select:" selectCoreType - case ${selectCoreType} in - 1) - if [[ "${selectInstallType}" == "2" ]]; then - customXrayInstall - else - xrayCoreInstall - fi - ;; - 2) - v2rayCoreVersion= - if [[ "${selectInstallType}" == "2" ]]; then - customV2RayInstall - else - v2rayCoreInstall - fi - ;; - 3) - v2rayCoreVersion=v4.32.1 - if [[ "${selectInstallType}" == "2" ]]; then - customV2RayInstall - else - v2rayCoreInstall - fi - ;; - *) - echoContent red ' ---> selection error, re-select' - selectCoreInstall - ;; - esac + 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 select:" selectCoreType + case ${selectCoreType} in + 1) + if [[ "${selectInstallType}" == "2" ]]; then + customXrayInstall + else + xrayCoreInstall + fi + ;; + 2) + v2rayCoreVersion= + echoContent red " ---> Since v2ray does not support many new features, maintenance is now discontinued in order to reduce development costs. It is recommended to use Xray-core, hysteria, and Tuic" + exit 0 + if [[ "${selectInstallType}" == "2" ]]; then + customV2RayInstall + else + v2rayCoreInstall + fi + ;; + 3) + v2rayCoreVersion=v4.32.1 + if [[ "${selectInstallType}" == "2" ]]; then + customV2RayInstall + else + v2rayCoreInstall + fi + ;; + *) + echoContent red ' ---> Wrong selection, select again' + selectCoreInstall + ;; + esac } -# v2ray-core install +# v2ray-core installation v2rayCoreInstall() { - cleanUp xrayClean - selectCustomInstallType= - totalProgress=13 - installTools 2 - # apply for tls - initTLSNginxConfig 3 + cleanUp xrayClean + checkBTPanel + selectCustomInstallType= + totalProgress=13 + installTools 2 + # Apply for tls + initTLSNginxConfig 3 - handleV2Ray stop - handleNginx start - checkIP + handleV2Ray stop + handleNginx start - installTLS 4 - handleNginx stop - # initNginxConfig 5 - randomPathFunction 5 - # Install V2Ray - installV2Ray 6 - installV2RayService 7 - customCDNIP 8 - initV2RayConfig all 9 - cleanUp xrayDel - installCronTLS 10 - nginxBlog 11 - updateRedirectNginxConf - handleV2Ray stop - sleep 2 - handleV2Ray start - handleNginx start - # generate account - checkGFWStatue 12 - showAccounts 13 + installTLS 4 + handleNginx stop + randomPathFunction 5 + # Install V2Ray + installV2Ray 6 + installV2RayService 7 + customCDNIP 8 + initV2RayConfig all 9 + cleanUp xrayDel + installCronTLS 10 + nginxBlog 11 + updateRedirectNginxConf + handleV2Ray stop + sleep 2 + handleV2Ray start + handleNginx start + # Generate account + checkGFWStatue 12 + showAccounts 13 } -# xray-core install +# xray-core installation xrayCoreInstall() { - cleanUp v2rayClean - selectCustomInstallType= - totalProgress=13 - installTools 2 - # apply for tls - initTLSNginxConfig 3 + cleanUp v2rayClean + checkBTPanel + selectCustomInstallType= + totalProgress=13 + installTools 2 + if [[ -n "${btDomain}" ]]; then + echoContent skyBlue "\nProgress 3/${totalProgress}: Pagoda panel detected, skip applying for TLS" + handleXray stop + customPortFunction + else + # Apply for tls + initTLSNginxConfig 3 + handleXray stop + # handleNginx start - handleXray stop - handleNginx start - checkIP + installTLS 4 + fi - installTLS 4 - handleNginx stop - randomPathFunction 5 - # install Xray - # handleV2Ray stop - installXray 6 - installXrayService 7 - customCDNIP 8 - initXrayConfig all 9 - cleanUp v2rayDel - installCronTLS 10 - nginxBlog 11 - updateRedirectNginxConf - handleXray stop - sleep 2 - handleXray start + handleNginx stop + randomPathFunction 5 + # Install Xray + installXray 6 false + installXrayService 7 + customCDNIP 8 + initXrayConfig all 9 + cleanUp v2rayDel + installCronTLS 10 + if [[ -n "${btDomain}" ]]; then + echoContent skyBlue "\nProgress 11/${totalProgress}: Pagoda panel detected, skipping disguised website" + # echoContent red "============================================== ================" + # echoContent yellow "# Notes" + # echoContent yellow "The static directory under the currently installed website will be cleared. If it has been customized, please select [n]\n" + # read -r -p "Please select [y/n]:" nginxBlogBTStatus + # if [[ "${nginxBlogBTStatus}" == "y" ]]; then + #nginxBlog 11 + #fi + else + nginxBlog 11 + fi + updateRedirectNginxConf + handleXray stop + sleep 2 + handleXray start - handleNginx start - # generate account - checkGFWStatue 12 - showAccounts 13 + handleNginx start + # Generate account + checkGFWStatue 12 + showAccounts 13 } -# Hysteria installation + +#HysteriaInstallation 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 + if ! echo "${currentInstallProtocolType}" | grep -q "0" || [[ -z "${coreInstallType}" ]]; then + echoContent red "\n ---> Due to environmental dependencies, if you install hysteria, please install Xray-core's VLESS_TCP_TLS_Vision first" + exit 0 + fi + totalProgress=5 + installHysteria 1 + initHysteriaConfig 2 + installHysteriaService 3 + reloadCore + showAccounts 4 } -# uninstall hysteria +# 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" + if [[ -z "${hysteriaConfigPath}" ]]; then + echoContent red "\n ---> not installed" + exit 0 + fi + deleteHysteriaPortHoppingRules + handleHysteria stop + rm -rf /etc/v2ray-agent/hysteria/* + rm ${configPath}02_socks_inbounds_hysteria.json + rm -rf /etc/systemd/system/hysteria.service + echoContent green " ---> Uninstall completed" +} +# Uninstall Tuic +unInstallTuicCore() { + + if [[ -z "${tuicConfigPath}" ]]; then + echoContent red "\n ---> not installed" + exit 0 + fi + handleTuic stop + rm -rf /etc/v2ray-agent/tuic/* + rm -rf /etc/systemd/system/tuic.service + echoContent green " ---> Uninstall completed" +} +unInstallXrayCoreReality() { + + if [[ -z "${realityStatus}" ]]; then + echoContent red "\n ---> not installed" + exit 0 + fi + echoContent skyBlue "\nFunction 1/1: reality uninstall" + echoContent red "\n================================================ =================" + echoContent yellow "# Only delete VLESS Reality related configurations, other content will not be deleted." + echoContent yellow "# If you need to uninstall other content, please uninstall the script function" + handleXray stop + rm /etc/v2ray-agent/xray/conf/07_VLESS_vision_reality_inbounds.json + rm /etc/v2ray-agent/xray/conf/08_VLESS_reality_fallback_grpc_inbounds.json + echoContent green " ---> Uninstall completed" } -# Core management +# Core Management coreVersionManageMenu() { - if [[ -z "${coreInstallType}" ]]; then - echoContent red "\n ---> No installation directory detected, please execute the script to install the content" - menu - exit 0 - fi - if [[ "${coreInstallType}" == "1" ]]; then - xrayVersionManageMenu 1 - elif [[ "${coreInstallType}" == "2" ]]; then - v2rayCoreVersion= - v2rayVersionManageMenu 1 - - elif [[ "${coreInstallType}" == "3" ]]; then - v2rayCoreVersion=v4.32.1 - v2rayVersionManageMenu 1 - fi + if [[ -z "${coreInstallType}" ]]; then + echoContent red "\n >The installation directory is not detected, please execute the script to install the content" + menu + exit 0 + fi + if [[ "${coreInstallType}" == "1" ]]; then + xrayVersionManageMenu 1 + elif [[ "${coreInstallType}" == "2" ]]; then + v2rayCoreVersion= + v2rayVersionManageMenu 1 + fi } -# cron task check certificate -cronRenewTLS() { - if [[ "${renewTLS}" == "RenewTLS" ]]; then - renewalTLS - exit 0 - fi +# Scheduled task check +cronFunction() { + if [[ "${cronName}" == "RenewTLS" ]]; then + renewalTLS + exit 0 + elif [[ "${cronName}" == "UpdateGeo" ]]; then + updateGeoSite >>/etc/v2ray-agent/crontab_updateGeoSite.log + echoContent green " ---> geo update date: $(date "+%F %H:%M:%S")" >>/etc/v2ray-agent/crontab_updateGeoSite.log + exit 0 + fi } -# Account management +#Account management manageAccount() { - echoContent skyBlue "\nFunction 1/${totalProgress} : Account Management" - echoContent red "\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 subscription" - echoContent yellow "3.Add user" - echoContent yellow "4.Delete user" - echoContent red "==============================================================" - read -r -p "Please enter:" manageAccountStatus - if [[ "${manageAccountStatus}" == "1" ]]; then - showAccounts 1 - elif [[ "${manageAccountStatus}" == "2" ]]; then - subscribe 1 - elif [[ "${manageAccountStatus}" == "3" ]]; then - addUser - elif [[ "${manageAccountStatus}" == "4" ]]; then - removeUser - else - echoContent red " ---> Selection error" - fi + echoContent skyBlue "\nFunction 1/${totalProgress}: Account Management" + if [[ -z "${configPath}" ]]; then + echoContent red " ---> not installed" + exit 0 + fi + + echoContent red "\n================================================ =================" + echoContent yellow "# You can customize email and uuid when adding a single user" + echoContent yellow "# If Hysteria or Tuic is installed, the account will be added to the corresponding type at the same time\n" + echoContent yellow "1.Check account" + echoContent yellow "2.View subscription" + echoContent yellow "3.Add subscription" + echoContent yellow "4.Add user" + echoContent yellow "5.Delete user" + echoContent red "================================================== ===============" + read -r -p "Please enter:" manageAccountStatus + if [[ "${manageAccountStatus}" == "1" ]]; then + showAccounts 1 + elif [[ "${manageAccountStatus}" == "2" ]]; then + subscribe + elif [[ "${manageAccountStatus}" == "3" ]]; then + addSubscribeMenu 1 + elif [[ "${manageAccountStatus}" == "4" ]]; then + addUserXray + elif [[ "${manageAccountStatus}" == "5" ]]; then + removeUser + else + echoContent red " ---> Wrong selection" + fi } -# subscribe +#Add subscription +addSubscribeMenu() { + echoContent skyBlue "\n====================== Add other machine subscriptions==================== ===" + echoContent yellow "1.Add" + echoContent yellow "2.Remove" + echoContent red "================================================== ===============" + read -r -p "Please select:" addSubscribeStatus + if [[ "${addSubscribeStatus}" == "1" ]]; then + addOtherSubscribe + elif [[ "${addSubscribeStatus}" == "2" ]]; then + rm -rf /etc/v2ray-agent/subscribe_remote/clashMeta/* + rm -rf /etc/v2ray-agent/subscribe_remote/default/* + echo >/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl + echoContent green " ---> Other machine subscriptions were deleted successfully" + subscribe + fi +} +# Add other machines to clashMeta subscription +addOtherSubscribe() { + echoContent yellow "#Notes:" + echoContent yellow "Please read the following article carefully: https://www.v2ray-agent.com/archives/1681804748677" + echoContent skyBlue "Input example: www.v2ray-agent.com:443:vps1\n" + read -r -p "Please enter the domain name, port and machine alias:" remoteSubscribeUrl + if [[ -z "${remoteSubscribeUrl}" ]]; then + echoContent red " ---> cannot be empty" + addSubscribe + elif ! echo "${remoteSubscribeUrl}" | grep -q ":"; then + echoContent red " ---> Rule is illegal" + else + echo "${remoteSubscribeUrl}" >>/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl + local remoteUrl= + remoteUrl=$(echo "${remoteSubscribeUrl}" | awk -F "[:]" '{print $1":"$2}') + + local serverAlias= + serverAlias=$(echo "${remoteSubscribeUrl}" | awk -F "[:]" '{print $3}') + + if [[ -n $(ls /etc/v2ray-agent/subscribe/clashMeta/) || -n $(ls /etc/v2ray-agent/subscribe/default/) ]]; then + find /etc/v2ray-agent/subscribe_local/default/* | while read -r email; do + email=$(echo "${email}" | awk -F "[d][e][f][a][u][l][t][/]" '{print $2}') + + local emailMd5= + emailMd5=$(echo -n "${email}$(cat "/etc/v2ray-agent/subscribe_local/subscribeSalt")"$'\n' | md5sum | awk '{print $1}') + + local clashMetaProxies= + clashMetaProxies=$(curl -s -4 "https://${remoteUrl}/s/clashMeta/${emailMd5}" | sed '/proxies:/d' | sed "s/${email}/${email}_${serverAlias}/g") + + local default= + default=$(curl -s -4 "https://${remoteUrl}/s/default/${emailMd5}" | base64 -d | sed "s/${email}/${email}_${serverAlias}/g") + + if echo "${default}" | grep -q "${email}"; then + echo "${default}" >>"/etc/v2ray-agent/subscribe/default/${emailMd5}" + echo "${default}" >>"/etc/v2ray-agent/subscribe_remote/default/${email}" + + echoContent green " ---> Universal subscription ${email} added successfully" + else + echoContent red " ---> Universal subscription ${email} does not exist" + fi + + if echo "${clashMetaProxies}" | grep -q "${email}"; then + echo "${clashMetaProxies}" >>"/etc/v2ray-agent/subscribe/clashMeta/${emailMd5}" + echo "${clashMetaProxies}" >>"/etc/v2ray-agent/subscribe_remote/clashMeta/${email}" + + echoContent green " ---> clashMeta subscription ${email} added successfully" + else + echoContent red " ---> clashMeta subscription ${email} does not exist" + fi + done + else + echoContent red " ---> Please check the subscription first and then add the subscription" + fi + fi +} +# clashMeta configuration file +clashMetaConfig() { + local url=$1 + local id=$2 + cat <"/etc/v2ray-agent/subscribe/clashMetaProfiles/${id}" +mixed-port: 7890 +unified-delay: false +geodata-mode: true +tcp-concurrent: false +find-process-mode: strict +global-client-fingerprint: chrome + +allow-lan: true +mode: rule +log-level: info +ipv6: true + +external-controller: 127.0.0.1:9090 + +geox-url: + geoip: "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.dat" + geosite: "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat" + mmdb: "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/country.mmdb" + +profile: + store-selected: true + store-fake-ip: true + +sniffer: + enable: false + sniff: + TLS: + ports: [443] + HTTP: + ports: [80] + override-destination: true + +tun: + enable: true + stack: system + dns-hijack: + - 'any:53' + auto-route: true + auto-detect-interface: true + +dns: + enable: true + listen: 0.0.0.0:1053 + ipv6: true + enhanced-mode: fake-ip + fake-ip-range: 28.0.0.1/8 + fake-ip-filter: + - '*' + - '+.lan' + default-nameserver: + - 223.5.5.5 + nameserver: + - 'tls://8.8.4.4#DNS_Proxy' + - 'tls://1.0.0.1#DNS_Proxy' + proxy-server-nameserver: + - https://dns.alidns.com/dns-query#h3=true + nameserver-policy: + "geosite:cn,private": + - 223.5.5.5 + - 114.114.114.114 + - https://dns.alidns.com/dns-query#h3=true + +proxy-providers: + ${subscribeSalt}_provider: + type: http + path: ./${subscribeSalt}_provider.yaml + url: ${url} + interval: 3600 + health-check: + enable: false + url: http://www.gstatic.com/generate_204 + interval: 300 + +proxy-groups: + - name: 节点选择 + type: select + use: + - ${subscribeSalt}_provider + proxies: + - 手动切换 + - 自动选择 + - 故障转移 + - 负载均衡 + - DIRECT + - name: 流媒体 + type: select + use: + - ${subscribeSalt}_provider + proxies: + - 手动切换 + - 自动选择 + - 故障转移 + - 负载均衡 + - DIRECT + - name: 手动切换 + type: select + use: + - ${subscribeSalt}_provider + proxies: null + - name: 自动选择 + type: url-test + url: http://www.gstatic.com/generate_204 + interval: 36000 + tolerance: 50 + use: + - ${subscribeSalt}_provider + proxies: null + - name: 故障转移 + type: fallback + url: http://www.gstatic.com/generate_204 + interval: 300 + tolerance: 50 + use: + - ${subscribeSalt}_provider + proxies: + - 自动选择 + - name: 负载均衡 + type: load-balance + url: http://www.gstatic.com/generate_204 + interval: 300 + tolerance: 50 + use: + - ${subscribeSalt}_provider + proxies: null + - name: 全球代理 + type: select + use: + - ${subscribeSalt}_provider + proxies: + - 手动切换 + - 自动选择 + - name: DNS_Proxy + type: select + use: + - ${subscribeSalt}_provider + proxies: + - 自动选择 + - 节点选择 + - DIRECT + + - name: Telegram + type: select + use: + - ${subscribeSalt}_provider + proxies: + - 手动切换 + - 自动选择 + + - name: YouTube + type: select + use: + - ${subscribeSalt}_provider + proxies: + - 手动切换 + - 自动选择 + - name: Netflix + type: select + use: + - ${subscribeSalt}_provider + proxies: + - 流媒体 + - 节点选择 + - 自动选择 + - name: HBO + type: select + use: + - ${subscribeSalt}_provider + proxies: + - 流媒体 + - 节点选择 + - 自动选择 + - name: Bing + type: select + use: + - ${subscribeSalt}_provider + proxies: + - 节点选择 + - 自动选择 + - name: OpenAI + type: select + use: + - ${subscribeSalt}_provider + proxies: + - 节点选择 + - 自动选择 + - name: Disney + type: select + use: + - ${subscribeSalt}_provider + proxies: + - 流媒体 + - 节点选择 + - 自动选择 + - name: GitHub + type: select + use: + - ${subscribeSalt}_provider + proxies: + - 手动切换 + - 自动选择 + - DIRECT + - name: Spotify + type: select + use: + - ${subscribeSalt}_provider + proxies: + - 流媒体 + - 手动切换 + - 自动选择 + - DIRECT + - name: Google + type: select + use: + - ${subscribeSalt}_provider + proxies: + - 手动切换 + - 自动选择 + - DIRECT + - name: 国内媒体 + type: select + use: + - ${subscribeSalt}_provider + proxies: + - DIRECT + - name: 本地直连 + type: select + use: + - ${subscribeSalt}_provider + proxies: + - DIRECT + - 节点选择 + - 自动选择 + - name: 漏网之鱼 + type: select + use: + - ${subscribeSalt}_provider + proxies: + - DIRECT + - 节点选择 + - 手动切换 + - 自动选择 +rule-providers: + lan: + type: http + behavior: classical + interval: 86400 + url: https://ghproxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/Lan/Lan.yaml + path: ./Rules/lan.yaml + reject: + type: http + behavior: domain + url: https://ghproxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/reject.txt + path: ./ruleset/reject.yaml + interval: 86400 + proxy: + type: http + behavior: domain + url: https://ghproxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/proxy.txt + path: ./ruleset/proxy.yaml + interval: 86400 + direct: + type: http + behavior: domain + url: https://ghproxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/direct.txt + path: ./ruleset/direct.yaml + interval: 86400 + private: + type: http + behavior: domain + url: https://ghproxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/private.txt + path: ./ruleset/private.yaml + interval: 86400 + gfw: + type: http + behavior: domain + url: https://ghproxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/gfw.txt + path: ./ruleset/gfw.yaml + interval: 86400 + greatfire: + type: http + behavior: domain + url: https://ghproxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/greatfire.txt + path: ./ruleset/greatfire.yaml + interval: 86400 + tld-not-cn: + type: http + behavior: domain + url: https://ghproxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/tld-not-cn.txt + path: ./ruleset/tld-not-cn.yaml + interval: 86400 + telegramcidr: + type: http + behavior: ipcidr + url: https://ghproxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/telegramcidr.txt + path: ./ruleset/telegramcidr.yaml + interval: 86400 + applications: + type: http + behavior: classical + url: https://ghproxy.com/https://raw.githubusercontent.com/Loyalsoldier/clash-rules/release/applications.txt + path: ./ruleset/applications.yaml + interval: 86400 + Disney: + type: http + behavior: classical + url: https://ghproxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/Disney/Disney.yaml + path: ./ruleset/disney.yaml + interval: 86400 + Netflix: + type: http + behavior: classical + url: https://ghproxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/Netflix/Netflix.yaml + path: ./ruleset/netflix.yaml + interval: 86400 + YouTube: + type: http + behavior: classical + url: https://ghproxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/YouTube/YouTube.yaml + path: ./ruleset/youtube.yaml + interval: 86400 + HBO: + type: http + behavior: classical + url: https://ghproxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/HBO/HBO.yaml + path: ./ruleset/hbo.yaml + interval: 86400 + OpenAI: + type: http + behavior: classical + url: https://ghproxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/OpenAI/OpenAI.yaml + path: ./ruleset/openai.yaml + interval: 86400 + Bing: + type: http + behavior: classical + url: https://ghproxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/Bing/Bing.yaml + path: ./ruleset/bing.yaml + interval: 86400 + Google: + type: http + behavior: classical + url: https://ghproxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/Google/Google.yaml + path: ./ruleset/google.yaml + interval: 86400 + GitHub: + type: http + behavior: classical + url: https://ghproxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/GitHub/GitHub.yaml + path: ./ruleset/github.yaml + interval: 86400 + Spotify: + type: http + behavior: classical + url: https://ghproxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/Spotify/Spotify.yaml + path: ./ruleset/spotify.yaml + interval: 86400 + ChinaMaxDomain: + type: http + behavior: domain + interval: 86400 + url: https://ghproxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/ChinaMax/ChinaMax_Domain.yaml + path: ./Rules/ChinaMaxDomain.yaml + ChinaMaxIPNoIPv6: + type: http + behavior: ipcidr + interval: 86400 + url: https://ghproxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/ChinaMax/ChinaMax_IP_No_IPv6.yaml + path: ./Rules/ChinaMaxIPNoIPv6.yaml +rules: + - RULE-SET,YouTube,YouTube,no-resolve + - RULE-SET,Google,Google,no-resolve + - RULE-SET,GitHub,GitHub + - RULE-SET,telegramcidr,Telegram,no-resolve + - RULE-SET,Spotify,Spotify,no-resolve + - RULE-SET,Netflix,Netflix + - RULE-SET,HBO,HBO + - RULE-SET,Bing,Bing + - RULE-SET,OpenAI,OpenAI + - RULE-SET,Disney,Disney + - RULE-SET,proxy,全球代理 + - RULE-SET,gfw,全球代理 + - RULE-SET,applications,本地直连 + - RULE-SET,ChinaMaxDomain,本地直连 + - RULE-SET,ChinaMaxIPNoIPv6,本地直连,no-resolve + - RULE-SET,lan,本地直连,no-resolve + - GEOIP,CN,本地直连 + - MATCH,漏网之鱼 +EOF + +} +# Random salt +initRandomSalt() { + local chars="abcdefghijklmnopqrtuxyz" + local initCustomPath= + for i in {1..10}; do + echo "${i}" >/dev/null + initCustomPath+="${chars:RANDOM%${#chars}:1}" + done + echo "${initCustomPath}" +} +# Subscribe subscribe() { - if [[ -n "${configPath}" ]]; then - 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/ + readInstallProtocolType - 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}') + if echo "${currentInstallProtocolType}" | grep -q 0 && [[ -n "${configPath}" ]]; then - local base64Result - base64Result=$(base64 -w 0 "/etc/v2ray-agent/subscribe/${email}") - echo "${base64Result}" >"/etc/v2ray-agent/subscribe/${email}" - echoContent skyBlue "--------------------------------------------------------------" - echoContent yellow "email:${email}\n" - local currentDomain=${currentHost} + echoContent skyBlue "-------------------------Remarks--------------------- ----------" + echoContent yellow "# Viewing subscriptions will regenerate local account subscriptions" + echoContent yellow "# When adding an account or modifying an account, you need to re-check the subscription before the subscription content for external access will be regenerated" + echoContent red "# You need to manually enter the md5 encrypted salt value. If you don't know, just use random" + echoContent yellow "# Does not affect the content of added remote subscriptions\n" - if [[ -n "${currentDefaultPort}" && "${currentDefaultPort}" != "443" ]]; then - currentDomain="${currentHost}:${currentDefaultPort}" - fi + if [[ -f "/etc/v2ray-agent/subscribe_local/subscribeSalt" && -n $(cat "/etc/v2ray-agent/subscribe_local/subscribeSalt") ]]; then + read -r -p "Read the Salt set by the last installation. Do you want to use the Salt generated last time? [y/n]:" historySaltStatus + if [[ "${historySaltStatus}" == "y" ]]; then + subscribeSalt=$(cat /etc/v2ray-agent/subscribe_local/subscribeSalt) + else + read -r -p "Please enter the salt value, [Enter] use random:" subscribeSalt + fi + else + read -r -p "Please enter the salt value, [Enter] use random:" subscribeSalt + 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" - fi + if [[ -z "${subscribeSalt}" ]]; then + subscribeSalt=$(initRandomSalt) + fi + echoContent yellow "\n ---> Salt: ${subscribeSalt}" + + echo "${subscribeSalt}" >/etc/v2ray-agent/subscribe_local/subscribeSalt + + rm -rf /etc/v2ray-agent/subscribe/default/* + rm -rf /etc/v2ray-agent/subscribe/clashMeta/* + rm -rf /etc/v2ray-agent/subscribe_local/default/* + rm -rf /etc/v2ray-agent/subscribe_local/clashMeta/* + showAccounts >/dev/null + + if [[ -n $(ls /etc/v2ray-agent/subscribe_local/default/) ]]; then + find /etc/v2ray-agent/subscribe_local/default/* | while read -r email; do + email=$(echo "${email}" | awk -F "[d][e][f][a][u][l][t][/]" '{print $2}') + # md5 encryption + local emailMd5= + emailMd5=$(echo -n "${email}${subscribeSalt}"$'\n' | md5sum | awk '{print $1}') + + cat "/etc/v2ray-agent/subscribe_local/default/${email}" >>"/etc/v2ray-agent/subscribe/default/${emailMd5}" + + if [[ -f "/etc/v2ray-agent/subscribe_remote/default/${email}" ]]; then + echo >"/etc/v2ray-agent/subscribe_remote/default/${email}_tmp" + while read -r remoteUrl; do + updateRemoteSubscribe "${emailMd5}" "${email}" "${remoteUrl}" "default" + done < <(grep "VLESS_TCP/TLS_Vision" <"/etc/v2ray-agent/subscribe_remote/default/${email}" | awk -F "@" '{print $2}' | awk -F "?" '{print $1}') + + echo >"/etc/v2ray-agent/subscribe_remote/default/${email}" + cat "/etc/v2ray-agent/subscribe_remote/default/${email}_tmp" >"/etc/v2ray-agent/subscribe_remote/default/${email}" + cat "/etc/v2ray-agent/subscribe_remote/default/${email}" >>"/etc/v2ray-agent/subscribe/default/${emailMd5}" + fi + + local base64Result + base64Result=$(base64 -w 0 "/etc/v2ray-agent/subscribe/default/${emailMd5}") + echo "${base64Result}" >"/etc/v2ray-agent/subscribe/default/${emailMd5}" + + echoContent yellow "--------------------------------------------------------------" + local currentDomain=${currentHost} + + if [[ -n "${currentDefaultPort}" && "${currentDefaultPort}" != "443" ]]; then + currentDomain="${currentHost}:${currentDefaultPort}" + fi + echoContent skyBlue "\n----------Default subscription----------\n" + echoContent green "email:${email}\n" + echoContent yellow "url:https://${currentDomain}/s/default/${emailMd5}\n" + echoContent yellow "Online QR code: https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=https://${currentDomain}/s/default/${emailMd5}\n " + echo "https://${currentDomain}/s/default/${emailMd5}" | qrencode -s 10 -m 1 -t UTF8 + + #clashMeta + if [[ -f "/etc/v2ray-agent/subscribe_local/clashMeta/${email}" ]]; then + + cat "/etc/v2ray-agent/subscribe_local/clashMeta/${email}" >>"/etc/v2ray-agent/subscribe/clashMeta/${emailMd5}" + + if [[ -f "/etc/v2ray-agent/subscribe_remote/clashMeta/${email}" ]]; then + echo >"/etc/v2ray-agent/subscribe_remote/clashMeta/${email}_tmp" + while read -r remoteUrl; do + updateRemoteSubscribe "${emailMd5}" "${email}" "${remoteUrl}" "ClashMeta" + done < <(grep -A3 "VLESS_TCP/TLS_Vision" <"/etc/v2ray-agent/subscribe_remote/clashMeta/${email}" | awk '/server:|port:/ {print $2}' | paste -d ':' - -) + echo >"/etc/v2ray-agent/subscribe_remote/clashMeta/${email}" + cat "/etc/v2ray-agent/subscribe_remote/clashMeta/${email}_tmp" >"/etc/v2ray-agent/subscribe_remote/clashMeta/${email}" + cat "/etc/v2ray-agent/subscribe_remote/clashMeta/${email}" >>"/etc/v2ray-agent/subscribe/clashMeta/${emailMd5}" + fi + + sed -i '1i\proxies:' "/etc/v2ray-agent/subscribe/clashMeta/${emailMd5}" + + local clashProxyUrl="https://${currentDomain}/s/clashMeta/${emailMd5}" + clashMetaConfig "${clashProxyUrl}" "${emailMd5}" + echoContent skyBlue "\n----------clashMeta subscription----------\n" + echoContent yellow "url:https://${currentDomain}/s/clashMetaProfiles/${emailMd5}\n" + echoContent yellow "Online QR code: https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=https://${currentDomain}/s/clashMetaProfiles/${emailMd5}\n " + echo "https://${currentDomain}/s/clashMetaProfiles/${emailMd5}" | qrencode -s 10 -m 1 -t UTF8 + fi + + echoContent skyBlue "------------------------------------------------- ---------------" + done + fi + else + echoContent red " ---> The disguise site is not installed and the subscription service cannot be used" + fi } -# toggle alpn +# Update remote subscription +updateRemoteSubscribe() { + local emailMD5=$1 + local email=$2 + local remoteUrl=$3 + local type=$4 + local remoteDomain= + remoteDomain=$(echo "${remoteUrl}" | awk -F ":" '{print $1}') + local serverAlias= + serverAlias=$(grep "${remoteDomain}" <"/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl" | awk -F ":" '{print $3}') + + if [[ "${type}" == "ClashMeta" ]]; then + local clashMetaProxies= + clashMetaProxies=$(curl -s -4 "https://${remoteUrl}/s/clashMeta/${emailMD5}" | sed '/proxies:/d' | sed "s/${email}/${email}_${serverAlias}/g") + if echo "${clashMetaProxies}" | grep -q "${email}"; then + echo "${clashMetaProxies}" >>"/etc/v2ray-agent/subscribe_remote/clashMeta/${email}_tmp" + + echoContent green " ---> clashMeta subscription ${remoteDomain}:${email} updated successfully" + else + echoContent red " ---> clashMeta subscription ${remoteDomain}:${email} does not exist" + fi + elif [[ "${type}" == "default" ]]; then + local default= + default=$(curl -s -4 "https://${remoteUrl}/s/default/${emailMD5}" | base64 -d | sed "s/${email}/${email}_${serverAlias}/g") + if echo "${default}" | grep -q "${email}"; then + echo "${default}" >>"/etc/v2ray-agent/subscribe_remote/default/${email}_tmp" + + echoContent green " ---> Universal subscription ${remoteDomain}:${email} updated successfully" + else + echoContent red " ---> Universal subscription ${remoteDomain}:${email} does not exist" + fi + fi +} + +# switch 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 skyBlue "\nFunction 1/${totalProgress}: switch alpn" + if [[ -z ${currentAlpn} ]]; then + echoContent red " ---> Unable to read alpn, please check whether 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 "==============================================================" + echoContent red "\n================================================ =================" + echoContent green "The first bit of the current alpn is: ${currentAlpn}" + echoContent yellow "1.When http/1.1 is the first, trojan is available, and some gRPC clients are available [the client supports manual selection of alpn]" + echoContent yellow "2.When h2 is the first, gRPC is available, and some trojan clients are available [the client supports manual selection of alpn]" + echoContent yellow "3.If the client does not support manual alpn replacement, it is recommended to use this function to change the server alpn order 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 + if [[ "${currentAlpn}" == "http/1.1" ]]; then + echoContent yellow "1.Switch alpn h2 first" + elif [[ "${currentAlpn}" == "h2" ]]; then + echoContent yellow "1.Switch alpn http/1.1 first" + else + echoContent red 'does not comply' + fi - echoContent red "==============================================================" + echoContent red "================================================== ===============" - read -r -p "Please select:" selectSwitchAlpnType - if [[ "${selectSwitchAlpnType}" == "1" && "${currentAlpn}" == "http/1.1" ]]; then + 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 + local frontingTypeJSON + frontingTypeJSON=$(jq -r ".inbounds[0].streamSettings.tlsSettings.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 + elif [[ "${selectSwitchAlpnType}" == "1" && "${currentAlpn}" == "h2" ]]; then + local frontingTypeJSON + frontingTypeJSON=$(jq -r ".inbounds[0].streamSettings.tlsSettings.alpn =[\"http/1.1\",\"h2\"]" ${configPath}${frontingType}.json) + echo "${frontingTypeJSON}" | jq . >${configPath}${frontingType}.json + else + echoContent red " ---> Wrong selection" + exit 0 + fi + reloadCore } -#hysteria management +#Initialize realityKey +initRealityKey() { + echoContent skyBlue "\n========================== Generate key ================= =========\n" + if [[ -n "${currentRealityPublicKey}" ]]; then + read -r -p "Read the last installation record. Do you want to use the PublicKey/PrivateKey from the last installation? [y/n]:" historyKeyStatus + if [[ "${historyKeyStatus}" == "y" ]]; then + realityPrivateKey=${currentRealityPrivateKey} + realityPublicKey=${currentRealityPublicKey} + fi + fi + if [[ -z "${realityPrivateKey}" ]]; then + realityX25519Key=$(/etc/v2ray-agent/xray/xray x25519) + realityPrivateKey=$(echo "${realityX25519Key}" | head -1 | awk '{print $3}') + realityPublicKey=$(echo "${realityX25519Key}" | tail -n 1 | awk '{print $3}') + fi + echoContent green "\n privateKey:${realityPrivateKey}" + echoContent green "\n publicKey:${realityPublicKey}" +} +# Check whether the reality domain name matches +checkRealityDest() { + local traceResult= + traceResult=$(curl -s "https://$(echo "${realityDestDomain}" | cut -d ':' -f 1)/cdn-cgi/trace" | grep "visit_scheme=https") + if [[ -n "${traceResult}" ]]; then + echoContent red "\n ---> The domain name used is detected, hosted on cloudflare and the proxy is enabled. Using this type of domain name may cause VPS traffic to be used by others [not recommended]\n" + read -r -p "Continue? [y/n]" setRealityDestStatus + if [[ "${setRealityDestStatus}" != 'y' ]]; then + exit 0 + fi + echoContent yellow "\n --->Ignore the risks and continue using" + fi +} + +#Initialize reality dest +initRealityDest() { + if [[ -n "${domain}" ]]; then + realityDestDomain=${domain}:${port} + else + local realityDestDomainList= + realityDestDomainList="gateway.icloud.com,itunes.apple.com,swdist.apple.com,swcdn.apple.com,updates.cdn-apple.com,mensura.cdn-apple.com,osxapps.itunes.apple.com,aod.itunes.apple.com,download-installer.cdn.mozilla.net,addons.mozilla.org,s0.awsstatic.com,d1.awsstatic.com,images-na.ssl-images-amazon.com,m.media-amazon.com,player.live-video.net,one-piece.com,lol.secure.dyn.riotcdn.net,www.lovelive-anime.jp,www.nokia.com,auth.riotgames.com,xsso.riotgames.com,csgo.com" + + echoContent skyBlue "\n====== Generate a domain name with fallback configuration , for example : [addons.mozilla.org:443] ======\n" + echoContent green "Fallback domain name list: https://www.v2ray-agent.com/archives/1680104902581#heading-8\n" + read -r -p "Please enter [Enter] to use random:" realityDestDomain + if [[ -z "${realityDestDomain}" ]]; then + local randomNum= + randomNum=$((RANDOM % 24 + 1)) + realityDestDomain=$(echo "${realityDestDomainList}" | awk -F ',' -v randomNum="$randomNum" '{print $randomNum":443"}') + + fi + if ! echo "${realityDestDomain}" | grep -q ":"; then + echoContent red "\n ---> The domain name does not comply with the standard, please re-enter" + initRealityDest + else + checkRealityDest + echoContent yellow "\n ---> Fallback domain name: ${realityDestDomain}" + fi + fi +} +# Initialize the ServersName available to the client +initRealityClientServersName() { + if [[ -n "${domain}" ]]; then + realityServerNames=\"${domain}\" + elif [[ -n "${realityDestDomain}" ]]; then + realityServerNames=$(echo "${realityDestDomain}" | cut -d ":" -f 1) + + realityServerNames=\"${realityServerNames//,/\",\"}\" + else + echoContent skyBlue "\n================ Configure serverNames available to the client ================\n" + echoContent yellow "#Notes" + echoContent green "List of serverNames available to the client: https://www.v2ray-agent.com/archives/1680104902581#heading-8\n" + echoContent yellow "Input example: addons.mozilla.org\n" + read -r -p "Please enter [Enter] to use random:" realityServerNames + if [[ -z "${realityServerNames}" ]]; then + realityServerNames=\"addons.mozilla.org\" + else + realityServerNames=\"${realityServerNames//,/\",\"}\" + fi + fi + + echoContent yellow "\n ---> Available client domain names: ${realityServerNames}\n" +} +#Initialize the reality port +initRealityPort() { + if [[ -n "${currentRealityPort}" ]]; then + read -r -p "Read the last installation record. Do you want to use the port from the last installation? [y/n]:" historyRealityPortStatus + if [[ "${historyRealityPortStatus}" == "y" ]]; then + realityPort=${currentRealityPort} + fi + fi + # todo Read the VLESS_TLS_Vision port and prompt whether to use it. There may be ambiguity here + if [[ -z "${realityPort}" ]]; then + if [[ -n "${port}" ]]; then + read -r -p "Do you use TLS+Vision port? [y/n]:" realityPortTLSVisionStatus + if [[ "${realityPortTLSVisionStatus}" == "y" ]]; then + realityPort=${port} + fi + fi + if [[ -z "${realityPort}" ]]; then + echoContent yellow "Please enter the port [Enter random 10000-30000]" + read -r -p "port:" realityPort + if [[ -z "${realityPort}" ]]; then + realityPort=$((RANDOM % 20001 + 10000)) + fi + fi + if [[ -n "${realityPort}" && "${currentRealityPort}" == "${realityPort}" ]]; then + handleXray stop + else + checkPort "${realityPort}" + # if [[ -n "${port}" && "${port}" == "${realityPort}" ]]; then + # echoContent red "The port cannot be the same as Vision--->" + # echo + #realityPort= + #fi + fi + fi + if [[ -z "${realityPort}" ]]; then + initRealityPort + else + allowPort "${realityPort}" + echoContent yellow "\n ---> Port: ${realityPort}" + fi + +} +#Initialize reality configuration +initXrayRealityConfig() { + echoContent skyBlue "\nProgress$1/${totalProgress}: Initializing Xray-core reality configuration" + initRealityPort + initRealityKey + initRealityDest + initRealityClientServersName +} +# Modify reality domain name port and other information +updateXrayRealityConfig() { + + local realityVisionResult + realityVisionResult=$(jq -r ".inbounds[0].port = ${realityPort}" ${configPath}07_VLESS_vision_reality_inbounds.json) + realityVisionResult=$(echo "${realityVisionResult}" | jq -r ".inbounds[0].streamSettings.realitySettings.dest = \"${realityDestDomain}\"") + realityVisionResult=$(echo "${realityVisionResult}" | jq -r ".inbounds[0].streamSettings.realitySettings.serverNames = [${realityServerNames}]") + realityVisionResult=$(echo "${realityVisionResult}" | jq -r ".inbounds[0].streamSettings.realitySettings.privateKey = \"${realityPrivateKey}\"") + realityVisionResult=$(echo "${realityVisionResult}" | jq -r ".inbounds[0].streamSettings.realitySettings.publicKey = \"${realityPublicKey}\"") + echo "${realityVisionResult}" | jq . >${configPath}07_VLESS_vision_reality_inbounds.json + reloadCore + echoContent green " ---> Modification completed" +} +# xray-core Reality installation +xrayCoreRealityInstall() { + totalProgress=13 + installTools 2 + # Download core + # prereleaseStatus=true + #updateXray + installXray 3 false + # Generate privateKey, configure fallback address, and configure serverNames + installXrayService 6 + # initXrayRealityConfig 5 + #Initialize configuration + initXrayConfig custom 7 + handleXray stop + cleanUp v2rayClean + sleep 2 + # start up + handleXray start + # Generate account + showAccounts 8 +} +#realitymanagement +manageReality() { + + echoContent skyBlue "\nProgress 1/1: reality management" + echoContent red "\n================================================ =================" + + if [[ -n "${realityStatus}" ]]; then + echoContent yellow "1.Reinstall" + echoContent yellow "2.Uninstall" + echoContent yellow "3.Change configuration" + else + echoContent yellow "1.Installation" + fi + echoContent red "================================================== ===============" + read -r -p "Please select:" installRealityStatus + + if [[ "${installRealityStatus}" == "1" ]]; then + selectCustomInstallType="7" + xrayCoreRealityInstall + elif [[ "${installRealityStatus}" == "2" ]]; then + unInstallXrayCoreReality + elif [[ "${installRealityStatus}" == "3" ]]; then + initXrayRealityConfig 1 + updateXrayRealityConfig + fi +} + +# hysteriaadmin 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.Port jump management" + echoContent yellow "4.core management" + echoContent yellow "5.View log" + hysteriaStatus=true + else + echoContent yellow "1.Installation" + fi - 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 + hysteriaPortHoppingMenu + elif [[ "${installHysteriaStatus}" == "4" && "${hysteriaStatus}" == "true" ]]; then + hysteriaVersionManageMenu 1 + elif [[ "${installHysteriaStatus}" == "5" && "${hysteriaStatus}" == "true" ]]; then + journalctl -fu hysteria + 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 +#tuicadmin +manageTuic() { + echoContent skyBlue "\nProgress 1/1: Tuic Management" + echoContent red "\n================================================ =================" + local tuicStatus= + if [[ -n "${tuicConfigPath}" ]]; then + echoContent yellow "1.Reinstall" + echoContent yellow "2.Uninstall" + echoContent yellow "3.core management" + echoContent yellow "4.View log" + tuicStatus=true + else + echoContent yellow "1.Installation" + fi + + echoContent red "================================================== ===============" + read -r -p "Please select:" installTuicStatus + if [[ "${installTuicStatus}" == "1" ]]; then + tuicCoreInstall + elif [[ "${installTuicStatus}" == "2" && "${tuicStatus}" == "true" ]]; then + unInstallTuicCore + elif [[ "${installTuicStatus}" == "3" && "${tuicStatus}" == "true" ]]; then + tuicVersionManageMenu 1 + elif [[ "${installTuicStatus}" == "4" && "${tuicStatus}" == "true" ]]; then + journalctl -fu tuic + fi +} +# hysteria version management +hysteriaVersionManageMenu() { + echoContent skyBlue "\nProgress$1/${totalProgress}: Hysteria version management" + if [[ ! -d "/etc/v2ray-agent/hysteria/" ]]; then + echoContent red " ---> The installation directory is not detected, please execute the script to install the content" + menu + exit 0 + fi + echoContent red "\n================================================ =================" + echoContent yellow "1.Upgrade Hysteria" + echoContent yellow "2.Close Hysteria" + echoContent yellow "3.Open Hysteria" + echoContent yellow "4.Restart Hysteria" + echoContent red "================================================== ===============" + + read -r -p "Please select:" selectHysteriaType + if [[ "${selectHysteriaType}" == "1" ]]; then + installHysteria 1 + handleHysteria start + elif [[ "${selectHysteriaType}" == "2" ]]; then + handleHysteria stop + elif [[ "${selectHysteriaType}" == "3" ]]; then + handleHysteria start + elif [[ "${selectHysteriaType}" == "4" ]]; then + handleHysteria stop + handleHysteria start + fi +} + +# Tuic version management +tuicVersionManageMenu() { + echoContent skyBlue "\nProgress$1/${totalProgress}: Tuic version management" + if [[ ! -d "/etc/v2ray-agent/tuic/" ]]; then + echoContent red " ---> The installation directory is not detected, please execute the script to install the content" + menu + exit 0 + fi + echoContent red "\n================================================ =================" + echoContent yellow "1.Upgrade Tuic" + echoContent yellow "2.Close Tuic" + echoContent yellow "3.Open Tuic" + echoContent yellow "4.Restart Tuic" + echoContent red "================================================== ===============" + + read -r -p "Please select:" selectTuicType + if [[ "${selectTuicType}" == "1" ]]; then + installTuic 1 + handleTuic start + elif [[ "${selectTuicType}" == "2" ]]; then + handleTuic stop + elif [[ "${selectTuicType}" == "3" ]]; then + handleTuic start + elif [[ "${selectTuicType}" == "4" ]]; then + handleTuic stop + handleTuic start + fi } # main menu menu() { - cd "$HOME" || exit - echoContent red "\n==============================================================" - 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.Reinstall" - else - echoContent yellow "1.Install" - fi + cd "$HOME" || exit + echoContent red "\n================================================ =================" + echoContent green "Author: mack-a" + echoContent green "Current version: v2.10.20" + echoContent green "Github: https://github.com/mack-a/v2ray-agent" + echoContent green "Description: 8-in-1 coexistence script\c" + showInstallStatus + checkWgetShowProgress + echoContent red "\n============================ Promotion area================ ============" + echoContent red " " + echoContent green "For promotion, please contact TG: @mackaff\n" + echoContent green "VPS purchasing guide: https://www.v2ray-agent.com/archives/1679975663984" + echoContent green "Low-price VPS AS4837 with an annual payment of 10 US dollars: https://www.v2ray-agent.com/archives/racknerdtao-can-zheng-li-nian-fu-10mei-yuan" + echoContent red "================================================== ===============" + if [[ -n "${coreInstallType}" ]]; then + echoContent yellow "1.Reinstall" + else + echoContent yellow "1.Installation" + fi - 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 - echoContent yellow "3.Switch Trojan[XTLS]" - fi + 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 + echoContent yellow "3.Switch Trojan[XTLS]" + fi - 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 select:" selectInstallType - case ${selectInstallType} in - 1) - selectCoreInstall - ;; - 2) - selectCoreInstall - ;; - 3) - initXrayFrontingConfig 1 - ;; - 4) - manageHysteria - ;; - 5) - manageAccount 1 - ;; - 6) - updateNginxBlog 1 - ;; - 7) - renewalTLS 1 - ;; - 8) - updateV2RayCDN 1 - ;; - 9) - ipv6Routing 1 - ;; - 10) - warpRouting 1 - ;; - 11) - streamingToolbox 1 - ;; - 12) - addCorePort 1 - ;; - 13) - btTools 1 - ;; - 14) - switchAlpn 1 - ;; - 15) - blacklist 1 - ;; - 16) - coreVersionManageMenu 1 - ;; - 17) - updateV2RayAgent 1 - ;; - 18) - bbrInstall - ;; - 19) - checkLog 1 - ;; - 20) - unInstall 1 - ;; - esac + echoContent yellow "4.Hysteria Management" + echoContent yellow "5.REALITY Management" + echoContent yellow "6.Tuic Management" + echoContent skyBlue "-------------------------Tool Management-------------------- ---------" + echoContent yellow "7.Account management" + echoContent yellow "8.Change the camouflage station" + echoContent yellow "9.Update certificate" + echoContent yellow "10.Change CDN node" + echoContent yellow "11.Diversion tool" + echoContent yellow "12.Add new port" + echoContent yellow "13.BT download management" + echoContent yellow "14.Switch alpn" + echoContent yellow "15.Domain name 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 select:" selectInstallType + case ${selectInstallType} in + 1) + selectCoreInstall + ;; + 2) + selectCoreInstall + ;; + 3) + initXrayFrontingConfig 1 + ;; + 4) + manageHysteria + ;; + 5) + manageReality 1 + ;; + 6) + manageTuic + ;; + 7) + manageAccount 1 + ;; + 8) + updateNginxBlog 1 + ;; + 9) + renewalTLS 1 + ;; + 10) + updateV2RayCDN 1 + ;; + 11) + routingToolsMenu 1 + ;; + 12) + addCorePort 1 + ;; + 13) + btTools 1 + ;; + 14) + switchAlpn 1 + ;; + 15) + blacklist 1 + ;; + 16) + coreVersionManageMenu 1 + ;; + 17) + updateV2RayAgent 1 + ;; + 18) + bbrInstall + ;; + 19) + checkLog 1 + ;; + 20) + unInstall 1 + ;; + esac } -cronRenewTLS +cronFunction menu